I have two collision demos for you, one using maths and the other using sparky's dll.
Maths demo:
This is a continuation of my previous thread:
http://forum.thegamecreators.com/?m=forum_view&t=167811&b=10
and uses some of the functions.
This demo is in the style of a racing game, where collision with the wall is detected by determining if any vertex is on the other side of the wall compared to the position of the object.
If a collision is detected, as shown in the diagram, the red point is calculated and the object is moved a distance in the x and z direction that is equal to the difference between the vertex and the red point, ie so that the vertex is now placed on the red point.
`Maths collision demo
`By 29 Games
`07 April 2012
`this program is a third person racing style demo
`controls: upkey to accelerate, down key to decelerate, left and right keys to turn
`car will slow down due to friction, which is higher when the car is sliding against
`a wall.
`this uses the vertex data from a model to detect collision with a map
`+++++ GLOBAL ARRAYS
dim wall_pos#(1000,2,3) :`start and end x, y, z of wall
dim wall_col(1000) :`colour of wall, can also be used to hold an image number for texture
`++++++ SET UP
gosub GENERAL_SET_UP
gosub CONSTANTS
gosub STARTING_VARIABLES
gosub CREATE_MAP
gosub CREATE_OBJECTS
`++++++ MAIN LOOP
do
gosub MOVE_PLAYER
gosub COLLISION_DETECTION
gosub PRINT_STUFF
sync
loop
end
`+++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++ SUB ROUTINES +++++++++++++++++++++++++++++++
`+++++++++++++++++++++++++++++++++++++++++++++++++++
GENERAL_SET_UP:
sync on
sync rate 65
hide mouse
set camera range 1, 3000
randomize timer()
cls
return
CONSTANTS:
`unit size of map
usi = 200
`map constants
num_walls_max = 1000 :`maximum number of wall in map
h# = usi*0.1 :`height of walls
wall_fric# = 0.6 :`decceleraton when car slides against a wall
fric# = 0.05 :`general friction
`number of squares in matrix
num_mtrx = 7
`player constants
accl# = 0.5
brak# = 0.5
turn# = 2.0
max_spd# = 10.0
ypos# = 3.0
`range camera is from player
cam_ran# = -75.0
cam_hgt = 30
cam_tip = 15
return
STARTING_VARIABLES:
`player
spd# = 0.0
facing# = 0.0
return
CREATE_OBJECTS:
`make object for car
make object box 1, 15, 5, 25
color object 1, rgb(0,250,0)
position object 1, 0.5*usi, 3, 1.5*usi
return
MOVE_PLAYER:
`apply friction
spd# = spd# - fric#
if spd# <= 0.0 then spd# = 0.0
`accelerate and brake
if upkey() = 1
spd# = spd# + accl#
if spd# > max_spd# then spd# = max_spd#
endif
if downkey() = 1
spd# = spd# - brak#
if spd# < 0.0 then spd# = 0.0
endif
`turn
if leftkey() = 1
facing# = wrapvalue(facing# - turn#)
endif
if rightkey() = 1
facing# = wrapvalue(facing# + turn#)
endif
`move car
move object 1, spd#
yrotate object 1, facing#
`position camera
yrotate camera facing#
position camera object position x(1), ypos#+cam_hgt, object position z(1)
move camera cam_ran#
xrotate camera cam_tip
return
COLLISION_DETECTION:
`get object's position
xpos# = object position x(1)
zpos# = object position z(1)
`make memblock
make mesh from object 1,1
make memblock from mesh 1, 1
`extact header info, only interested in the vertex data
num_verts = memblock dword(1,0)
pos_verts = memblock dword(1,4)
vert = 0
hit_track = 0
repeat
`extract vertex data, only need X and Z coordinates
xv# = memblock float(1, 12*vert + pos_verts)
zv# = memblock float(1, 12*vert + pos_verts + 8)
wall = 1
repeat
if LINES_CROSS(xpos#,zpos#,xv#,zv#, wall_pos#(wall,1,1),wall_pos#(wall,1,3),wall_pos#(wall,2,1),wall_pos#(wall,2,3)) = 1
hit_track = 1
`get sliding collision coordinates
xi# = X_INTERSECT_P_TO_LINE(xv#,zv#, wall_pos#(wall,1,1),wall_pos#(wall,1,3),wall_pos#(wall,2,1),wall_pos#(wall,2,3))
zi# = Z_INTERSECT_P_TO_LINE(xv#,zv#, wall_pos#(wall,1,1),wall_pos#(wall,1,3),wall_pos#(wall,2,1),wall_pos#(wall,2,3))
`calculate difference between vertex and sliding collision coordinates
x_delta# = xi# - xv#
z_delta# = zi# - zv#
xpos# = xpos#+x_delta#
zpos# = zpos#+z_delta#
`reposition object
position object 1, xpos#, ypos#, zpos#
`get memblock data for new position of object
make mesh from object 1,1
make memblock from mesh 1, 1
exit
endif
inc wall
until wall > num_walls
inc vert
until vert = num_verts
delete mesh 1
delete memblock 1
if hit_track = 0
color object 1, rgb(0,250,0)
else
spd# = spd# - wall_fric#
if spd# <= 0.0 then spd# = 0.0
color object 1, rgb(250,0,0)
endif
return
PRINT_STUFF:
set cursor 0,0
print "controls: upkey to accelerate, down key to decelerate, left and right keys to turn"
print "car will slow down due to friction, which is higher when sliding against walls."
print "number of walls in the map = ", num_walls
print "number of vertices in the car = ", num_verts
print "screen fps = ", screen fps()
print
print "speed = ", spd#
return
CREATE_MAP:
restore _wall_data
for i = 1 to num_walls_max
`write wall data to array
read ax#,az#, bx#, bz#, col
if col <> 0
num_walls = i
wall_pos#(i,1,1) = ax# * usi :`start x coordinate
wall_pos#(i,1,3) = az# * usi :`start z coordinate
wall_pos#(i,2,1) = bx# * usi :`end x coordinate
wall_pos#(i,2,3) = bz# * usi :`end z coordinate
wall_col(i) = col :`colour or texture of wall
endif
next i
for i = 1 to num_walls
MAKE_WALL_OBJECT(i+1, wall_pos#(i,1,1), wall_pos#(i,1,3), wall_pos#(i,2,1), wall_pos#(i,2,3), h#, wall_col(i))
`turn culling off so the wall made with the above function can be seen from both sides
set object i+1, 1, 0, 0
next i
return
`+++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++ FUNCTIONS ++++++++++++++++++++++++++++++++++
`+++++++++++++++++++++++++++++++++++++++++++++++++++
`+++++ COLLISION DETECTION +++++++++++++++++++++++++
function LINES_CROSS(ax#,ay#,bx#,by#, cx#,cy#,dx#,dy#):
`this simply makes use of the same side function and determines if two line have crossed
if SAME_SIDE(ax#,ay#, bx#,by#, cx#,cy#,dx#,dy#) = 0
if SAME_SIDE(cx#,cy#, dx#,dy#, ax#,ay#,bx#,by#) = 0
yes = 1
else
yes = 0
endif
else
yes = 0
endif
endfunction yes
function SAME_SIDE(px#,py#, rx#,ry#, sx#,sy#,fx#,fy#)
`this function determines if point p is on same side of line sf as point r
psi# = px# - sx#: psj# = py# - sy# :`vector ps
fsi# = fx# - sx#: fsj# = fy# - sy# :`vector fs
rsi# = rx# - sx#: rsj# = ry# - sy# :`vector rs
fs_cross_ps# = fsi#*psj# - psi#*fsj# :`cross product of vectors fs and rs
fs_cross_rs# = fsi#*rsj# - rsi#*fsj# :`cross product of vectors fs and rs
if fs_cross_ps# > 0 then fs_cross_ps# = 1 else fs_cross_ps# = -1
if fs_cross_rs# > 0 then fs_cross_rs# = 1 else fs_cross_rs# = -1
if fs_cross_ps# = fs_cross_rs# then yes = 1 else yes = 0
endfunction yes
function X_INTERSECT_P_TO_LINE(px#,pz#, ax#,az#,bx#,bz#)
`draw a line through point p that is perpendicular to line ab
`this function calculates the x coordinate of the intersection
`line ab is parallel with x axis
if az# = bz#
pdx# = px#
endif
`line ab is parallel with z axis
if ax# = bx#
pdx# = ax#
endif
`line ab is not parallel to either x or z axis
if az# <> bz# and ax# <> bx#
mab# = (bx# - ax#)/(bz# - az#)
aaa# = (ax#/mab#) + (mab#*px#)
bbb# = pz# - az#
ccc# = mab# + (1/mab#)
pdx# = (aaa# + bbb#) / ccc#
endif
endfunction pdx#
function Z_INTERSECT_P_TO_LINE(px#,pz#, ax#,az#,bx#,bz#)
`draw a line through point p that is perpendicular to line ab
`this function calculates the z coordinate of the intersection
`line ab is parallel with x axis
if az# = bz#
pdz# = az#
endif
`line ab is parallel with z axis
if ax# = bx#
pdz# = pz#
endif
`line ab is not parallel to either x or z axis
if az# <> bz# and ax# <> bx#
mab# = (bx# - ax#)/(bz# - az#)
aaa# = (pz#/mab#) + mab#*az#
bbb# = px# - ax#
ccc# = mab# + (1/mab#)
pdz# = (aaa# + bbb#) / ccc#
endif
endfunction pdz#
`+++++ FUNCTION FOR MAKING THE WALLS +++++++++++++++++++++++++++++++++++++
function MAKE_WALL_OBJECT(ob, x1#,z1#, x2#,z2#, h#, colour)
`when creating a plain in this manner, the plain will only
`be visible from one side
dim c#(4,3)
dim n#(4,3)
`set coordinates of each vertex
c#(1,1) = x1#
c#(1,2) = 0
c#(1,3) = z1#
c#(2,1) = x2#
c#(2,2) = 0
c#(2,3) = z2#
c#(3,1) = x1#
c#(3,2) = h#
c#(3,3) = z1#
c#(4,1) = x2#
c#(4,2) = h#
c#(4,3) = z2#
`calculate normals
for i = 1 to 4
n#(i,1) = -1*h#*(c#(2,3) - c#(1,3))
n#(i,2) = 0
n#(i,3) = h#*(c#(2,1) - c#(1,1))
next i
`there is one side to a plain
num_sides = 1
`memblock number
mem = 1
`header values
num_verts = num_sides * 4
pos_verts = 32
num_norms = num_verts
pos_norms = num_verts*12 + pos_verts
num_faces = num_sides*2
pos_faces = pos_norms + num_norms*12
size_faces = num_faces*7
pos_uv = pos_faces + size_faces*4
`calculate size of memblock
size_mem = 32 + (num_verts + num_norms)*12 + size_faces*4 + num_sides*32
`create the memblock
make memblock mem, size_mem
`write header values to memblock
write memblock dword mem, 0, num_verts
write memblock dword mem, 4, pos_verts
write memblock dword mem, 8, num_norms
write memblock dword mem, 12, pos_norms
write memblock dword mem, 16, num_faces
write memblock dword mem, 20, pos_faces
write memblock dword mem, 24, size_faces
write memblock dword mem, 28, pos_uv
`write vertex data to memblock
pos = 0
for i = 1 to 4
for j = 1 to 3
write memblock float mem, pos + pos_verts, c#(i,j)
pos = pos + 4
next j
next i
`write normal data to memblock
pos = 0
for i = 1 to 4
for j = 1 to 3
write memblock float mem, pos + pos_norms, n#(i,j)
pos = pos + 4
next j
next i
`write face data to memblock
restore _facedata
for pos = pos_faces to pos_faces+(num_faces*28)-28 step 28
read nvf, va,na, vb, nb, vc,nc
write memblock dword mem, pos, nvf
write memblock dword mem, pos+4, va
write memblock dword mem, pos+8, na
write memblock dword mem, pos+12, vb
write memblock dword mem, pos+16, nb
write memblock dword mem, pos+20, vc
write memblock dword mem, pos+24, nc
next pos
`write UV data to memblock
restore _uvdata
for pos = pos_uv to pos_uv+(num_sides*32)-32 step 32
read ua#,va#, ub#,vb#, uc#,vc#, ud#,vd#
write memblock float mem, pos, ua#
write memblock float mem, pos+4, va#
write memblock float mem, pos+8, ub#
write memblock float mem, pos+12, vb#
write memblock float mem, pos+16, uc#
write memblock float mem, pos+20, vc#
write memblock float mem, pos+24, ud#
write memblock float mem, pos+28, vd#
next pos
`create the object from the memblock
make mesh from memblock ob, mem
make object ob, ob, 0
color object ob, colour
delete mesh ob
delete memblock mem
`data used in the function
_facedata:
data 3, 0,0, 3,3, 1,1 :`face 0
data 3, 3,3, 0,0, 2,2 :`face 1
_uvdata:
data 0.0,1.0, 1.0,1.0, 0.0,0.0, 1.0,0.0
endfunction
`+++++++++++++++++++++++++++++++++++++++++++++++++++
`++++++ DATA +++++++++++++++++++++++++++++++++++++++
`+++++++++++++++++++++++++++++++++++++++++++++++++++
_wall_data:
`walls must form an enclosed area
`outer wall
data 1.0,0.0, 0.0,1.0, 121000
data 0.0,1.0, 0.0,4.5, 121000
data 0.0,4.5, 2.5,7.0, 121000
data 2.5,7.0, 5.5,7.0, 121000
data 5.5,7.0, 7.0,5.5, 121000
data 7.0,5.5, 7.0,4.0, 121000
data 7.0,4.0, 6.0,3.0, 121000
data 6.0,3.0, 5.0,3.0, 121000
data 5.0,3.0, 3.5,2.5, 121000
data 3.5,2.5, 3.5,1.0, 121000
data 3.5,1.0, 2.5,0.0, 121000
data 2.5,0.0, 1.0,0.0, 121000
`inner wall
data 1.5,1.0, 1.0,1.5, 121000
data 1.0,1.5, 1.0,4.0, 121000
data 1.0,4.0, 3.0,6.0, 121000
data 3.0,6.0, 5.0,6.0, 121000
data 5.0,6.0, 6.0,5.0, 121000
data 6.0,5.0, 6.0,4.5, 121000
data 6.0,4.5, 5.5,4.0, 121000
data 5.5,4.0, 3.5,4.0, 121000
data 3.5,4.0, 2.5,3.0, 121000
data 2.5,3.0, 2.5,1.5, 121000
data 2.5,1.5, 2.0,1.0, 121000
data 2.0,1.0, 1.5,1.0, 121000
`marks the end of the track wall data
data 0.0,0.0, 0.0,0.0, 0
I've used a simple box for a car but you can use any object you wish. However, I've seen major slow down if there are too many vertices.
Sparky's collision demo:
Now, not having used DBC in a while, I'd forgotten that there aren't any sliding collision commands and then I remembered that the idea came to me because of the above demo.
If you look at the diagram, the dotted line is just a ray cast from the centre of the object to a vertex. Where the ray cast intersects the wall (in the case of sparky's this will be a ploygon), the intersect point can be used in the same way the red point is used in the first demo. I.e. the difference between the point P and the intersecting can be used to simulate sliding. In Sparky's the interest point is the static collision coordinates so is easy to calculate.
So you could do the above demo using Sparky's or for an FPS style game you could place an invisible box around the player. However, the box is only be being used to determine the end point of the ray cast so for FPS collision you can get rid of the box and simply use some maths to calculate the end point of the ray cast.
`Sparky's collision demo
`By 29 Games
`07 April 2012
`this is a first person camera demo using Sparky's collision dll
`controls : wasd to move, mouse look, r to toglle run/walk, c to toggle stand/crouch, space to jump
dim ply_pos#(2,3) :`old and new x, y, z positions of camera
dim ply_fac#(2) :`direction camera is facing left and right and up and down
`++++++ SET UP
gosub GENERAL_SET_UP
gosub CONSTANTS
gosub LOAD_OBJECTS
gosub STARTING_VARIABLES
`+++++ MAIN LOOP
_main_loop:
do
gosub OTHER_CONTROLS
gosub MOVE_PLAYER
gosub COLLIDE_WITH_MAP
gosub PLACE_CAMERA
gosub PRINT_STUFF
sync
loop
GENERAL_SET_UP:
sync on
sync rate 60
hide mouse
set camera range 1, 3000
fog on
fog distance 600
fog color rgb(20, 0, 20)
randomize timer()
cls
return
CONSTANTS:
`player
wspd# = 0.16 :`walk speed
rspd# = 0.48 :`run speed
mspd# = wspd# :`current forward movement speed
sspd# = wspd# :`strafe speed and backward movement speed
tspd# = 0.2 :`turn speed (looking left to right
pspd# = 0.2 :`pitch speed (looking up and down)
jspd# = 1.0 :`the initial speed with which the player jumps up
psiz# = 3.0 :`player size as represented by a radius
psht# = 5.0 :`standing height of the player
pcht# = psht#*0.5 :`crouching height of the player
min_y# = 0.1 :`this is the minimum value the y position of the player can be
max_fspd# = -1.0 :`maximum falling speed of player
`note that psiz# and psht# (or pcht#) mean that the player is essentially represented by a cylinder
`gravity
grav# = 0.05
return
LOAD_OBJECTS:
`object management
num_objects = 0 :`this is the number of objects in the game
ob_num = 0
do
read w,l,h, x,y,z, a
if w = 0 then exit
inc ob_num
make object box ob_num, w,l,h
position object ob_num, x,y,z
yrotate object ob_num, a
setupObjectDBC(ob_num,1,0)
loop
return
STARTING_VARIABLES:
ply_pos#(2,1) = 0 :`initial x position
ply_pos#(2,2) = min_y# :`initial y position
ply_pos#(2,3) = -100 :`initial z position
ply_fac#(1) = 0.0 :`initial facing
ply_fac#(2) = 0.0 :`initial pitch
cur_jspd# = 0 :`initial jump speed (current jump speed)
cur_pht# = psht# :`initial player height (current player height)
`flags
jump = 0 :`whether or not the player is jumping / falling
hit_surface = 0 :`whether or not the player has hit a top or bottom surface
return
OTHER_CONTROLS:
`press r to toggle walk or run
if run = 0
if keystate(19)=1
run = 1
if mspd# = rspd# then mspd# = wspd# else mspd# = rspd#
endif
endif
if keystate(19)=0 then run = 0
`press c to toggle standing and crouching
if crouch = 0
if keystate(46)=1
crouch = 1
if cur_pht# = pcht#
`standing up
`ray cast up to see if there is enough head room to stand up
xa# = ply_pos#(2,1)
ya# = ply_pos#(2,2) + cur_pht#
za# = ply_pos#(2,3)
xb# = xa#
yb# = ply_pos#(2,2) + psht#
zb# = za#
`determine if there is a collision with the ceiling if not allow the player to stand up
if intersectObjectDBC(1,1,xa#,ya#,za#,xb#,yb#,zb#,0) = 0
cur_pht# = psht#
endif
else
`crouching
cur_pht# = pcht#
endif
endif
endif
if keystate(46)=0 then crouch = 0
return
MOVE_PLAYER:
`save old position
ply_pos#(1,1) = ply_pos#(2,1)
ply_pos#(1,2) = ply_pos#(2,2)
ply_pos#(1,3) = ply_pos#(2,3)
`use mouse to look left, right, up and down
`rotate left and right
ply_fac#(1) = wrapvalue(ply_fac#(1) + mousemovex()*tspd#)
`pitch camera up and down
ply_fac#(2) = wrapvalue(ply_fac#(2) + mousemovey()*pspd#)
`this restricts the look up and down angle
campitchtest# = wrapvalue(ply_fac#(2)+180)
if campitchtest# < 90 then ply_fac#(2) = 270
if campitchtest# > 270 then ply_fac#(2) = 90
`w = forward, s = backward, a = strafe left, d = strafe right
`move forward
if keystate(17) = 1
ply_pos#(2,1) = newxvalue(ply_pos#(2,1), ply_fac#(1), mspd#)
ply_pos#(2,3) = newzvalue(ply_pos#(2,3), ply_fac#(1), mspd#)
endif
`move back
if keystate(31) = 1
ply_pos#(2,1) = newxvalue(ply_pos#(2,1), wrapvalue(ply_fac#(1)+180), sspd#)
ply_pos#(2,3) = newzvalue(ply_pos#(2,3), wrapvalue(ply_fac#(1)+180), sspd#)
endif
`strafe left
if keystate(30) = 1
ply_pos#(2,1) = newxvalue(ply_pos#(2,1), wrapvalue(ply_fac#(1)-90), sspd#)
ply_pos#(2,3) = newzvalue(ply_pos#(2,3), wrapvalue(ply_fac#(1)-90), sspd#)
endif
`strafe right
if keystate(32) = 1
ply_pos#(2,1) = newxvalue(ply_pos#(2,1), wrapvalue(ply_fac#(1)+90), sspd#)
ply_pos#(2,3) = newzvalue(ply_pos#(2,3), wrapvalue(ply_fac#(1)+90), sspd#)
endif
`jumping = space to jump
`jump
if jump = 0 and cur_jspd# = 0
if spacekey()=1
jump = 1
cur_jspd# = jspd#
endif
endif
`moving in the y direction (jumping and falling)
ply_pos#(2,2) = ply_pos#(2,2) + cur_jspd#
cur_jspd# = cur_jspd# - grav#
if cur_jspd# < max_fspd# then cur_jspd# = max_fspd#
return
COLLIDE_WITH_MAP:
`ray cast down to detect where the ground is on the main map directly below the player
xa# = ply_pos#(2,1)
ya# = ply_pos#(2,2) + cur_pht#
za# = ply_pos#(2,3)
xb# = xa#
yb# = -1000
zb# = za#
`calculate where the ground is
if intersectObjectDBC(1,1,xa#,ya#,za#,xb#,yb#,zb#,0) > 0
ground# = getStaticCollisionY() + min_y#
endif
`if the player's current y position is below the ground then position the player on the ground
if ply_pos#(2,2) <= ground#
jump = 0
ply_pos#(2,2) = ground#
cur_jspd# = 0
endif
`if the player is jumping up, ray cast up to determine if player has jumped up into something
if cur_jspd# > 0
xa# = ply_pos#(2,1)
ya# = ply_pos#(2,2)
za# = ply_pos#(2,3)
xb# = xa#
yb# = ply_pos#(2,2) + cur_pht#
zb# = za#
if intersectObjectDBC(1,1,xa#,ya#,za#,xb#,yb#,zb#,0) > 0
ply_pos#(2,2) = getStaticCollisionY() - min_y# - cur_pht#
cur_jspd# = 0
endif
endif
`this determines if the player has collided with the walls and then
if ply_pos#(1,1) <> ply_pos#(1,2)
if ply_pos#(1,3) <> ply_pos#(2,3)
`determine if the walls of map have been hit
`ray cast parallel to XZ plane at two heights (mid way up from the ground and at camera height) to see if the side of an object has been hit
for j = 1 to 2
`ray cast out in six directions
for i = 0 to 5
xa# = ply_pos#(2,1)
ya# = ply_pos#(2,2) + cur_pht#*j*0.45
za# = ply_pos#(2,3)
xb# = psiz#*sin(ply_fac#(2,1) + i*60) + xa# :`note that the i*60 is because we are ray casting in six directions
yb# = ya#
zb# = psiz#*cos(ply_fac#(2,1) + i*60) + za# :`note that the i*60 is because we are ray casting in six directions
`determine collision with map
if intersectObjectDBC(1,1,xa#,ya#,za#, xb#,yb#,zb#,0) > 0
`get static collision cooridinates but only need x and z
ix# = getStaticCollisionX()
iz# = getStaticCollisionZ()
`determine the different between the end point of the ray cast and the static collision point
difx# = xb# - ix#
difz# = zb# - iz#
`move the player by the difference to simulate sliding
ply_pos#(2,1) = ply_pos#(2,1) - difx#
ply_pos#(2,3) = ply_pos#(2,3) - difz#
endif
next i
next j
endif
endif
return
PLACE_CAMERA:
yrotate camera ply_fac#(1)
xrotate camera ply_fac#(2)
position camera ply_pos#(2,1), ply_pos#(2,2)+cur_pht#*0.8, ply_pos#(2,3)
return
PRINT_STUFF:
set cursor 0,0
print "1st person collision demo using sparky's collision dll"
print "wasd to move, mouse look"
print "r to toggle run/walk, c to toggle crouch/stand, space to jump"
print "screen fps : ", screen fps()
return
`++++++ functions
function setupObjectDBC(objNum,groupNum,objectType)
commonSetup(objNum)
vertData = get memblock ptr(254)
objectData = get memblock ptr(255)
call dll 1,"setupObject",objNum,groupNum,objectType,vertData,objectData
delete memblock 254
endfunction
function setupComplexObjectDBC(objNum,groupNum,facesPerNode)
commonSetup(objNum)
vertData = get memblock ptr(254)
objectData = get memblock ptr(255)
call dll 1,"setupComplexObject",objNum,groupNum,facesPerNode,vertData,objectData
delete memblock 254
endfunction
function commonSetup(objNum)
if dll exist(1)=0 then load dll "DBCcollision.dll",1
if memblock exist(255)=0 then make memblock 255,24
x#=object position x(objNum)
y#=object position y(objNum)
z#=object position z(objNum)
angx#=object angle x(objNum)
angy#=object angle y(objNum)
angz#=object angle z(objNum)
write memblock float 255,0,x#
write memblock float 255,4,y#
write memblock float 255,8,z#
write memblock float 255,12,angx#
write memblock float 255,16,angy#
write memblock float 255,20,angz#
position object objNum,0,0,0
rotate object objNum,0,0,0
make mesh from object 255,objNum
make memblock from mesh 254,255
delete mesh 255
position object objNum,x#,y#,z#
rotate object objNum,angx#,angy#,angz#
endfunction
function updateObjectDBC(objNum)
if memblock exist(255)=0 then make memblock 255,24
write memblock float 255,0,object position x(objNum)
write memblock float 255,4,object position y(objNum)
write memblock float 255,8,object position z(objNum)
write memblock float 255,12,object angle x(objNum)
write memblock float 255,16,object angle y(objNum)
write memblock float 255,20,object angle z(objNum)
objectData = get memblock ptr(255)
call dll 1,"updateObject",objNum,objectData
endfunction
function intersectObjectDBC(objNum,groupFlag,oldx#,oldy#,oldz#,x#,y#,z#,excludeObj)
collide=call dll(1,"intersectObject",objNum,groupFlag,oldx#,oldy#,oldz#,x#,y#,z#,excludeObj)
endfunction collide
function setObjectCollisionOnDBC(objNum)
call dll 1,"set_object_collision_on",objNum
endfunction
function setObjectCollisionOffDBC(objNum)
call dll 1,"set_object_collision_off",objNum
endfunction
function collisionStatusDBC(objNum)
result=call dll(1,"collisionstatus",objNum)
endfunction result
function getStaticCollisionX()
result#=call dll(1,"getStaticCollisionX")
endfunction result#
function getStaticCollisionY()
result#=call dll(1,"getStaticCollisionY")
endfunction result#
function getStaticCollisionZ()
result#=call dll(1,"getStaticCollisionZ")
endfunction result#
function getCollisionNormalX()
result#=call dll(1,"getCollisionNormalX")
endfunction result#
function getCollisionNormalY()
result#=call dll(1,"getCollisionNormalY")
endfunction result#
function getCollisionNormalZ()
result#=call dll(1,"getCollisionNormalZ")
endfunction result#
`++++++++++++++++++++++++
`++++++ GAME DATA +++++++
`++++++++++++++++++++++++
level_data:
data 500,2,500, 0,-1,0,0
data 20,2,20, 0,1,20,0
data 20,4,20, 20,2,20,0
data 20,6,20, 40,3,20,0
data 20,8,40, 60,4,30,0
data 20,10,20, 80,5,40,0
data 30,12,30, 95,6,40,45
data 10,2,50, 120,11,65,45
data 30,12,30, 145,6,90,45
data 10,2,100, 145,11,155,0
data 30,12,30, 145,6,205,45
data 50,10,20, 110,5,205,0
data 10,6,20, 80,7,205,0
data 50,10,20, 50,5,205,0
data 10,12,20, 20,6,205,0
data 40,14,40, 0,7,205,0
data 10,8,10, 0,4,230,0
I've used primative but it will also work for models that are loaded in. There are no ramps in the demo but this will work with ramps. The only problem with ramps is that you get a sort of hopping motion when going down ramps. I also struggled to get this to work with lifts, going up was fine but not coming down. The lift would go down faster than gravity could accelerate the player downward, which it does in the real world but real world gravity in games always seems to fast in games. I suspect that there's an easy way to sort this out.
Anyway, enjoy.