@Latch-
Just do it? OK. Here is a fixed version of the above:
remstart
==============================================================
= Title : Sliding Collision using helper DLL sliding Collision Function
= and coldets Ray and Sphere collision detection
= Author : Latch Grapple (c) 2012
= Date : 04/12/2012
= Update : 05/06/2012
= Version: .40
==============================================================
Comments
05/06/2012
Bug fixes in sliding collision function
Added:
Y height to built in collision function
04/12/2012
The coldet library provides sphere/mesh collision detection.
This can be adapted for use in First Person Shooters
to test the camera against the enivornment for collision.
==============================================================
remend
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
autocam off
set display mode 800,600,32
set camera aspect .625
sync on
sync rate 40
hide mouse
rem =============================================================
rem = MAIN
rem =============================================================
_main:
rem some credits
credits(26,0)
for n=256 to 0 step -4
set gamma n,n,n
next n
cls 0
wait 100
set gamma 255,255,255
rem intialize demo
gosub _init
ink rgb(255,255,255),0
toggle=0
do
center text screen width()/2,screen height()-40,"BUILT IN SLIDING COLLISION FUNCTION EXAMPLE"
center text screen width()/2,screen height()-20,"Press [ENTER] to toggle INFO"
oe=ne
ne=returnkey()
if ne > oe
toggle=1-toggle
endif
if toggle
gosub _debug
endif
gosub _move_camera
sync
loop
end
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
_initialize_coldet:
rem load in the DBC library files
#INCLUDE "include_files\inc_dbccoldet.dba"
rem set up the arrays needed by the library to store memblock info
rem reserve memblocks to return most values
dim colmem(3,2)
colmem(1,1) = 247
make memblock colmem(1,1),12 : rem store 3 floats if necessary
colmem(1,2) = get memblock ptr(colmem(1,1))
colmem(2,1) = 248
make memblock colmem(2,1),18*4 : rem store 18 floats
colmem(2,2) = get memblock ptr(colmem(2,1))
colmem(3,1) = 249
make memblock colmem(3,1),10*4 : rem store 40 floats
colmem(3,2) = get memblock ptr(colmem(3,1))
rem store the working directory
cdir$=get dir$()
rem load in the dll
coldll=1
cd "bin"
load dll "dbcwithcoldet.dll",coldll
rem return to working directory
set dir cdir$
rem initialize the collision DLL with the maximum number of objects
rem needed. It's okay to leave this at it's default by setting it to 0
rem If the function is successful it will return the maximum number of objects,
rem if not 0 is returned
maxCollisionObjects=0
maxCollisionOBjects=coldetInitalize(coldll,maxCollisionObjects)
return
`================================================================
_init:
rem setup the game
rem initialize the collision dll
gosub _initialize_coldet
dim getsliding#(2)
rem load the environment
cd "media"
load object "factory.x",1
load object "factory_lmap.x",2
load image "lmap.png",2
texture object 2,2
ghost object on 2,1
rem brighten up the environment a bit
set object ambient 1,rgb(255,255,255)
set object ambient 2,rgb(255,255,255)
rem return to working directory
set dir cdir$
rem setup collision
gosub _setup_collision_objects
rem set camera
fspeed# = .75
sspeed# = .65
height# = 8.1
remstart
We have to be careful that the radius is small enough to get through doorways and climb
on stairs, but also large enough so that the camera doesn't penetrate a wall or something.
remend
radius# = 2
position camera 0,-16,0
return
`================================================================
_setup_collision_objects:
rem After the objects are created or loaded, setup the collision environment
rem by adding any objects that need to be collided with
coldetSetupObject(coldll,1,1)
coldetUpdateObject(coldll,1,xang#,yang#,zang#,posx#,posy#,posz#)
rem this object is used to mark the collision point on the walls
rem and other objects on the X Z plane
make object cube 5,1
rem a triangle to draw for collision
make object triangle 6,-1,0,0, 0,1,0, 1,0,0
color object 6,rgb(255,255,0)
set object 6,0,1,0
ghost object on 6
rem create a memblock to manipulate triangle
make mesh from object 6,6
make memblock from mesh 6,6
return
`================================================================
_move_camera:
remstart
In this example, we'll put an imaginary sphere around the camera
and test that against the environment. We've already set up
the factory as a polygon collision object.
Using the coldetUpdateSlidingCollision(), we'll let the DLL automatically
figure out the sliding collision based on our input values. This function
needs to be called every time a test for collision needs to be updated.
This function uses sphere and ray collision against the collision
object identified in the call.
remend
rem based on the camera's speed, we will create an X and Z component
rem that represent the direction the camera wants to go.
rem what y angle are we facing?
yang#=wrapvalue(camera angle y()+mousemovex())
xang#=xang#+mousemovey()
rem limit the up and down looking angle
if xang# > 80 then xang#=80
if xang# < -80 then xang#=-80
rotate camera wrapvalue(xang#),yang#,0
inc g#,0.37
g#=camStrafe(coldll,0,4.0,radius#,height#,0.75,g#,2.0,1.0)
center text 400,0,str$(g#)
return
`================================================================
_debug:
text 0,0,"CONTROLS:"
text 20,20,"Move with ARROW KEYS"
text 20,40,"Steer With Mouse"
text 0,80,"STATISTICS:"
text 20,100,"FPS = "+str$(screen fps())
text 20,120,"Polygons = "+str$(statistic(1))
text 0,160,"CAMERA:"
text 20,180,"Forward/Backward = "+str$(forward#)
text 20,200,"Right/Left = "+str$(strafe#)
text 20,220,"Camera Position X = "+str$(newx#)
text 20,240,"Camera Position Y = "+str$(camy#)
text 20,260,"Camera position Z = "+str$(newz#)
text 0,300,"COLLISION:"
text 20,320,"Sliding Collision X = "+str$(coldetGetSlidingX(coldll))
text 20,340,"Sliding Collision Y = "+str$(coldetGetSlidingY(coldll))
text 20,360,"Sliding Collision Z = "+str$(coldetGetSlidingZ(coldll))
text 20,400,"Collision Point X = "+str$(coldetGetCollisionX(coldll))
text 20,420,"Collision Point Y = "+str$(coldetGetCollisionY(coldll))
text 20,440,"Collision Point Z = "+str$(coldetGetCollisionZ(coldll))
return
rem =============================================================
rem = FUNCTIONS
rem =============================================================
function credits(rows,ht)
restore _credit
ink rgb(0,255,0),0
set text font "system",1
for n=1 to rows
read a$
center text screen width()/2,ht+(n*20),a$
next n
center text screen width()/2,screen height()-40,"press any key"
sync
wait key
_credit:
data "CREDITS"
data "=="
data "Sliding Collision Demonstration Program 2 by Latch"
data "This demo shows the use of the sliding collision function built into my"
data "DBC helper DLL for ColDet."
data "---------------"
data "Use the Arrow Keys to move and the Mouse to steer."
data "The triangle collided with will be highlighted and the collision"
data "point will be marked by a cube."
data "---------------"
data "ColDet - 3D Collision Detection Library"
data "Copyright (C) 2000 Amir Geva"
data "---------------"
data "DarkBASIC Classic helper DLL made for use with ColDet and"
data "Demonstration Programs and Examples"
data "by Latch Grapple jkk"
data "---------------"
data "Programming - Latch"
data "Texturing and Lightmapping - Latch"
data "3D Model modifications - Latch"
data "---------------"
data "Base model for the factory is the example model 'Warehouse' from"
data "DeleD CE. You can find DeleD CE at:"
data "http://www.delgine.com/"
data "---------------"
data "=="
endfunction
function camStrafe(coldll,obj,offsety#,radius#,height#,F#,G#,J#,frim#)
F#=F#*frim#
`Set up/down/left/right variables at 0 and set the control angle at invalid
u=0:d=0:l=0:r=0:a=-1
`Get control input for W/S/A/D, arrow keys, and joystick
if keystate(17) or upkey() or joystick up() then u=1
if keystate(31) or downkey() or joystick down() then d=1
if keystate(30) or leftkey() or joystick left() then l=1
if keystate(32) or rightkey() or joystick right() then r=1
`Determine which direction the player is going
if u=1 and r=1 and l!1 and d!1
a=45
else:if r=1 and u=d and l!1
a=90
else:if r=1 and d=1 and l!1 and u!1
a=135
else:if d=1 and l=r and u!1
a=180
else:if d=1 and l=1 and u!1 and r!1
a=225
else:if l=1 and u=d and r!1
a=270
else:if l=1 and u=1 and r!1 and d!1
a=315
else:if u=1 and l=r and d!1
a=0
endif:endif:endif:endif:endif:endif:endif:endif
`Initialize some variables, taking into account vertical offset and get an angle value relative to the camera's current angle
X1#=camera position x():Y1#=camera position y()-offsety#:Z1#=camera position z():B#=wrapvalue(camera angle y()+a)
`Adjust position variables so you have the parameters for the player's position before and after
X2#=X1#:Y2#=Y1#-(G#*frim#):Z2#=Z1#
if a>=0 then inc X2#,F#*sin(B#):inc Z2#,F#*cos(B#)
`Check for collisions. This part is probably messed up.
G#=slidingCollision(coldll,obj,X1#,Y1#,Z1#,X2#,Y2#,Z2#,radius#,height#,G#,J#)
X2#=getsliding#(0)
Y2#=getsliding#(1)
Z2#=getsliding#(2)
`Place the camera where it should go, taking into account the vertical offset
position camera X2#,Y2#+offsety#,Z2#
endfunction G#
function slidingCollision(coldll,obj,X1#,Y1#,Z1#,X2#,Y2#,Z2#,r#,height#,G#,J#)
co#=0.0
jumpable=0
x#=X2#
y#=Y2#
z#=Z2#
ra#=r#*0.7071
yco#=y#+co#
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#-r#,yco#,z#,1,0.0,1.0)>0
x#=coldetGetCollisionX(coldll)+r#
endif
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#+r#,yco#,z#,1,0.0,1.0)>0
x#=coldetGetCollisionX(coldll)-r#
endif
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#,yco#,z#-r#,1,0.0,1.0)>0
z#=coldetGetCollisionZ(coldll)+r#
endif
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#,yco#,z#+r#,1,0.0,1.0)>0
z#=coldetGetCollisionZ(coldll)-r#
endif
`remstart
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#+ra#,yco#,z#+ra#,1,0.0,1.0)>0
x#=coldetGetCollisionX(coldll)-ra#
z#=coldetGetCollisionZ(coldll)-ra#
endif
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#-ra#,yco#,z#-ra#,1,0.0,1.0)>0
x#=coldetGetCollisionX(coldll)+ra#
z#=coldetGetCollisionZ(coldll)+ra#
endif
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#+ra#,yco#,z#-ra#,1,0.0,1.0)>0
x#=coldetGetCollisionX(coldll)-ra#
z#=coldetGetCollisionZ(coldll)+ra#
endif
if coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#-ra#,yco#,z#+ra#,1,0.0,1.0)>0
x#=coldetGetCollisionX(coldll)+ra#
z#=coldetGetCollisionZ(coldll)-ra#
endif
`remend
r1=coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#,yco#+r#,z#,1,0.0,1.0)
if r1>0
if J#<0.0 then jumpable=1
if G#<0.0 then G#=0.0
y#=coldetGetCollisionY(coldll)+co#-r#
endif
r1=coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#,yco#-height#,z#,1,0.0,1.0)
if r1>0
if J#>0.0 then jumpable=1
if G#>0.0 then G#=0.0
y#=coldetGetCollisionY(coldll)+co#+height#
endif
if coldetSphereObjectCollision(coldll,obj,x#,Y1#,Z1#,ra#)>0
x#=X1#
endif
r1=coldetSphereObjectCollision(coldll,obj,X1#,yco#,Z1#,ra#)
if r1>0
if Y2#>Y1#
`if going up
if J#<0.0 then jumpable=1
if G#<0.0 then G#=0.0
else
`if going down
if J#>0.0 then jumpable=1
if G#>0.0 then G#=0.0
endif
y#=Y1#+co#
endif
if coldetSphereObjectCollision(coldll,obj,X1#,Y1#,z#,ra#)>0
z#=Z1#
endif
r1=coldetRayObjectCollision(coldll,obj,X1#,Y1#+co#,Z1#,X2#,Y2#+co#,Z2#,1,0.0,1.0)
if r1>0
jumpable=0
x#=X1#
y#=Y1#+co#
z#=Z1#
r1=coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#,yco#+r#,z#,1,0.0,1.0)
if r1>0
if J#<0.0 then jumpable=1
if G#<0.0 then G#=0.0
y#=coldetGetCollisionY(coldll)+co#-r#
endif
r1=coldetRayObjectCollision(coldll,obj,x#,yco#,z#,x#,yco#-height#,z#,1,0.0,1.0)
if r1>0
if J#>0.0 then jumpable=1
if G#>0.0 then G#=0.0
y#=coldetGetCollisionY(coldll)+co#+height#
endif
endif
getsliding#(0)=x#
getsliding#(1)=y#
getsliding#(2)=z#
if jumpable=1 and spacekey() then G#=J#*-1.0
endfunction G#
`================================================================
Attached is a version of the Dark Survival 2 engine that has ColDet incorporated into it. Finally, efficient physical psuedo-realism in DarkBASIC. Many thanks for your library.