try this for the tilting (forget about some unused subroutines)
it's a bit comlicated subroutine (groundalign) but you may notice I'm using limb rotation (limb 0) for object z angle tilting. cause "zrotate object objnum,angle" won't work (It tilts the object around world z axis instead of object z axis).
Rem Project: Matrix_Align
rem by Scorpyo
Rem Created: 06/01/04 14.14.03
Rem ***** Main Source File *****
top:
rem ********** INITIALIZATION ****************
set display mode 800,600,16
hide mouse
set global collision off
autocam off
backdrop on
sync on
cls
landsize=20000
grid=40
mtxrandomize=160
x#=10000.0
z#=10250.0
cubesize#=100.0
gosub maketextures
gosub Setupland1
gosub makewheels
gosub makecar
gosub Resetcam
do_loop:
do
if inkey$()="r" then a#=0.0
gosub Carcontrol
gosub groundalign
gosub camera_controls
gosub update_camera
gosub printdata
sync
loop
rem ***********************
groundalign:
rem Calculate wheel X+Z coordinates (4 wheels at 45° from center)
rem displacement=70 units=cube corners (must correspond to real wheel displacement)
foot#=70
frontra#=wrapvalue(a#+45)
frontrx#=newxvalue(x#,frontra#,foot#) : frontrz#=newzvalue(z#,frontra#,foot#)
frontla#=wrapvalue(a#-45)
frontlx#=newxvalue(x#,frontla#,foot#) : frontlz#=newzvalue(z#,frontla#,foot#)
backra#=wrapvalue(a#+135)
backrx#=newxvalue(x#,backra#,foot#) : backrz#=newzvalue(z#,backra#,foot#)
backla#=wrapvalue(a#+225)
backlx#=newxvalue(x#,backla#,foot#) : backlz#=newzvalue(z#,backla#,foot#)
rem calculate ground height at wheel points
frontrh#=get ground height(1,frontrx#,frontrz#)
frontlh#=get ground height(1,frontlx#,frontlz#)
backrh#=get ground height(1,backrx#,backrz#)
backlh#=get ground height(1,backlx#,backlz#)
rem calculate wheel ground height differences
rem front/back right wheel and front/back left wheel
rem divide by 2 to get mid point on diagonal for exact tilt angle calculation
rotrx#=(backrh#-frontrh#)/2
rotlx#=(backlh#-frontlh#)/2
rem calculate car right/left side tilt X angles
rem based on car height from ground in units (50=half cube size)
oarx#=atan (rotrx#/50)
oalx#=atan (rotlx#/50)
rem calculate difference between right side and left side X tilt angles
diffx#=abs(oarx#-oalx#)
rem height adjustment for vehicle + half cube size + 2
h#=frontrh#+rotrx#+52
rem if abs difference between the 2 X angles is above 1
rem choose right side X angle for X rotation
if diffx#>1
oax#=oarx#
position object 2,x#,h#,z#
endif
rem else choose left X angle
if diffx#<=1
oax#=oalx#
position object 2,x#,h#,z#
endif
rem Z angles management
rem get car front and car back Z tilt angles
rotfz#=(frontrh#-frontlh#)/2
rotbz#=(backrh#-backlh#)/2
oafz#=atan (rotfz#/50)
oabz#=atan (rotbz#/50)
rem check abs difference
diffz#=abs(oafz#-oabz#)
if diffz#<=1
rem routine tracing
trace$="front_Z_angle_active"
rem
oaz#=oafz#
position object 2,x#,h#-rotfz#,z#
endif
rem check real height of front left wheel
lfwheelh#=backlh#-rotrx#*2
if diffz#>1
trace$="back_Z_angle_active"
rem if front left wheel higher than ground height at wheel point
rem choose back z angle rotation
if lfwheelh#>frontlh# then oaz#=oabz#:position object 2,x#,h#-rotbz#-1,z#
rem if front left wheel lower than ground height
rem choose front z angle rotation
if lfwheelh#<frontlh# then oaz#=oafz#:position object 2,x#,h#-rotfz#-1,z#
endif
rotate limb 2,0,oax#,0,oaz#
return
Carcontrol:
rem ---- Control Vehicle ----
x#=newxvalue(x#,a#,s#)
z#=newzvalue(z#,a#,s#)
yrotate object 2,a#
if upkey()=1 and s#<8 then s#=s#+3
if downkey()=1 and s#>-8 then s#=s#-3
if leftkey()=1 then a#=wrapvalue(a#-6)
if rightkey()=1 then a#=wrapvalue(a#+6)
if inkey$()="ù" then s#=40
if inkey$()="à" then s#=0
return
rem ****** CREATE LEVEL ******
maketextures:
rem ground textures
rem create texture
cls rgb(0,100,20)
inkcolor#=rgb(255,255,255)
line 0,0,0,250
line 1,1,1,250
line 2,2,2,250
line 0,0,250,0
line 1,1,250,1
line 2,2,250,2
line 0,0,250,250
line 0,250,250,0
rem next n
get image 2,0,0,256,256
cls rgb(0,10,200)
line 0,108,128,108
line 0,109,128,109
line 0,110,128,110
for n= 112 to 128
line 0,n,20,n
line 108,n,128,n
next n
get image 3,0,0,128,128
cls rgb(200,10,20)
get image 4,0,0,128,128
return
Setupland1:
rem Make landscape
make matrix 1,landsize,landsize,grid,grid
set matrix 1,1,0,0,1,1,1,1
prepare matrix texture 1,2,1,1
randomize matrix 1,mtxrandomize
for n=18 to 22
set matrix height 1,n,15,0
set matrix height 1,n,17,0
set matrix height 1,n,18,200
set matrix height 1,n,19,200
set matrix height 1,n,20,0
set matrix height 1,n,21,0
set matrix height 1,n,22,200
set matrix height 1,n,23,200
set matrix height 1,n,24,0
set matrix height 1,n,25,0
set matrix height 1,n,26,200
set matrix height 1,n,27,200
set matrix height 1,n,28,0
set matrix height 1,n,29,0
next n
rem ***********
rem get ground done
update matrix 1
return
makewheels:
make object cylinder 4,20
texture object 4,4
make object cylinder 5,20
texture object 5,4
make object cylinder 6,20
texture object 6,4
make object cylinder 7,20
texture object 7,4
return
makecar:
cubesize#=100.0
make object cube 2,cubesize#
position object 2,x#,cubesize#,z#
texture object 2,3
return
rem CAMERA
camera_controls:
if inkey$()="z" then camdist=camdist+6
if inkey$()="Z" then camdist=camdist-6
if inkey$()="x" then camhgt=camhgt+6
if inkey$()="X" then camhgt=camhgt-6
if inkey$()="c" then camrot=wrapvalue(camrot+6)
if inkey$()="C" then camrot=wrapvalue(camrot-6)
if inkey$()="v" then camlen=camlen+6
if inkey$()="V" then camlen=camlen-6
if inkey$()="b" then camrot = 180
if inkey$()="B" then camrot = 0
if inkey$()="n" then camdist=80:camlen=0:camrot=180:camhgt=100:camflag=0:wait 1
if inkey$()="N" then camdist=80:camlen=0:camrot=0:camhgt=100:camflag=1:wait 1
if inkey$()=">" then gosub Resetcam
if inkey$()="m" then camdist=-1000:camhgt=500:set camera range 100,20000
if inkey$()="M" then camdist=-3000:camhgt=1000:set camera range 100,20000
return
rem camera update
update_camera:
rem Position camera to the back of the character
ca#=wrapvalue(a#+camrot)
cx#=newxvalue(x#,ca#,camdist)
cz#=newzvalue(z#,ca#,camdist)
cy#=get ground height(1,x#,z#)
position camera cx#,cy#+camhgt,cz#
rem Point camera at object
point camera x#,cy#+camhgt+camlen,z#
return
Resetcam:
set camera range 20,20000
camdist=-500
camhgt=200
camrot=0
camlen=0
return
rem PRINT
printdata:
set cursor 0,0
set text opaque
rem debug check
print "polygons=",statistic(1)
print "Fps=",screen fps()
print "landsize=",landsize
print "grid=",grid
print "x#=",x#
print "z#=",z#
print "a#=",a#
print
print "h#=",h#-52
print
print "frontrh#=",frontrh#
print "frontlh#=",frontlh#
print "backrh#=",backrh#
print "backlh#=",backlh#
print
print "rotrx#=",rotrx#
print "rotlx#=",rotlx#
print "rotfz#=",rotfz#
print "rotbz#=",rotbz#
print
print "oarx#=",oarx#
print "oalx#=",oalx#
print "oafz#=",oafz#
print "oabz#=",oabz#
print
print "diffx#=",diffx#
print "diffz#=",diffz#
print
print "trace=",trace$
print "real_left_front_wheel_height=",lfwheelh#
return
end