I've been doing some experimenting with limb/frame animations and the results thus far are really good!
I got the idea for this system here:
http://forum.thegamecreators.com/?m=forum_view&t=189929&b=1
Baically what I;m doing is looping through each frame, grabbing the object's mesh and then later applying each of the grabbed meshes to a null object as limbs, giving the object a set of limbs that represent the frames of an animation. Then by simply turning limbs off and on again we can get the effect of animation.
Here's the code, using the same model as before:
sync on : sync rate 0 : sync
autocam off
//Variables
Global MaxLimbs as integer
Global MaxObjects as integer
Global SF as integer
Global EF as integer
Global MaxFrames as integer
//Load the object
obj=1
load object "mobzombie1.x",obj
//Double check that object 1 is at 0,0,0
position object obj,0,0,0
//As all the objects are the same they have the same amount of limbs
perform checklist for object limbs obj
MaxLimbs =checklist quantity()-1
SF =2527
EF =2545
MaxFrames =EF-SF
MaxObjects =4
//Make the AnimationArray
Type GXYZType
x as float
y as float
z as float
EndType
Type AnimationArrayType
Object as integer
Playing as boolean
Looping as boolean
CurrentFrame as integer
StartFrame as integer
EndFrame as integer
NumberOfLimbs as integer
Position as GXYZType
Rotation as GXYZType
Mesh as integer
EndType
Global Dim AnimationArray(MaxObjects,MaxLimbs,MaxFrames) as AnimationArrayType
//Vertex array
// Global Dim VertexArray(MaxLimbs,5000,MaxFrames) as GXYZType
//Store general data in objectID,0,0
AnimationArray(obj,0,0).NumberOfLimbs=MaxLimbs
AnimationArray(obj,0,0).Object=obj
position camera 0,50,-150
point camera 0,0,0
// if file exist("OUTPUT.txt")=1 then delete file "OUTPUT.txt"
// open to write 1,"OUTPUT.txt"
// write string 1,"These are the positions and rotations of each limb for each animation frame:"
for t=0 to MaxFrames
//Set the frame
set object frame obj,t+SF
//Update animation
sync
//Record the data
// write string 1," "
// write string 1,"FRAME NUMBER: "+str$(t)
// for lmb=0 to MaxLimbs
//LIMB METHOD
// AnimationArray(obj,lmb,t).Position.x =limb position x(obj,lmb)
// AnimationArray(obj,lmb,t).Position.y =limb position y(obj,lmb)
// AnimationArray(obj,lmb,t).Position.z =limb position z(obj,lmb)
// AnimationArray(obj,lmb,t).rotation.x =limb direction x(obj,lmb)
// AnimationArray(obj,lmb,t).rotation.y =limb direction y(obj,lmb)
// AnimationArray(obj,lmb,t).rotation.z =limb direction z(obj,lmb)
// write string 1,"Limb "+str$(lmb)+" POS: "+str$(AnimationArray(obj,lmb,t).Position.x)+","+str$(AnimationArray(obj,lmb,t).Position.y)+","+str$(AnimationArray(obj,lmb,t).Position.z)+" ROT:"+str$(AnimationArray(obj,lmb,t).rotation.x)+","+str$(AnimationArray(obj,lmb,t).rotation.y)+","+str$(AnimationArray(obj,lmb,t).rotation.z)
//VERTEX METHOD
// write string 1," Vertex data for limb: "+str$(lmb)
// lock vertexdata for limb obj,lmb,1
// for v=0 to get vertexdata vertex count()-1
// px# =get vertexdata position x(v)
// py# =get vertexdata position y(v)
// pz# =get vertexdata position z(v)
// write string 1," Vertex "+str$(v)+" POS: "+str$(px#)+","+str$(py#)+","+str$(pz#)
// VertexArray(lmb,v,t).x =px#
// VertexArray(lmb,v,t).y =py#
// VertexArray(lmb,v,t).z =pz#
// next v
// unlock vertexdata
// next lmb
//MESH-LIMB METHOD
make mesh from object t+1,obj
AnimationArray(obj,0,t).Mesh =t+1
//Wait so we can see what's going on
`wait 25
next t
// close file 1
//MESH-LIMB METHOD - CONTINUED
//Delete base object
delete object obj
//Load texture pre-loop
load image "mobzombie1_D.dds",1
for o=0 to MaxObjects-1
//Load null object
make object cube obj+o,0
//Add meshes as limbs to null object
for t=0 to MaxFrames
//Add limb
add limb obj+o,t+1,AnimationArray(obj,0,t).Mesh
hide limb obj+o,t+1
next t
texture object obj+o,1
position object obj+o,(-0.5*MaxObjects*30)+o*30,0,0
next o
//Delete unneeded meshes to free resources
for t=0 to MaxFrames
delete mesh AnimationArray(obj,0,t).Mesh
next t
//Position the camera
position camera 0,150,-150
point camera 0,-50,0
//Set the initial frame
`FRAME=sf-1
//Loop the objects
for t=1 to MaxObjects
AnimateObjectLoop(t,1,MaxFrames)
next t
do
//ANIMATION
AnimateObjects()
`AnimateObjectSetFrame(1,FRAME_NUMBER)
if spacekey()=1
for o=1 to MaxObjects
AnimationArray(o,0,0).Playing=0
next o
else
for o=1 to MaxObjects
AnimationArray(o,0,0).Playing=1
next o
endif
//Control object frame for setframe
if rightkey()=1 and KEY=0
KEY=1
inc FRAME_NUMBER,1
if FRAME_NUMBER>MaxFrames then FRAME_NUMBER=1
endif
if leftkey()=1 and KEY=0
KEY=1
dec FRAME_NUMBER,1
if FRAME_NUMBER<1 then FRAME_NUMBER=MaxFrames
endif
if leftkey()=0 and rightkey()=0 then KEY=0
//CAMERA
control camera using arrowkeys 0,5,5
//PRINT TO SCREEN
set cursor 0,0
print "FPS: ",screen fps()
print "Ploygons: ",statistic(1)
print "Frame: ",AnimationArray(1,0,0).CurrentFrame
// lmb=1 : v=1
// print str$(VertexArray(lmb,v,AnimationArray(t,0,0).CurrentFrame).x)+","+str$(VertexArray(lmb,v,AnimationArray(t,0,0).CurrentFrame).y)+","+str$(VertexArray(lmb,v,AnimationArray(t,0,0).CurrentFrame).z)
//SYNC
sync
//WAIT - DEBUG PURPOSES
`wait 500
loop
end
function AnimateObjectLoop(AnimID as integer, StartFrame as integer, EndFrame as integer)
AnimationArray(AnimID,0,0).StartFrame=StartFrame
AnimationArray(AnimID,0,0).EndFrame=EndFrame
AnimationArray(AnimID,0,0).CurrentFrame=StartFrame
AnimationArray(AnimID,0,0).Looping=1
AnimationArray(AnimID,0,0).Playing=1
endfunction
function AnimateObjectSetFrame(AnimID as integer, Frame as integer)
if limb exist(AnimationArray(AnimID,0,0).Object,Frame)
//MESH-LIMB METHOD
//Hide current limb
hide limb AnimationArray(AnimID,0,0).Object,AnimationArray(AnimID,0,0).CurrentFrame
//Show next limb
show limb AnimationArray(AnimID,0,0).Object,Frame
//Set the current frame
AnimationArray(AnimID,0,0).CurrentFrame =Frame
endif
endfunction
function AnimateObjects()
//Loop through objects
for t=1 to MaxObjects
//Check to see if it's playing
if AnimationArray(t,0,0).Playing=1
//Loop through limbs
// for lmb=0 to AnimationArray(t,0,0).NumberOfLimbs
//LIMB METHOD
//Position limb
// px# =AnimationArray(t,lmb,AnimationArray(t,0,0).CurrentFrame).Position.x
// py# =AnimationArray(t,lmb,AnimationArray(t,0,0).CurrentFrame).Position.y
// pz# =AnimationArray(t,lmb,AnimationArray(t,0,0).CurrentFrame).Position.z
// offset limb AnimationArray(t,0,0).Object,lmb,px#,py#,pz#
// //rotate limb
// rx# =AnimationArray(t,lmb,AnimationArray(t,0,0).CurrentFrame).Rotation.x
// ry# =AnimationArray(t,lmb,AnimationArray(t,0,0).CurrentFrame).Rotation.y
// rz# =AnimationArray(t,lmb,AnimationArray(t,0,0).CurrentFrame).Rotation.z
// rotate limb AnimationArray(t,0,0).Object,lmb,rx#,ry#,rz#
//VERTEX METHOD
//Lock the vertexdata for the limb and update the position
// lock vertexdata for limb t,lmb,1
// for v=0 to get vertexdata vertex count()-1
// set vertexdata position v,VertexArray(lmb,v,AnimationArray(t,0,0).CurrentFrame).x,VertexArray(lmb,v,AnimationArray(t,0,0).CurrentFrame).y,VertexArray(lmb,v,AnimationArray(t,0,0).CurrentFrame).z
// next v
// unlock vertexdata
// next lmb
// //For Vertex and limb methods
// //Increment the frame number
// inc AnimationArray(t,0,0).CurrentFrame,1
// //Check for end of animation
// if AnimationArray(t,0,0).CurrentFrame>AnimationArray(t,0,0).EndFrame
// if AnimationArray(t,0,0).Looping=1
// AnimationArray(t,0,0).CurrentFrame=AnimationArray(t,0,0).StartFrame
// else
// AnimationArray(t,0,0).Playing=0
// endif
// endif
//MESH-LIMB METHOD
//Hide current limb
hide limb t,AnimationArray(t,0,0).CurrentFrame
//Increment the frame number
inc AnimationArray(t,0,0).CurrentFrame,1
//Show next limb
if AnimationArray(t,0,0).CurrentFrame<=AnimationArray(t,0,0).EndFrame
show limb t,AnimationArray(t,0,0).CurrentFrame
endif
//Check for end of animation
if AnimationArray(t,0,0).CurrentFrame>AnimationArray(t,0,0).EndFrame
if AnimationArray(t,0,0).Looping=1
AnimationArray(t,0,0).CurrentFrame=AnimationArray(t,0,0).StartFrame
show limb t,AnimationArray(t,0,0).CurrentFrame
else
AnimationArray(t,0,0).Playing=0
endif
endif
endif
next t
Endfunction
`jump = 190,209
`idle = 210,234
`walk = 235,259
`strafeleft = 260,279
`straferight = 280,299
`run = 300,318
`trowgrenade = 319,355
`treadwater = 160,189
`jumpdiefowards = 3245,3300
`getup = 523,552
`diefowards = 40,59
`diebackwards = 60,79
`diebackright = 120,139
`diefall = 140,159
`diebackleft = 80,99
`diefall = 100,119
`idlecrouch = 356,380
`crouchwalk = 381,405
`crouchthrowgrenade = 406,442
`idleswim = 443,462
`treadwater = 463,492
`jumplandpreparefire = 553,572
`idlepistol = 573,597
`walkpistol = 598,622
`strafeleftpistol = 623,642
`straferightpistol = 643,662
`runpistol = 663,681
`reloadpistol = 682,731
`treadwater = 160,189
`diebackwards = 0,19
`deadfall = 20,39
`getupwithrifle = 882,911
`diefowards = 40,59
`diewater = 60,79
`getupshotgun = 912,941
`crouchpistol = 732,756
`crouchwalkpistol = 757,781
`waterpistol = 832,851
`swimpistol = 852,881
`run+ = 2501,2519
`run++ = 2527,2545
`idle+ = 2553,2602
`idle+2 = 2609,2658
`idle+3 = 2665,2714
`idle+4 = 2721,2770
`attackconsecutivearms = 2776,2848
`attackleftarm = 2861,2904
`attacktwoarmsright = 2916,2969
`attacktwoarmsleft = 2981,3034
`roar = 3046,3094
`hurthead = 3104,3154
`diebackwardsragdoll = 3165,3235
`diefowardsragdoll = 3245,3300
`diebackwardsragdoll2 = 3310,3370
`diebackwardsragdollslow = 3380,3440
I haven't cleaned it up or anything, that's just as it is including all my previous attempts, it's dirty but it works. There are some upsides and some downsides to this method:
The upsides:
*Super fast animation
*Easy custom animations
The downsides:
*No bone collision
*No limb detection
*(I suspect) large file size
When I say it's super fast, I mean with the 4 object example I get a non-animating FPS of 60 (on my slower machine) and an animating FPS of 59, that's a 1FPS drop to animate 4 objects frame-number independent, that makes it way quicker than the standard commands. However, there is no limb collision detection as each frame is a limb of the object and there is no bone collision either as the bones aren't really being animated. Also, I haven't checked it out yet but I think that the file size and memory usage might be quite high too?
Any thoughts or improvements? What FPS do you guys get when animating and not animating?
Thanks,
BC