Here is some code you can play with, all it gives me is a "Could not perform conversion" instantly on trying to convert it to any language.
[edit] Uploaded new code that doesn't use any plugins and loads faster. Only works with DBP 6.6 though.
`Culling Theory Ported over frum this guide by Mark Morley
`http://crownandcutlass.com/features/technicaldetails/frustum.html
`Frustum culling
`======================
`©Lost In Thought
`======================
`Main Source File
`My culling changes need this at the top of your code
`*****************************************************************************
`*****************************************************************************
`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
CullType 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
`set default culling to boxes
cullmode = 3
`fast vector distance check declarations
global ClipRange = 4
null=make vector3(ClipRange)
`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
`*****************************************************************************
`*****************************************************************************
`display stuff
sync on : sync rate 0
set camera range .5, 1500
autocam off
position camera 0, 0, -30
hide mouse
set global collision off
cubesize# = 10.0
`make test object with 4096 limbs
num_Objs = 1
testobj = num_Objs
a = 1
depth# = 0
wide# = 0
`tall
for j = 1 to 32
`across
for k = 1 to 32
if j = 1 and k = 1
make object cube testobj, cubesize#
make mesh from object testobj, 1
position object testobj, wide#, 0, depth#
else
add limb 1, a, 1
offset limb 1, a, (k-1)*20, 0, (j-1)*20
inc a, 1
endif
next k
next j
calculate object bounds 1
set object collision off 1
inc num_Objs, 1
`enter the object into the culling system
`setup_Cull_obj( object number, culling type )
`use 0 for limb culling type and 1 for object culling type
setup_Cull_obj( testobj, 0 )
do
`mlook
rotate camera camera angle x()+(mousemovey()/2),camera angle y()+(mousemovex()/2),0
if camera angle x()>90 then xrotate camera 90
if camera angle x()<-90 then xrotate camera -90
cx#=camera angle x() : cy#=camera angle y() : cz#=camera angle z()
`simple flying movement
if upkey()=1
move camera 3
endif
if downkey()=1
move camera -3
endif
if rightkey()=1
xrotate camera 0: yrotate camera cy# + 90: move camera 3: xrotate camera cx#: yrotate camera cy#
endif
if leftkey()=1
xrotate camera 0: yrotate camera cy# - 90: move camera 3: xrotate camera cx#: yrotate camera cy#
endif
`This culling code goes inside your Main loop
`****************************************************************************
`****************************************************************************
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 = 4
endif
if keystate(11) = 1
cullmode = 0
endif
cullbegtime = timer()
`Update object culling
Update_cull_objs( cullmode )
cullendtime = (timer() - cullbegtime)
`print culling result info
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 = ", cullendtime, "ms"
`****************************************************************************
`****************************************************************************
sync
loop
`This goes after your main loop
`****************************************************************************
`****************************************************************************
null=delete matrix4(ProjectionMatrix)
null=delete matrix4(ViewMatrix)
null=delete matrix4(ClipMatrix)
null=delete vector3(ClipRange)
end
function Update_cull_objs( cmode as integer )
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
if Limb_Info(j, 0).NumLimbs = 0
LtestX# = object position x( Limb_Info(j, 0).Objnum )
LtestY# = object position y( Limb_Info(j, 0).Objnum )
LtestZ# = object position z( Limb_Info(j, 0).Objnum )
else
LtestX# = 0
LtestY# = 0
LtestZ# = 0
endif
`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 + LtestX#, Limb_Info(j, i).Ypos + LtestY#, Limb_Info(j, i).Zpos + LtestZ#, Limb_Info(j, i).Spheresize )
endcase
case 2
if SphereInfrustum( Limb_Info(j, i).Xpos + LtestX#, Limb_Info(j, i).Ypos + LtestY#, Limb_Info(j, i).Zpos + LtestZ#, Limb_Info(j, i).Spheresize ) > 0
resultcheck# = CubeInfrustum( Limb_Info(j, i).Xpos + LtestX#, Limb_Info(j, i).Ypos + LtestY#, Limb_Info(j, i).Zpos + LtestZ#, Limb_Info(j, i).Cubesize )
else
resultcheck# = 0
endif
endcase
case 3
if SphereInfrustum( Limb_Info(j, i).Xpos + LtestX#, Limb_Info(j, i).Ypos + LtestY#, Limb_Info(j, i).Zpos + LtestZ#, Limb_Info(j, i).Spheresize ) > 0
resultcheck# = BoxInfrustum( Limb_Info(j, i).Xpos + LtestX#, Limb_Info(j, i).Ypos + LtestY#, Limb_Info(j, i).Zpos + LtestZ#, 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
if Limb_Info(j, 0).NumLimbs > 0
show limb Limb_Info(j, 0).Objnum, i
else
exclude object off Limb_Info(j, 0).Objnum
endif
Limb_Info(j, i).Hidden = 0
endif
else
if Limb_Info(j, i).Hidden = 0
if Limb_Info(j, 0).NumLimbs > 0
hide limb Limb_Info(j, 0).Objnum, i
else
exclude object on Limb_Info(j, 0).Objnum
endif
Limb_Info(j, i).Hidden = 1
endif
endif
endif
else
if Limb_Info(j, i).Hidden = 1
if Limb_Info(j, 0).NumLimbs > 0
show limb Limb_Info(j, 0).Objnum, i
else
exclude object off Limb_Info(j, 0).Objnum
endif
Limb_Info(j, i).Hidden = 0
endif
endif
endif
endif
next i
next j
endfunction
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) = 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, ctype as integer )
`use ctype = 0 for limb culling and ctype = 1 for whole object
inc NumCullObjs, 1
if ctype = 0
perform checklist for object limbs objnum
numterrlimbs = checklist quantity()
empty checklist
if numterrlimbs-1 > maxLimbs then maxLimbs = numterrlimbs-1
else
numterrlimbs = 1
endif
dim Limb_Info(NumCullObjs, maxLimbs) as Cull_Obj_Data
Limb_Info(NumCullObjs, 0).CullType = ctype
`store object numbers
Limb_Info(NumCullObjs, 0).Objnum = objnum
Limb_Info(NumCullObjs, 0).NumLimbs = numterrlimbs-1
for i = 0 to numterrlimbs-1
if ctype = 0
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)
else
ellipposx# = object collision center x(objnum)
ellipposy# = object collision center y(objnum)
ellipposz# = object collision center z(objnum)
ellipsizex# = object size x(objnum, 1)*0.5
limb_max_size# = ellipsizex#
ellipsizey# = object size y(objnum, 1)*0.5
if ellipsizey# > limb_max_size# then limb_max_size# = ellipsizey#
ellipsizez# = object size z(objnum, 1)*0.5
if ellipsizez# > limb_max_size# then limb_max_size# = ellipsizez#
`positions to use for all 3 types of testing
Limb_Info(NumCullObjs, 0).Xpos = ellipposx#
Limb_Info(NumCullObjs, 0).Ypos = ellipposy#
Limb_Info(NumCullObjs, 0).Zpos = ellipposz#
endif
`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#
`****************************************************************************
`****************************************************************************