Hiys guys, sorry I missed these posts. My code is a mess at the best of times, it is a bit more straightforward though once you know what it's trying to do
.
The heightmap is stored in an array called ter(), and the getheight#(x,y) function will return the height at a given 2D location. The terrain is vertex adjusted depending on the heights returned from their X and Z location, so it can use any mesh as a terrain, designed for using LOD meshes, although I find just having lots of patches as limbs on a main terrain object works best.
The cursor is really just a terrain object, it gets textured with a grid and circle, and it's vertex's get molded onto the terrain. Using pick object on the terrain object allows you to work out the 3D location that the mouse pointer is on, like...
pick=PICK OBJECT(mx,my,100,100)
if pick>0
curx#=camera position x()+get pick vector x()
curz#=camera position z()+get pick vector z()
update_cursor(curx#,curz#)
if cammode=0 then gosub RTS_cam
endif
if mb=1 then gosub tool
This would check MX and MY (the mouse pointer position) against object 100 (the terrain object), and then store the 2D location in curx# and cury# (the cursor). The update_cursor() function will mold the cursor mesh to the terrain.
If you click the mouse, then the tool subroutine is called, which does all the height adjusting and painting.
Each brush mode is handled in the tool subroutine, and each indice in the ter array is affected depending on the distance to the cursor center point. So...
` Work out the array location of the cursor
cx=int(curx#/100)
cz=int(curz#/100)
` And the real snapped location
curx=cx*100
curz=cz*100
` Now the area the cursor covers in the ter() array
st_x=cx-1-cursize
st_z=cz-1-cursize
en_x=cx+1+cursize
en_z=cz+1+cursize
` Work out the real size of the cursor
brush_range#=(cursize*100.0)+100.0
` Step through the area the cursor covers
for xx=st_x to en_x
for zz=st_z to en_z
` Work out the distance between the current XX,ZZ location and the center of cursor
vr#=dist#(xx*100.0,zz*100.0,curx#,curz#)
` Now make it a 0.0-1.0 multiplier
brush_v#=vr#/brush_range#
if brush_v#<1.0
if brushmode=1 or brushmode=7 `Raise
ter(xx,zz)=ter(xx,zz)+((1.0-brush_v#)*15.0*elapsed#)
stamp_ter_update(xx,zz,1)
endif
endif
next zz
next xx
So raising the terrain is done directly in the tool sub, by adding to the ter() array depending on the brush size.
Smoothing the terrain is a bit more involved...
if brushmode=4 `Smooth
hh#=0
for ang=0 to 360 step 90 hh#=hh#+(getheight#(curx+(sin(ang)*200.0),curz+(cos(ang)*200.0))-ter(xx,zz))
next ang ter(xx,zz)=ter(xx,zz)+((hh#/100.0)*(1.0-brush_v#)*elapsed#)
stamp_ter_update(xx,zz,1)
endif
That is similar to raising terrain, except it checks the surrounding heights and uses that to determine how much to modify the height by. This is also depending on cursor size of course, usually it's just a case of multiplying by (1.0-brush_v#).
When painting the textures on, the same principle is used except instead of modifying the ter() array, it's modifying the map() array, which is like a bitmap but with an element for each texture layer. The map() array is updated then periodically it will update the textures through memblocks.
I will try and watch this thread from now on, so any more queries just post them here and I'll explain as best I can.
Tersculpt2 is shaping up, one major change to the way it works is that now it uses a texture as a colour base, so there's only 5 textures to play with - but, you can paste sprites and paint directly onto the terrain now. Attached a screenie to proove that it is being worked on. The object placement isn't properly in yet, but the terrain painting works a treat.