I didn't know about the "change mesh" command. It doesn't seem to work for me. It seems to do the same as
delete object
make object (from mesh)
, which when i tried it, kept the "format" of the object intact- ie if it started with shared vertices it kept them. Perhaps this is a DBP version issue or i have misunderstood. If you could edit my code and make it work without recourse to memblocks, i'd be very happy to see it.
Anyway "change mesh" seems a very useful function - especially for changing limbs, so thanks for the info.
OK here's a new version. Press [space] to explode, [control] to reset.
Rem Project: vertexdata explode
Rem Created: 17/12/2008 21:14:21
Rem ***** Main Source File *****
`an example of exploding a sphere using vertexdata commands
`i read somewhere vertexdata commands might be faster than using memblocks
`haven't checked this yet.
#constant temp_memblocknum 1
sync on
sync rate 0
autocam off
hide mouse
make object sphere 1,50,25,25 `you can put other objects here, but may want to change the function
`that gives initial velocities based on positions..
`load image "Marble_107_seamless_sample.jpg",1
roll object left 1,5 `try to disguise regularity of lat/long shape
single_pixel_image(1,250,150,255,255) `purple
single_pixel_image(2,100,100,100,255) `d.grey
make object plain 3,5000,5000
`load image "3334.jpg",3
_make_chequer_image(3)
texture object 3,3
position object 3,0.0,-40.1,0.0
scale object texture 3,50,50
xrotate object 3,90.0
REMSTART
`add onion rings?
make mesh from object 1,1
add limb 1,1,1
`add limb 1,2,1
scale limb 1,1,90,90,90
`scale limb 1,2,80,80,80
rotate limb 1,1,rnd(360),rnd(360),rnd(360)
`rotate limb 1,2,rnd(360),rnd(360),rnd(360)
delete mesh 1
make mesh from object 1,1
delete object 1
make object 1,1,1
delete mesh 1
REMEND
`Using memblock is a trick to get from the default format, where there are a minimal number
`of vertices, with a list of vertices, and faces listing their vertices (like DB classic
`used to have) , to the format where every polygon has 3 unique vertices, resulting in about
`six times as many vertices overall. This is hella inefficient, but means we can explode
`the object!
`it's a shame it can't easily be found which vertices share the same space. This would be easy
`to get during the process that converts from one format to the other, but it's a black box!
`i should look more into using memblock objects, because when writing meblocks, you can use either
`format... a job for another day!
`REMSTART
`TRICK TO CHANGE OBJECT TO NO SHARED VERTICES FORMAT ===========================
make mesh from object 1,1
delete object 1
make memblock from mesh 1,1
make mesh from memblock 1,1
delete memblock 1
make object 1,1,1
`===============================================================================
`REMEND
`make mesh from object 1,1
`change mesh 1,0,1
set object cull 1,0 `so you can see backfaces
`shadow object!
make object 2,1,3
set object 2,1,1,0,1,1,0,1
_obj2setstuff()
set object 3,1,0,0,1,0,0,0
obj=1
limb=0
LOCK VERTEXDATA FOR LIMB OBJ,LIMB,1
numverts=GET VERTEXDATA VERTEX COUNT()
numfaces=numverts/3
dim centrepos#(3,numfaces)
dim offsetpos#(3,numverts)
dim centrevel#(3,numfaces)
dim centreposreset#(3,numfaces)
`rotating pieces! rotate about fixed axis only..
dim rotaxis#(3,numfaces)
dim angspd#(numfaces)
dim angrot#(numfaces)
dim rpll#(3,numverts)
dim rperp#(3,numverts)
dim rperp2#(3,numverts) `<-- could pull all together in matrix, but tad less confusing this way..
FOR N=0 TO numverts-1
X# = GET VERTEXDATA POSITION X(N)
Y# = GET VERTEXDATA POSITION Y(N)
Z# = GET VERTEXDATA POSITION Z(N)
offsetpos#(1,n)=x#
offsetpos#(2,n)=y#
offsetpos#(3,n)=z#
NEXT N
UNLOCK VERTEXDATA
for f=0 to numfaces-1
n=f*3
na=n+1
nb=n+2
for c=1 to 3
temp#=(offsetpos#(c,n)+offsetpos#(c,na)+offsetpos#(c,nb))/3.0
offsetpos#(c,n)=offsetpos#(c,n)-temp#
offsetpos#(c,na)=offsetpos#(c,na)-temp#
offsetpos#(c,nb)=offsetpos#(c,nb)-temp#
centrepos#(c,f)=temp# `not sure whether is more efficient just to sub in this for temp# above..
centreposreset#(c,f)=temp#
next c
next f
`get data for rotating pieces. want radom rotation axes for pieces.
`in actual fact, will proably like to have axes predominantly in plane of piece later.
for f=0 to numfaces-1
`make axes....
mag#=0.0
for c= 1 to 3
rotaxis#(c,f)=rnd(5)-2.5
inc mag#,rotaxis#(c,f)*rotaxis#(c,f)
next c
mag#=sqrt(mag#)
`normalise..
for c=1 to 3
rotaxis#(c,f)=rotaxis#(c,f)/mag#
next c
`get components parallel to, perpendicular to, and perpendicular to both..
s=3*f-1
for a=1 to 3
v=s+a
dotp#=offsetpos#(1,v)*rotaxis#(1,f)+offsetpos#(2,v)*rotaxis#(2,f)+offsetpos#(3,v)*rotaxis#(3,f)
for x=1 to 3
rpll#(x,v)=dotp#*rotaxis#(x,f)
rperp#(x,v)=offsetpos#(x,v)-rpll#(x,v)
next x
`last axis is x prod of other 2.., but use pll direction, so same mag as rperp
rperp2#(1,v)=rperp#(2,v)*rotaxis#(3,f)-rperp#(3,v)*rotaxis#(2,f)
rperp2#(2,v)=rperp#(3,v)*rotaxis#(1,f)-rperp#(1,v)*rotaxis#(3,f)
rperp2#(3,v)=rperp#(1,v)*rotaxis#(2,f)-rperp#(2,v)*rotaxis#(1,f)
next a
angspd#(f)=0.5*(rnd(11)-5.5)
next f
position camera 100,10,300
point camera 0,-40,0
`set directional light 0,-1,-0.1,-3 `pointing away from camera
set directional light 0,0.0,-1,0.0 `pointing down
color backdrop 1000
color ambient light rgb(140,140,140)
set ambient light 100
set camera fov 25
global nfm1
nfm1=numfaces-1
timenow=timer()
do
timelast=timenow
timenow=timer()
timechange=timenow-timelast
timechange=timechange
position camera 0,-40,0
rotate camera 15.0,camera angle y()+timechange*0.02,0.0
move camera -300
if controlkey() `to test how much simple (is thing above ground) test is affecting framerate..
exploded=0
gravity#=0.0
delete object 1:make object 1,1,1:set object cull 1,0
`change mesh 1,0,1
delete object 2:make object 2,1,3:set object 2,1,1,0,1,1,0,1
`change mesh 2,0,1
_obj2setstuff()
for f=1 to nfm1
for c=1 to 3
centrepos#(c,f)=centreposreset#(c,f)
centrevel#(c,f)=0.0
next c
angrot#(f)=0.0
next f
endif
if exploded=1 or exploded=0
LOCK VERTEXDATA FOR LIMB OBJ,LIMB,1
for f=0 to nfm1 `numfaces-1
if centrepos#(2,f)<-40 `SIMPLE ABOVE GROUND CHECK.. quite inefficient - ignores ordering of particles etc.
`REMSTART
if centrevel#(2,f)<0.001 `a better collision system could make this part a lot faster!
`^.. a bit of a fudge -if timechange is large, can still mess up..
centrevel#(1,f)=centrevel#(1,f)*0.6
centrevel#(3,f)=centrevel#(3,f)*0.6
centrevel#(2,f)=-0.2*centrevel#(2,f)
`centrepos#(2,f)=-40
endif
`REMEND
`centrevel#(1,f)=0.0
`centrevel#(3,f)=0.0
`centrevel#(2,f)=0.0
else
dec centrevel#(2,f),gravity#*timechange `GRAVITY
if exploded=1 then angrot#(f)=wrapvalue(angrot#(f)+angspd#(f)*timechange) `SPIN FACES!
endif
for c=1 to 3
inc centrepos#(c,f),centrevel#(c,f)*timechange
next c
ct#=cos(angrot#(f)):st#=sin(angrot#(f))
s=3*f-1
for a=1 to 3
v=s+a
for c=1 to 3
offsetpos#(c,v)=rpll#(c,v)+ct#*rperp#(c,v)+st#*rperp2#(c,v) `SPINNING
next c
set vertexdata position v,centrepos#(1,f)+offsetpos#(1,v),centrepos#(2,f)+offsetpos#(2,v),centrepos#(3,f)+offsetpos#(3,v)
next a
next f
UNLOCK VERTEXDATA
`shadow object 2. note maybe good to store total positions...
LOCK VERTEXDATA FOR LIMB 2,LIMB,1
greycol=rgb(50,50,50)
for f=1 to nfm1
s=3*f-1
for a=1 to 3
v=s+a
xp#=centrepos#(1,f)+offsetpos#(1,v)
zp#=centrepos#(3,f)+offsetpos#(3,v)
set vertexdata position v,xp#,-40.0,zp#
`uv positions via projection!
set vertexdata uv v,xp#/100.0,zp#/100.0
`this bit only needs to be done once :
set vertexdata diffuse v, greycol `<-- won't work unless light switched on for obj..
set vertexdata normals v,0.0,-1.0,0.0 `point them down - so only responds to ambient
next a
next f
UNLOCK VERTEXDATA
endif
if exploded=0
if spacekey()
exploded=1
gravity#=0.0002
for f=0 to nfm1
c#=sqrt(rnd(256)) `randomly distribute parts over sphere (when expanded far..)
for c=1 to 3
centrevel#(c,f)=0.0006*c#*centrepos#(c,f)
next c
next f
endif
endif
text 0,0,str$(screen fps())
text 0,10,str$(numfaces)
`text 0,20,str$(numverts)
sync
loop
end
function _obj2setstuff()
`greycol=rgb(50,50,50)
LOCK VERTEXDATA FOR LIMB 2,LIMB,1
for f=1 to nfm1
s=3*f-1
for a=1 to 3
v=s+a
set vertexdata diffuse v, greycol `<-- won't work unless light switched on for obj..
`set vertexdata normals v,0.0,-1.0,0.0 `point them down - so only responds to ambient
next a
next f
UNLOCK VERTEXDATA
endfunction
function single_pixel_image(imagenum,red,green,blue,alpha)
make memblock temp_memblocknum,16
write memblock dword temp_memblocknum,0,1
write memblock dword temp_memblocknum,4,1
write memblock dword temp_memblocknum,8,32
write memblock dword temp_memblocknum,12,rgba(red,green,blue,alpha)
make image from memblock imagenum,1
delete memblock temp_memblocknum
endfunction
`RGBA function by Aaron Miller
function rgba(r,g,b,a)
c = (a and 0xff) << 24 or ((r and 0xff) << 16) or ((g and 0xff) << 8) or (b and 0xff)
endfunction c
function _make_chequer_image(imgnum)
create bitmap 1,256,256
ink rgb(255,255,255),0
box 0,0,256,256
ink rgb(128,128,128),0
box 0,0,128,128
box 128,128,256,256
get image imgnum,0,0,256,256
delete bitmap 1
set current bitmap 0
ink 0,0
endfunction
I haven't changed the normals yet- they should be spinning too. However, there is a problem in that backfaces should have reversed normals - i probably need to double up my polygons.
This is going to be useful for me because i am using a debris generator in my spaceship game, where simple plain particles spew out from explosions etc. I tried objects, instanced objects and objects with many limbs, and all were hella slow when the number of particles is appreciable. The maths for moving them was fast, but it seems DB is quite slow when you move large numbers of objects or limbs at a time. This should make that stuff much faster hopefully, and i can have a lot more grit and junk flying around in my game!
I should do a comparison with using memblocks to change object vertices on the fly to see what the speed difference is if any, then implement in the game.