MS3D code and Advanced Animation

Started by
122 comments, last by JudgeX 22 years, 1 month ago
Now that the problems with the normal animation have been taken care of, I''ve started looking into handling an actual usable form of animations. However, I need some input and some help before I begin a full implementation. The first option I came up with was to fill a model with about 300 frames using different imported SMD files from half-life (and creating my own using the 3dsMAX SMD exporter). Of course, then, I''d need a way to use Bret''s awesome code to play the animation from frame x to frame y on command, which seems really difficult (I don''t think there''s an easy way to throw in a couple of paramaters on the existing functions or anything, it looks like almost a whole rework of the animation portion of the loading code). My second idea was to forego having frames whatsoever in the milkshape file, and manually importing the SMD files by adding in an importer. Don''t laugh too hard yet, try opening an SMD file, they''re simple text, a list of bones and coordinates at each frame... that''s it. This seems like it would be fairly easy to do, and it would be more versatile, as the models would be far smaller, and many models could share many animations. I really can''t figure out which of these two ideas would be most difficult to implement, and I''m looking for a lot of help here. Honestly, I see advantages to both of them, the first one seems slightly easier to implement(though I have no clue how at the moment and would REALLY appreciate input) and the second seems more difficult to implement, but with larger payoff, since you could dynamically load the animations and put the models through them. Any input will be greatly appreciated. Thanks, JudgeX
Advertisement
Hi,

The latest version of PortaLib started to introduce support for multiple animations. I''ve asked Mete if he''ll hadd this feature to MS3D but haven''t heard back.

You could make 2 modifications to the system to get it to do what you want: 1 is to load multiple MS3D files into one Object3D and store the animations. Only load the model vertices once. This would work well with SMDs since when MS3D decompiles it it builds one model MS3D file and a bunch of animation files.

The other way is to modify the one animation after loading, splitting it into several based on keyframes.

The support is weak for now (no way to select which one yet - but easy to do). I am planning on doing an MD3 loader and implementing it at the same time. What do you think?

Now that I''m not bug hunting, feature requests sound good

~~~
Cheers!
Brett Porter
PortaLib3D : A portable 3D game/demo libary for OpenGL
~~~Cheers!Brett PorterPortaLib3D : A portable 3D game/demo libary for OpenGLCommunity Service Announcement: Read How to ask questions the smart way before posting!
I like the idea of an md3 loader, myself, but I actually think the ms3d loader being modified to take in the smd keyframe information directly from smd''s would be the most versatile and useful thing ever. At the beginning of the program, you could just load up all your SMD keyframes, and then apply them to the skeletons whenever. This seems really nice to me, and I''m not sure how md3''s work.


Okay, how would I split the long animation into keyframes? I have a couple models that have 190 frames that load fine, but I need to play say, frame 32 to frame 70 to show the model do a running longjump.

I''m also interested in the other method... what is an Object3D? How could I implement loading the smd animations into a model straight from the smd file? I''m pretty good at file I/O, so, I think I could handle getting the data, but, I don''t know how to work it in conjunction with the timing, or exactly where to put the movement info for each joint (or if I have to do anything with normals, and so on).

Any input at all would be helpful

Thanks,
JudgeX
Hi again!

Object3D is in PortaLib3D. It''s another abstraction to allow better handling of models with shadows and animation.

You can probably load an SMD into that to create the appropriate animation. If you can find a detailed file format for SMD I''ll put together a loader - how does that sound? Other than that I''ll do MD3 because it is more recent and I think does the same and more.

Splitting a long animation would involve pulling chunks out of the existing set of keyframe data and splitting the array.

HTH...

~~~
Cheers!
Brett Porter
PortaLib3D : A portable 3D game/demo libary for OpenGL
~~~Cheers!Brett PorterPortaLib3D : A portable 3D game/demo libary for OpenGLCommunity Service Announcement: Read How to ask questions the smart way before posting!
hehe, I think I could almost do a detailed description of the SMD format myself .

Here goes...

It starts with version number, like this (literally like this):

version 1

then, lists the nodes (like this - when I say that, I''m taking it right from the file):

nodes
0 "Bip01" -1
1 "Bip01 Footsteps" 0
2 "Bip01 Pelvis" 0
3 "Bip01 L Leg" 2
4 "Bip01 L Leg1" 3
5 "Bip01 L Foot" 4
6 "Bip01 L Toe0" 5
7 "Bip01 L Toe01" 6
8 "Bip01 L Toe02" 7
9 "Dummy16" 8
10 "Bip01 R Leg" 2
11 "Bip01 R Leg1" 10
12 "Bip01 R Foot" 11
13 "Bip01 R Toe0" 12
14 "Bip01 R Toe01" 13
15 "Bip01 R Toe02" 14


--- And it goes on through the rest of them... I don''t know exactly how to use number is beside each of those, as it always indicates the bone before it in the hierarchy.

After all those it has an "end" and "skeleton" as shown:

end
skeleton

then it goes into the first time, and starts showing the various movements, listed by the number in front of each bone as listed above, followed by 6 numbers. Since I don''t really, truly know how bones work, I''m not sure what these numbers are. I''m pretty sure it''s x, y, z position and orientation. It looks like this:

time 1
0 0.233849 -0.404778 39.769844 0.000000 0.000000 -1.570795
1 -0.000000 -0.000000 -39.769844 0.000000 0.000000 1.570795
2 -0.000000 -0.000000 0.000000 -1.570795 -1.570796 0.000000
3 -0.000005 0.000007 3.713255 -0.015828 3.120255 -0.742554
4 18.045723 0.000000 0.000000 0.000000 0.000000 -0.835961
5 17.597597 0.000001 0.000000 -0.000583 0.026559 0.175834
6 3.793089 6.407222 0.000000 -0.000000 -0.000000 1.570796
7 0.935739 -0.000000 0.000000 0.000000 0.000000 0.000000
8 0.935741 -0.000000 0.000000 0.000000 0.000000 0.000000
9 0.935740 0.000000 0.000000 -0.000000 -0.000000 3.141593
10 0.000005 -0.000003 -3.713255 -0.009092 -3.126596 0.376169
11 18.045721 0.000000 -0.000000 0.000000 -0.000000 -0.799382
12 17.597597 -0.000001 0.000000 0.016928 0.004586 -0.490899
13 3.793090 6.407223 -0.000000 -0.000000 -0.000000 1.570796
14 0.935741 -0.000002 0.000000 0.000000 0.000000 0.000000
15 0.935740 0.000000 -0.000000 0.000000 0.000000 0.000000
16 0.935740 0.000001 -0.000000 0.000000 0.000000 0.000000

and continues to the last bone.

then goes into time 2 immediately

time 2
0 0.233849 -8.729897 39.109177 0.000000 0.000000 -1.570795
1 0.000000 0.000000 -39.109177 0.000000 0.000000 1.570795
2 0.000000 0.000000 0.000000 -1.570795 -1.570796 0.000000
3 -0.000005 0.000007 3.713255 -0.013781 3.118581 -0.645517
4 18.045723 -0.000002 0.000000 0.000000 -0.000000 -0.635464
5 17.597597 -0.000001 -0.000000 0.001139 0.026796 0.138399
6 3.793089 6.407221 -0.000000 -0.000000 -0.000000 1.570796
7 0.935740 -0.000001 0.000000 0.000000 0.000000 0.000000
8 0.935741 0.000000 0.000000 0.000000 0.000000 0.000000
9 0.935740 0.000000 0.000000 -0.000000 -0.000000 3.141593
10 0.000005 -0.000004 -3.713255 -0.006928 -3.125482 0.237251
11 18.045723 -0.000000 0.000000 -0.000000 0.000000 -1.270162
12 17.597597 0.000000 -0.000000 0.016007 0.007169 -0.315530
13 3.793090 6.407221 -0.000000 -0.000000 0.000000 1.570796

and continues, and so on, and so forth... so, the stuff listed beside "0" is apparently the movement for 3 is apparently the stuff for the biped''s left leg. This pattern continues to the end of the file, where it''s terminated with an end...

end

And that''s the whole format... As far as what those numbers do, the first three are the location of the bone, you can see that clearly because this animation example I''ve given is for walk, in which the half life model walks towards the camera. Notice that Bip01(0)''s Z distance decreases between time 1 and time 2, it continues to do so for the entire file. The next three number *could* be the rotation, ... I''ve noticed that in the file, the right leg''s 6th number fluctuates, perhaps indicating the front to back motion of a walking leg... well, anyway... that''s pretty much the format, and, having written the ms3d loader yourself already, I''m sure you can make more sense of it than I can... I have tons of SMDs if you''d like to work with some, or if you''d like me to send them.

Think that''s enough, and if so, how long will it take you to make an importer?

Thanks,
JudgeX
mrh8red@home.com


quote:Original post by JudgeX

The first option I came up with was to fill a model with about 300 frames using different imported SMD files from half-life (and creating my own using the 3dsMAX SMD exporter). Of course, then, I''d need a way to use Bret''s awesome code to play the animation from frame x to frame y on command, which seems really difficult (I don''t think there''s an easy way to throw in a couple of paramaters on the existing functions or anything, it looks like almost a whole rework of the animation portion of the loading code).

[End Quote]

hi all .. ye old anonomous poster again ;D spose i should register sometime heheh .. anyway..

I alterd the advance Animation function to try to play from
frame x to y
the only changes i made really was to that very first part that checks the time .. cause i figured were interpolating between the frames x / y depending on the timers time..
this "seems" to be working for me .. tell me what you think

oh i added a few variables and m_totalFrames, and m_FPS.. those just get set when your loading in the model ..
(in the load model data function)
// skip currentTime
pPtr += sizeof( float );

int totalFrames = *( int* )pPtr;
pPtr += sizeof( int );

m_totalFrames = totalFrames;// <-- add this..
m_FPS = animFPS; // <-- add this..
m_totalTime = (totalFrames*1000.0)/animFPS;

m_numJoints = *( word* )pPtr;
pPtr += sizeof( word );

(then in the advance animation function)
void Model::advanceAnimation(int startframe, int endframe)
{
double time = m_pTimer->getTime();
double endTime; //<-- added

time +=(((startframe)*1000)/m_FPS); // <-- added

if ((endframe > 0) && (endframe < m_totalFrames))//<-add
endTime = (((endframe)*1000)/m_FPS);//<-add
else //<-add
endTime = m_totalTime;//<-add

if ( time > endTime) //<-altered
{
if ( m_looping )
{
restart();
time = (((startframe)*1000)/m_FPS);//<-altered
}
else
time = endTime; //<-altered

}

tell me what you think .. any suggestions would be greatly appreciatied.. *bows down before brett porters wicked interpolation routeens. damn fine code
Where did you put m_totalFrames and m_FPS''s declarations?

The code looks good and workable, but I dunno where to put the declarations for these... it looks like you reference them both in Model::advanceAnimation and MilkshapeModel:loadModelData, but I can''t seem to find an appropriate place that lets me compile with the current code...

Thanks,
JudgeX
ah, i''ve made a model class inside my engine which i peiced together from the tutorials (this was a big pain hehe took me 3 trys .. when it came to the actual bone animation part with the timers and such .. just took me a bit to figure out how it was all linking together), the vars are just declared in the header file as private doubles.
Excellent, got it... works like a charm. Thank you...

Now I''ve just gotta get it to play once and stop .

JudgeX
*cry .. i thought it was werking too ..
got an assert failure when i played frames 50-59 for some reason =(

i think its just out to get meh =/

any ideas?

This topic is closed to new replies.

Advertisement