Culling is 15-20 times faster in this code and gives me an extra 10-50 fps over the other code depending on camera data.
`Frustum culling Ported over frum this guide by Mark Morley
`http://crownandcutlass.com/features/technicaldetails/frustum.html
`Initialize
sync on
sync rate 0
hide mouse
disable escapekey
if check display mode(800,600,32)=1
SET DISPLAY MODE 800,600,32, 0
else
SET DISPLAY MODE 800,600,16, 0
endif
`set gamma 255,255,255
Autocam off
Set Camera Range 10,10000
color backdrop rgb(0,0,0)
backdrop off
set ambient light 100
scale listener 100
`Get the map to load
file$=cl$()
file$=replace$(file$,chr$(34),"")
if file$=""
file$="mapsCity_14.dbo"
endif
cls
sync
splashdelay=1500
`Startup screen
if escape=0
load image "logo_db.bmp",1, 1
cls
paste image 1,(screen width()-512)/2,(screen height()-152)/2
sync
wait splashdelay
delete image 1
endif
if escape=0
load image "logo_3DWorldStudio.bmp",1, 1
cls
paste image 1,(screen width()-386)/2,(screen height()-164)/2
sync
wait splashdelay
delete image 1
endif
if escape=0
load image "logo_ng.bmp",1, 1
cls
paste image 1,(screen width()-430)/2,(screen height()-88)/2
sync
wait splashdelay
delete image 1
endif
if escape=0
load image "logo_arteria.bmp",1, 1
cls
paste image 1,(screen width()-330)/2,(screen height()-152)/2
sync
wait splashdelay
delete image 1
endif
cls
ink rgb(255,255,255),rgb(255,255,255)
text screen width()/2-20,screen height()/2,"Loading..."
sync
`Constants
#Constant TYPE_NGC_ELLIP=1
#Constant TYPE_NGC_MESH=2
#Constant ELLIP_2_ELLIP=1
#Constant ELLIP_2_POLY=2
#Constant RESP_STICK=1
#Constant RESP_SLIDE=2
#Constant RESP_SLIDE_NO_SLOPES=6
#Constant RESP_SLIDE_NO_GRAV=10
#Constant RESP_SLIDE_NO_ACCEL=18
#Constant RESP_NONE=32
#Constant DYN_NO_RESP=1
#Constant DYN_RESP=2
#Constant DYN_RESP_LOCK=6
#Constant DYN_RESP_LOCK_NOTURN=14
#Constant NCULL_CLOCK 0
#Constant NCULL_COUNTER_CLOCK 1
#Constant NCULL_NONE 2
#Constant TYPE_PLAYER=10
#Constant TYPE_BRUSH=11
#Constant TYPE_TERRAIN=12
`Globals
global world
global camera=0
global playerobject=1
global player=1
global Player_Speed#=450.0
global gravity#=600.0
global newobjectcounter=1000
global skyenabled
`Structures
type flare
object
radius#
color
range#
nextflare
targetalpha#
alpha#
endtype
global dim flares(100) as flare
global countflares
`Start collision
rem Starts the collision system, this MUST be called before you can call any other
rem collision commands
StartCollisionPRO(000000000,000000000,000000000)
setoctreebuildpro(1)
setoctreethresholdpro(400)
SetCollisionsPro(TYPE_PLAYER,TYPE_BRUSH,ELLIP_2_POLY,RESP_SLIDE_NO_ACCEL,DYN_NO_RESP)
SetCollisionsPro(TYPE_PLAYER,TYPE_TERRAIN,ELLIP_2_POLY,RESP_SLIDE_NO_ACCEL,DYN_NO_RESP)
`Create player
setstaticbuildpro(0)
make object sphere playerobject,2
position object playerobject,0,128,0
hide object playerobject
CollisionTypePRO(playerobject,TYPE_PLAYER)
SetObjRadiusPRO(playerobject,32,80,32)
setstaticbuildpro(1)
#constant x_axis 1
#constant y_axis 2
#constant z_axis 3
`My culling chnages
`dim arrays for culling
dim frustum#(5,3)
dim clip#(15)
`gloabls for multiple objects
global maxLimbs = 0
global NumCullObjs = 0
global num_Objs = 0
`setup type for cull objs
type Cull_Obj_Data
Objnum as integer
NumLimbs as integer
Cull_on as boolean
Check as boolean
Hidden as boolean
Xpos as float
Ypos as float
Zpos as float
Cubesize as float
BoxXsize as float
BoxYsize as float
BoxZsize as float
Spheresize as float
endtype
dim Limb_Info(0, 0) as Cull_Obj_Data
`fast vector distance check declarations
global ClipRange = 4
null=make vector3(ClipRange)
`Load world
LoadWorld(file$)
sky=NewObjectIndex()
if skyenabled=1
load object "modelsskydome.x",sky
scale object sky,1000000,1000000,1000000
set object light sky,0
set object ambient sky,0
set object fog sky,0
endif
`set default culling to boxes
cullmode = 3
`make vectors and matrix4 for distance and frustum checks
ProjectionMatrix = 1
ViewMatrix = 2
ClipMatrix = 3
null=MAKE MATRIX4(ProjectionMatrix)
null=MAKE MATRIX4(ClipMatrix)
null=MAKE MATRIX4(ViewMatrix)
`get the screen space matrix (you don't need to update this matrix4 unless
`resolution or aspect etc changes
Projection Matrix4 ProjectionMatrix
remstart
testlimb=NewObjectIndex()
perform checklist for object limbs world
numlimbs = checklist quantity()
empty checklist
for i = 0 to numlimbs-1
make object from limb testlimb, world, i
make mesh from object 99, testlimb
delete mesh 99
delete object testlimb
next i
remend
`=====================================================
`Main loop
`=====================================================
Beg_Time# = timer() + 1000
Old_Time# = Beg_Time# - 40
do
Time_Update# = timer()
if Time_Update# > Beg_Time#
Time_Speed# = (Time_Update# - Old_Time#)/1000
Old_Time# = Time_Update#
gosub Mlook_Movement
endif
`Update collision
RunCollisionPRO()
CamX# = object position x(playerobject)
CamY# = object position y(playerobject)
CamZ# = object position z(playerobject)
`update the camera to the players position after collision
position camera CamX#, CamY#+30, CamZ#
rotate camera CamAX#, CamAY#, CamAZ#
position listener CamX#, CamY#+30, CamZ#
rotate listener CamAX#, CamAY#, CamAZ#
`Update flare entities
UpdateFlares()
`Sky
if object exist(sky)
position object sky,CamX#, CamY#, CamZ#
endif
`****************************************************************************
`****************************************************************************
if keystate(2) = 1
cullmode = 1
endif
if keystate(3) = 1
cullmode = 2
endif
if keystate(4) = 1
cullmode = 3
endif
if keystate(5) = 1
cullmode = 6
endif
if keystate(11) = 1
cullmode = 0
endif
cullbegtime = hitimer(10000)
`update all cull objects' limbs
Update_cull_objs( cullmode )
cullendtime = hitimer(10000) - cullbegtime
cullendtimeres# = cullendtime * .10
`****************************************************************************
`****************************************************************************
framerate=screen fps()
set cursor 0, 30
print "FPS: ",framerate
print "Polys: ",statistic(1)
print "use keys 1-3 for different culling 1 sphere, 2 cube, 3 box"
print "key 4 to turn of culling but keep culled limbs hidden"
print "key 0 showes all : Cull time = ", cullendtimeres#, "ms"
sync
if escapekey()=1
load image "ad.bmp", 1, 1
paste image 1, 0, 0
sync
wait 2000
end
endif
loop
`****************************************************************************
`****************************************************************************
null=delete matrix4(ProjectionMatrix)
null=delete matrix4(ViewMatrix)
null=delete matrix4(ClipMatrix)
null=delete vector3(ClipRange)
end
function Update_cull_objs( cmode )
resultcheck# = 0
gosub Extractfrustum
`check each object setup for culling
for j = 1 to NumCullObjs
`test each limb against the frustum (you would use an octree to cut down
`the checks)
for i = 0 to Limb_Info(j, 0).NumLimbs
`use to turn culling off for this limb permanently
if Limb_Info(j, i).Cull_on = 1
`will be used to turn culling off temporarily for octrees later
if Limb_Info(j, i).Check = 1
if cmode > 0
select cmode
case 1
resultcheck# = SphereInfrustum( Limb_Info(j, i).Xpos, Limb_Info(j, i).Ypos, Limb_Info(j, i).Zpos, Limb_Info(j, i).Spheresize )
endcase
case 2
if SphereInfrustum( Limb_Info(j, i).Xpos, Limb_Info(j, i).Ypos, Limb_Info(j, i).Zpos, Limb_Info(j, i).Spheresize ) > 0
resultcheck# = CubeInfrustum( Limb_Info(j, i).Xpos, Limb_Info(j, i).Ypos, Limb_Info(j, i).Zpos, Limb_Info(j, i).Cubesize )
else
resultcheck# = 0
endif
endcase
case 3
if SphereInfrustum( Limb_Info(j, i).Xpos, Limb_Info(j, i).Ypos, Limb_Info(j, i).Zpos, Limb_Info(j, i).Spheresize ) > 0
resultcheck# = BoxInfrustum( Limb_Info(j, i).Xpos, Limb_Info(j, i).Ypos, Limb_Info(j, i).Zpos, Limb_Info(j, i).BoxXsize, Limb_Info(j, i).BoxYsize, Limb_Info(j, i).BoxZsize )
else
resultcheck# = 0
endif
endcase
endselect
if cmode < 4
if resultcheck# > 0
if Limb_Info(j, i).Hidden = 1
show limb Limb_Info(j, 0).Objnum, i
Limb_Info(j, i).Hidden = 0
endif
else
if Limb_Info(j, i).Hidden = 0
hide limb Limb_Info(j, 0).Objnum, i
Limb_Info(j, i).Hidden = 1
endif
endif
endif
else
if Limb_Info(j, i).Hidden = 1
show limb Limb_Info(j, 0).Objnum, i
Limb_Info(j, i).Hidden = 0
endif
endif
endif
endif
next i
next j
endfunction
`update player movement and mouse look
Mlook_Movement:
offsetx# = 0.0
offsety# = 0.0
offsetz# = 0.0
`mouselook
fMouseX = MouseMoveX()
fMouseY = MouseMoveY()
CamAX# = object Angle X(playerobject)+(fMouseY/3.5)
CamAY# = WrapValue( object Angle Y(playerobject)+(fMouseX/3.5) )
CamAZ# = Object Angle Z(playerobject)
If CamAX# > 80 then CamAX# = 80
If CamAX# < -80 then CamAX# = -80
Rotate object playerobject, CamAX#, CamAY#, CamAZ#
`simple movement
If upkey()=1
offsetx# = offsetx# + newxvalue(0, CamAY#, Player_Speed#*Time_Speed#)
offsety# = offsety# + newyvalue(0, 0, Player_Speed#*Time_Speed#)
offsetz# = offsetz# + newzvalue(0, CamAY#, Player_Speed#*Time_Speed#)
endif
If downkey()=1
offsetx# = offsetx# + newxvalue(0, CamAY#, 0.0-(Player_Speed#*Time_Speed#))
offsety# = offsety# + newyvalue(0, 0, 0.0-(Player_Speed#*Time_Speed#))
offsetz# = offsetz# + newzvalue(0, CamAY#, 0.0-(Player_Speed#*Time_Speed#))
endif
If leftkey()=1
offsetx# = offsetx# + newxvalue(0, CamAY#-90, Player_Speed#*Time_Speed#)
offsety# = offsety# + newyvalue(0, 0, Player_Speed#*Time_Speed#)
offsetz# = offsetz# + newzvalue(0, CamAY#-90, Player_Speed#*Time_Speed#)
endif
If rightkey()=1
offsetx# = offsetx# + newxvalue(0, CamAY#+90, Player_Speed#*Time_Speed#)
offsety# = offsety# + newyvalue(0, 0, Player_Speed#*Time_Speed#)
offsetz# = offsetz# + newzvalue(0, CamAY#+90, Player_Speed#*Time_Speed#)
endif
CamX# = object position x(playerobject) + offsetx#
CamY# = object position y(playerobject) - (gravity#*Time_Speed#) + offsety#
CamZ# = object position z(playerobject) + offsetz#
`update all objects to the player's position before collision
position object playerobject, CamX#, CamY#, CamZ#
return
Extractfrustum:
t# = 0
`get the camera space matrix
VIEW MATRIX4 ViewMatrix
`multiply the camera space matrix by the screen space matrix
`to get the clip matrix to get the frustum planes from
MULTIPLY MATRIX4 ClipMatrix, ViewMatrix, ProjectionMatrix
`assign the clip matrix elements to an array so we can use them
for i = 0 to 15
clip#(i) = DK Get Matrix4 Element( ClipMatrix, i )
next i
`/* Extract the numbers for the RIGHT plane */
frustum#(0,0) = clip#( 3) - clip#( 0)
frustum#(0,1) = clip#( 7) - clip#( 4)
frustum#(0,2) = clip#(11) - clip#( 8)
frustum#(0,3) = clip#(15) - clip#(12)
`/* Normalize the result */
rangeClipx# = frustum#(0,0)
rangeClipy# = frustum#(0,1)
rangeClipz# = frustum#(0,2)
t#=1/ClipDistance( rangeClipx#, rangeClipy#, rangeClipz# )
frustum#(0,0) = frustum#(0,0) * t#
frustum#(0,1) = frustum#(0,1) * t#
frustum#(0,2) = frustum#(0,2) * t#
frustum#(0,3) = frustum#(0,3) * t#
`/* Extract the numbers for the LEFT plane */
frustum#(1,0) = clip#( 3) + clip#( 0)
frustum#(1,1) = clip#( 7) + clip#( 4)
frustum#(1,2) = clip#(11) + clip#( 8)
frustum#(1,3) = clip#(15) + clip#(12)
`/* Normalize the result */
`use distance from right plane to normalize data
frustum#(1,0) = frustum#(1,0) * t#
frustum#(1,1) = frustum#(1,1) * t#
frustum#(1,2) = frustum#(1,2) * t#
frustum#(1,3) = frustum#(1,3) * t#
`/* Extract the BOTTOM plane */
frustum#(2,0) = clip#( 3) + clip#( 1)
frustum#(2,1) = clip#( 7) + clip#( 5)
frustum#(2,2) = clip#(11) + clip#( 9)
frustum#(2,3) = clip#(15) + clip#(13)
`/* Normalize the result */
rangeClipx# = frustum#(2,0)
rangeClipy# = frustum#(2,1)
rangeClipz# = frustum#(2,2)
t#=1/ClipDistance( rangeClipx#, rangeClipy#, rangeClipz# )
frustum#(2,0) = frustum#(2,0) * t#
frustum#(2,1) = frustum#(2,1) * t#
frustum#(2,2) = frustum#(2,2) * t#
frustum#(2,3) = frustum#(2,3) * t#
`/* Extract the TOP plane */
frustum#(3,0) = clip#( 3) - clip#( 1)
frustum#(3,1) = clip#( 7) - clip#( 5)
frustum#(3,2) = clip#(11) - clip#( 9)
frustum#(3,3) = clip#(15) - clip#(13)
`/* Normalize the result */
`use distance from bottom plane to normalize data
frustum#(3,0) = frustum#(3,0) * t#
frustum#(3,1) = frustum#(3,1) * t#
frustum#(3,2) = frustum#(3,2) * t#
frustum#(3,3) = frustum#(3,3) * t#
`/* Extract the FAR plane */
frustum#(4,0) = clip#( 3) - clip#( 2)
frustum#(4,1) = clip#( 7) - clip#( 6)
frustum#(4,2) = clip#(11) - clip#(10)
frustum#(4,3) = clip#(15) - clip#(14)
`/* Normalize the result */
rangeClipx# = frustum#(4,0)
rangeClipy# = frustum#(4,1)
rangeClipz# = frustum#(4,2)
t#=1/ClipDistance( rangeClipx#, rangeClipy#, rangeClipz# )
frustum#(4,0) = frustum#(4,0) * t#
frustum#(4,1) = frustum#(4,1) * t#
frustum#(4,2) = frustum#(4,2) * t#
frustum#(4,3) = frustum#(4,3) * t#
`/* Extract the NEAR plane */
frustum#(5,0) = clip#( 3) + clip#( 2)
frustum#(5,1) = clip#( 7) + clip#( 6)
frustum#(5,2) = clip#(11) + clip#(10)
frustum#(5,3) = clip#(15) + clip#(14)
`/* Normalize the result */
rangeClipx# = frustum#(5,0)
rangeClipy# = frustum#(5,1)
rangeClipz# = frustum#(5,2)
t#=1/ClipDistance( rangeClipx#, rangeClipy#, rangeClipz# )
frustum#(5,0) = frustum#(5,0) * t#
frustum#(5,1) = frustum#(5,1) * t#
frustum#(5,2) = frustum#(5,2) * t#
frustum#(5,3) = frustum#(5,3) * t#
return
function setup_Cull_obj( objnum as integer )
inc NumCullObjs, 1
perform checklist for object limbs objnum
numterrlimbs = checklist quantity()
empty checklist
if numterrlimbs-1 > maxLimbs then maxLimbs = numterrlimbs-1
dim Limb_Info(NumCullObjs, maxLimbs) as Cull_Obj_Data
`store object numbers
Limb_Info(NumCullObjs, 0).Objnum = objnum
Limb_Info(NumCullObjs, 0).NumLimbs = numterrlimbs-1
for i = 0 to numterrlimbs-1
make object from limb num_Objs, objnum, i
ellipposx# = object collision center x(num_Objs)
ellipposy# = object collision center y(num_Objs)
ellipposz# = object collision center z(num_Objs)
ellipsizex# = object size x(num_Objs, 1)*0.5
limb_max_size# = ellipsizex#
ellipsizey# = object size y(num_Objs, 1)*0.5
if ellipsizey# > limb_max_size# then limb_max_size# = ellipsizey#
ellipsizez# = object size z(num_Objs, 1)*0.5
if ellipsizez# > limb_max_size# then limb_max_size# = ellipsizez#
delete object num_Objs
`positions to use for all 3 types of testing
Limb_Info(NumCullObjs, i).Xpos = ellipposx# + limb position x(objnum, i)
Limb_Info(NumCullObjs, i).Ypos = ellipposy# + limb position y(objnum, i)
Limb_Info(NumCullObjs, i).Zpos = ellipposz# + limb position z(objnum, i)
`size to use for cube testing
Limb_Info(NumCullObjs, i).Cubesize = limb_max_size#
`sizes to use for box testing
Limb_Info(NumCullObjs, i).BoxXsize = ellipsizex#
Limb_Info(NumCullObjs, i).BoxYsize = ellipsizey#
Limb_Info(NumCullObjs, i).BoxZsize = ellipsizez#
`size to use for sphere testing
Limb_Info(NumCullObjs, i).Spheresize = ClipDistance( ellipsizex#, ellipsizey#, ellipsizez# )
Limb_Info(NumCullObjs, i).Cull_on = 1
Limb_Info(NumCullObjs, i).Check = 1
Limb_Info(NumCullObjs, i).Hidden = 0
next i
endfunction
`distance from plane
`distance = A * X + B * Y + C * Z + D
`returns 0 for outside and distance of sphere from camera if in
function SphereInfrustum( x#, y#, z#, radius# )
`set result to default
result# = 0
`check to see if the center point is within the radius of the sphere
`to the planes
for p = 0 to 5
d# = (frustum#(p,0) * x#) + (frustum#(p,1) * y#) + (frustum#(p,2) * z#) + frustum#(p,3)
`if not then it is out
if d# <= 0-radius#
exitfunction result#
endif
next p
`get the distange from the sphere to the camera if inside
`usefull for LOD calcs ;-)
result# = d# + radius#
endfunction result#
function CubeInfrustum( x#, y#, z#, size# )
`test each point of the box against each plane
minx# = x#-size#
maxx# = x#+size#
miny# = y#-size#
maxy# = y#+size#
minz# = z#-size#
maxz# = z#+size#
for p = 0 to 5
a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
`if none of the points are in then exit test
if a = 0
exit
endif
next p
`if exited from none in give 0 as a result
if a = 0
exitfunction 0
endif
`else give a 1
endfunction 1
function BoxInfrustum( x#, y#, z#, sizex#, sizey#, sizez# )
minx# = x#-sizex#
maxx# = x#+sizex#
miny# = y#-sizey#
maxy# = y#+sizey#
minz# = z#-sizez#
maxz# = z#+sizez#
for p = 0 to 5
a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * minz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * miny#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * minx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
if (frustum#(p,0) * maxx#) + (frustum#(p,1) * maxy#) + (frustum#(p,2) * maxz#) + frustum#(p,3) > 0
a = 1
endif
endif
if a = 0
exit
endif
next p
if a = 0
exitfunction 0
endif
endfunction 1
`simple and fast box in box function Thanks to Ideas from Sparky
`returns 0 if totally outside, 1 if partially overlapping, and
`-1 if the source (box 1) is totally inside the destination (box 2)
function box_in_Box(posx1#, posy1#, posz1#, posx2#, posy2#, posz2#, sizex1#, sizey1#, sizez1#, sizex2#, sizey2#, sizez2#)
minx1# = posx1# - sizex1#
miny1# = posy1# - sizey1#
minz1# = posz1# - sizez1#
maxx1# = posx1# + sizex1#
maxy1# = posy1# + sizey1#
maxz1# = posz1# + sizez1#
minx2# = posx2# - sizex2#
miny2# = posy2# - sizey2#
minz2# = posz2# - sizez2#
maxx2# = posx2# + sizex2#
maxy2# = posy2# + sizey2#
maxz2# = posz2# + sizez2#
if ( minx2#>maxx1# || minx1#>maxx2# ) then exitfunction 0
if ( miny2#>maxy1# || miny1#>maxy2# ) then exitfunction 0
if ( minz2#>maxz1# || minz1#>maxz2# ) then exitfunction 0
a = 0
if ( minx1#>=minx2# && maxx1#<=maxx2# ) then inc a, 1
if ( miny1#>=miny2# && maxy1#<=maxy2# ) then inc a, 1
if ( minz1#>=minz2# && maxz1#<=maxz2# ) then inc a, 1
if a = 3 then exitfunction -1
endfunction 1
`simple and fast distance function using vectors
function ClipDistance( x as float, y as float, z as float )
set vector3 ClipRange, x, y, z
temp#=length vector3(ClipRange)
endfunction temp#
`****************************************************************************
`****************************************************************************
It requires these 2 plugin sets to compile.
http://forum.thegamecreators.com/?m=forum_view&t=85209&b=18 for acurate time testing (can be removed with no culling effects)
http://forum.thegamecreators.com/?m=forum_view&t=67196&b=5 for actual culling
I also posted an optimized and more portable version of my stand alone culling code here:
http://forum.thegamecreators.com/?m=forum_view&t=67369&b=6