Thanks for the help guys, but I still don't seem to be able to get it to work...
@BMacZero
Yeah, I originally intended to use this, but as I said above the movement is very jumpy, even using the code you posted, and the formula on the Wikipedia page...
Here's a quick demo showing what I mean, I'm using object based terrain in my game, but this just uses matrices to make it simpler.
sync on : sync rate 60
set display mode desktop width(),desktop height(),32 : maximize window : color backdrop rgb(150,150,230)
position camera 100,50,100 : make object cube 1,1 : position object 1,100,0,100
global m_speed# = 0.25 : global t_speed# = 4.0 : global jump : global jump_timer# : global base_height#
generate_world(8,512)
set matrix wireframe off 1
ghost matrix on 1
matrix_normals(1)
make_wire()
////////////////////////////////////vvvvvvvvvvvv
//terrain height method:
global thm = 1
///////////////////////////////////^^^^^^^^^^^^^
do
move_char()
if jump = 1 then update_jump()
sync
LOOP
////////////////////////////////////////////////////////////////////////////////////////////////////vvvvvvvv
function terrain_height(x#,y#)
fx = floor(x#) : cx = ceil(x#)
fy = floor(y#) : cy = ceil(y#)
a# = get matrix height(1,fx,fy) :text 0,10,"a: "+str$(a)
c# = get matrix height(1,cx,fy) :text 0,20,"b: "+str$(b)
b# = get matrix height(1,fx,cy) :text 0,30,"c: "+str$(c)
d# = get matrix height(1,cx,cy) :text 0,40,"d: "+str$(d)
px# = x# - fx : py# = y# - fy
if thm = 1 then height# = (1-px#) * (py#*c# + (1-py#)*d#) + (px#) * (py#*b# + (1-py#)*a#) //method you posted(not sure if I'm using it properly)
if thm = 2 then height# = (a*(1-px#)*(1-py#)) + (b*px*(1-py#)) + (c*(1-px#)*py#) + (a*px#*py#) //formula on wikiepdia
if thm = 3 then height# = get ground height(1,x#,y#) //matrix command
text 0,0,"height: " + str$(height#)
endfunction height#
///////////////////////////////////////////////////////////////////////////////////////////////////////^^^^^^^^^^^^
function move_char()
if keystate(17) = 1 or upkey() = 1 then move object 1,m_speed#
if keystate(31) = 1 or downkey() = 1 then move object 1,-m_speed#/2
if keystate(30) = 1 or leftkey() = 1 then rotate object 1,0,object angle y(1)-t_speed#,0
if keystate(32) = 1 or rightkey() = 1 then rotate object 1,0,object angle y(1)+t_speed#,0
if keystate(2) = 1 then thm = 1
if keystate(3) = 1 then thm = 2
if keystate(4) = 1 then thm = 3
if object position y(1) < terrain_height(object position x(1),object position z(1))
jump = 0
ENDIF
/////////////////////////////////////
position object 1,object position x(1),terrain_height(object position x(1),object position z(1)),object position z(1)
//////////////////////////////////////
if jump = 0
if keystate(57) = 1 then start_jump()
if keystate(29) = 1 then start_jump()
endif
set camera to follow object position x(1),object position y(1),object position z(1),object angle y(1),30,15,10,0
ENDFUNCTION
function start_jump()
jump = 1
jump_timer = timer()
base_height# = terrain_height(object position x(1),object position z(1))
ENDFUNCTION
function update_jump()
a# = (timer() - jump_timer)/10
position object 1,object position x(1),(fn(a#))+base_height#,object position z(1)
ENDFUNCTION
function fn(y#)
x# = -1*(((y#/20)-1.4)^2)+2
ENDFUNCTION x#
function generate_world(scale,chunk_size) : dim matrix_no(2,2)
make matrix matrix_ID + 1,chunk_size,chunk_size,chunk_size,chunk_size : matrix_ID = matrix_ID + 1 : matrix_no(0,0) = matrix_ID : set matrix height matrix_ID,0,0,rnd(10)-5 : s=scale
for x=2^s to chunk_size step 2^s : set matrix height matrix_id,x,0,get matrix height (matrix_id,x-2^s,0) + rnd((2^s))-((2^s))/20 : next x : for y=2^s to chunk_size step 2^s : set matrix height matrix_id,0,y,get matrix height (matrix_id,0,y-2^s) + rnd((2^s))-((2^s))/20 : next y
for y = 2^s to chunk_size step 2^s : for x=2^s to chunk_size step 2^s : set matrix height matrix_id,x,y,(get matrix height (matrix_id,x-2^s,y) + get matrix height (matrix_id,x,y-2^s))/2 + rnd((2^s))-((2^s))/20 : next x : next y
for o = 1 to s : p=s-o+1 : for y = 0 to chunk_size step 2^p : for x=2^p/2 to chunk_size step 2^p : set matrix height matrix_id,x,y,(get matrix height (matrix_id,x-(2^p/2),y) + get matrix height (matrix_id,x+(2^p/2),y))/2 + (rnd(2^p*2)-2^p)/10 : next x : next y
for y = 2^p/2 to chunk_size step 2^p : for x=0 to chunk_size step 2^p : set matrix height matrix_id,x,y,(get matrix height (matrix_id,x,y-(2^p/2)) + get matrix height (matrix_id,x,y+(2^p/2)))/2 + (rnd(2^p*2)-2^p)/4 : next x : next y : for y = 2^p/2 to chunk_size step 2^p : for x = 2^p/2 to chunk_size step 2^p : set matrix height matrix_id,x,y,(get matrix height (matrix_id,x,y-(2^p/2)) + get matrix height (matrix_id,x,y+(2^p/2)) + get matrix height (matrix_id,x-(2^p/2),y) + get matrix height (matrix_id,x+(2^p/2),y))/4 + (rnd(2^p*2)-2^p)/4 : next x : next y
next o : update matrix matrix_id
endfunction
function matrix_normals(m_no)
for x = 1 to 511 : for y = 1 to 511
h8# = get matrix height(m_no,x,y-1)
h4# = get matrix height(m_no,x-1,y)
h# = get matrix height(m_no,x,y)
h2# = get matrix height(m_no,x,y)
rem Calculate projected angle X using heights
x1#=(x-1) : y1#=h#
x2#=(x+0) : y2#=h4#
dx#=x2#-x1#
dy#=y2#-y1#
ax# = AtanFull(dx#,dy#)
ax# = WrapValue(90-ax#)
rem Calculate projected angle Z using heights
z1# = (z-1) : y1#=h2#
z2# = (z+0) : y2#=h8#
dz# = z2#-z1#
dy# = y2#-y1#
az# = AtanFull(dz#,dy#)
az# = WrapValue(90-az#)
rem Make normal from projected angle
nx# = Sin(ax#)
ny# = Cos(ax#)
nz# = Sin(az#)
set matrix normal m_no,x,y,nx#/2,ny#/2,nz#/2
next y : next x
update matrix m_no
ENDFUNCTION
function make_wire()
make matrix 2,512,512,512,512
for x = 0 to 512 : for y = 0 to 512
set matrix height 2,x,y, get matrix height(1,x,y)
next y : next x
matrix_normals(2)
endfunction
press 1,2 and 3 to switch between functions
1 = the one you posted
2 = one on wikipedia
3 = get ground height
any help?
@latch
I understood everything up to the "using the normals to calculate height" part.
I can't figure out how normals give you the answer, I've heard many people talking about it before, but I don't know how.
>.<
can you explain it please?
Thanks , Lewis