Since your custom collision routine is checking the size and the position in three dimensions, you could probably increase performance by running your own sphere collision routine instead of cube checking where you only check the distance between radii instead of check x y and z.
You can further improve the check by using squared distances instead of using SQRT() to find the actual distance:
rem custom sphere collision example
rem by latch
rem september 2011
set display mode 800,600,32
sync on
sync rate 0
hide mouse
autocam off
rem a matrix for reference
make matrix 1,1000,1000,10,10
rem store the radii of all the spheres so I can use that information later
dim radius#(20)
rem some spheres
for obj=1 to 20
make object sphere obj,25
if obj=1 then color object obj,rgb(255,0,0)
if obj > 1
position object obj,rnd(1000),13,rnd(1000)
endif
radius#(obj)=25/2.0
next obj
`=================================================================
_test_1:
remstart
for this test, we'll use DBC's built in sphere collision and just
run general fps to get an idea of performance
remend
rem set up sphere collision
for obj=1 to 20
set object collision to spheres obj
set object collision on obj
next obj
do
text 0,0,"TEST 1 - Built in Sphere Collision"
text 0,20,"FPS = "+str$(screen fps())
text 0,80,"Press SPACE to run test 2"
rem test collision
bang=object collision(1,0)
if bang
text 0,40,"COLLISION DETECTED!!!! object = "+str$(bang)
endif
rem move sphere
gosub _move_object
rem use space key toggle to switch to test 2
os=ns
ns=spacekey()
if os > ns
goto _test_2
endif
sync
loop
`=================================================================
_test_2:
remstart
This test will use calculated sphere collision testing based on
the distances of the centers of the spheres
remend
rem turn off collision on all objects
for obj=1 to 20
set object collision off obj
next obj
do
text 0,0,"TEST 2 - Calculated Sphere Collision"
text 0,20,"FPS = "+str$(screen fps())
text 0,80,"Press SPACE to run test 1"
rem test collision
bang=test_sphere_collision(1,0)
if bang
text 0,40,"COLLISION DETECTED!!!! object = "+str$(bang)
endif
rem move sphere
gosub _move_object
rem use space key toggle to switch to test 2
os=ns
ns=spacekey()
if os > ns
goto _test_1
endif
sync
loop
`=================================================================
_move_object:
speed=1
if upkey() then z=z+speed
if downkey() then z=z-speed
if rightkey() then x=x+speed
if leftkey() then x=x-speed
position object 1,x,13,z
position camera x,30,z-100
return
`=================================================================
function test_sphere_collision(obj1,obj2)
remstart
obj1 == the object that is going to collide with something
obj2 == the object that will be collided into
set to 0 to test against all other objects
except obj1
This function would be expanded to have some constraints or limits on how
to search through all objects for collision testing for efficiency but for
this example, I know the obejcts are from 1 to 20 so I won't worry about
that right now.
remend
rem check for all or one test
if obj2 < 1
rem ALL
for n=1 to 20
rem skip obj1
if n ! obj1
rem test collision and exit when hit
dx#=object position x(obj1)-object position x(n)
dy#=object position y(obj1)-object position y(n)
dz#=object position z(obj1)-object position z(n)
if ((dx#*dx#)+(dy#*dy#)+(dz#*dz#)) < ((radius#(obj1)+radius#(n))*(radius#(obj1)+radius#(n)))
exitfunction n
endif
endif
next n
else
rem single object test
dx#=object position x(obj1)-object position x(obj2)
dy#=object position y(obj1)-object position y(obj2)
dz#=object position z(obj1)-object position z(obj2)
if ((dx#*dx#)+(dy#*dy#)+(dz#*dz#)) < ((radius#(obj1)+radius#(obj2))*(radius#(obj1)+radius#(obj2)))
exitfunction 1
endif
endif
endfunction 0
Enjoy your day.