Advertisement

Little help with RSN milkshape loader !!

Started by May 15, 2002 01:51 PM
4 comments, last by Fixxxer 22 years, 9 months ago
Hi guys, can anyone please point me to where i can fing the number of frames in the MS3D file ... i''m using RSN loader, how can i find the number of frames in the loaded mode ... (pModel) !!! Please help ...
"If you don''t like something, change it. If you can''t change it, change the way you think about it!""He who asks is a fool for five minutes, but he who does not ask remains a fool forever.""Imagination is more important than knowledge, for knowledge is limited while imagination embraces the entire world."(Einstein)"The normal teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires."(William Arthur Ward)
each model has int m_numJoints. Each Joint has int m_numRotationKeyframes, m_numTranslationKeyframes;

I''ve done a reimplementation of Brett''s method, now looking at cal3d which looks AMAZING.

Still trying to figure an efficient way to do the transformations on the vid card though, as bretts way is VERY cpu limitted. Fine for 1000 poly models, even (1) 10,000 poly model on a 1 ghz+ machine, but surely theres a better way..
[size="1"]
Advertisement
Dear Sir,

Could you please help me out or point me to the right direction, all i need is a very small help in one thing.

simply put i need to replace the Brett''s AdvanceAniomation() function, with a function that could be named AdvanceAnimationByOneFrame() ...

Brett''s AdvanceAnimation() uses time to advance the animation, i truly need a function that advance the animation by a single frame, could you please please help me with that ...

i can use your model loading routine if it''s ok, but i guess helping me with the function is eaiser ...

the function at Brett''s code is :


void Model::advanceAnimation()
{
double time = m_pTimer->getTime();

if ( time > m_totalTime )
{
if ( m_looping )
{
restart();
time = 0;
}
else
time = m_totalTime;
}

for ( int i = 0; i < m_numJoints; i++ )
{
float transVec[3];
Matrix transform;
int frame;
Joint *pJoint = &m_pJoints;

if ( pJoint->m_numRotationKeyframes == 0 && pJoint->m_numTranslationKeyframes == 0 )
{
pJoint->m_final.set( pJoint->m_absolute.getMatrix());
continue;
}

frame = pJoint->m_currentTranslationKeyframe;
while ( frame < pJoint->m_numTranslationKeyframes && pJoint->m_pTranslationKeyframes[frame].m_time < time )
{
frame++;
}
pJoint->m_currentTranslationKeyframe = frame;

if ( frame == 0 )
memcpy( transVec, pJoint->m_pTranslationKeyframes[0].m_parameter, sizeof ( float )*3 );
else if ( frame == pJoint->m_numTranslationKeyframes )
memcpy( transVec, pJoint->m_pTranslationKeyframes[frame-1].m_parameter, sizeof ( float )*3 );
else
{
assert( frame > 0 && frame < pJoint->m_numTranslationKeyframes );

const Model::Keyframe& curFrame = pJoint->m_pTranslationKeyframes[frame];
const Model::Keyframe& prevFrame = pJoint->m_pTranslationKeyframes[frame-1];

float timeDelta = curFrame.m_time-prevFrame.m_time;
float interpValue = ( float )(( time-prevFrame.m_time )/timeDelta );

transVec[0] = prevFrame.m_parameter[0]+( curFrame.m_parameter[0]-prevFrame.m_parameter[0] )*interpValue;
transVec[1] = prevFrame.m_parameter[1]+( curFrame.m_parameter[1]-prevFrame.m_parameter[1] )*interpValue;
transVec[2] = prevFrame.m_parameter[2]+( curFrame.m_parameter[2]-prevFrame.m_parameter[2] )*interpValue;
}

frame = pJoint->m_currentRotationKeyframe;
while ( frame < pJoint->m_numRotationKeyframes && pJoint->m_pRotationKeyframes[frame].m_time < time )
{
frame++;
}
pJoint->m_currentRotationKeyframe = frame;

if ( frame == 0 )
transform.setRotationRadians( pJoint->m_pRotationKeyframes[0].m_parameter );
else if ( frame == pJoint->m_numRotationKeyframes )
transform.setRotationRadians( pJoint->m_pRotationKeyframes[frame-1].m_parameter );
else
{
assert( frame > 0 && frame < pJoint->m_numRotationKeyframes );

const Model::Keyframe& curFrame = pJoint->m_pRotationKeyframes[frame];
const Model::Keyframe& prevFrame = pJoint->m_pRotationKeyframes[frame-1];

float timeDelta = curFrame.m_time-prevFrame.m_time;
float interpValue = ( float )(( time-prevFrame.m_time )/timeDelta );

assert( interpValue >= 0 && interpValue <= 1 );

#if 0
Quaternion qPrev( prevFrame.m_parameter );
Quaternion qCur( curFrame.m_parameter );
Quaternion qFinal( qPrev, qCur, interpValue );
transform.setRotationQuaternion( qFinal );
#else
float rotVec[3];

rotVec[0] = prevFrame.m_parameter[0]+( curFrame.m_parameter[0]-prevFrame.m_parameter[0] )*interpValue;
rotVec[1] = prevFrame.m_parameter[1]+( curFrame.m_parameter[1]-prevFrame.m_parameter[1] )*interpValue;
rotVec[2] = prevFrame.m_parameter[2]+( curFrame.m_parameter[2]-prevFrame.m_parameter[2] )*interpValue;

transform.setRotationRadians( rotVec );
#endif
}

transform.setTranslation( transVec );
Matrix relativeFinal( pJoint->m_relative );
relativeFinal.postMultiply( transform );

if ( pJoint->m_parent == -1 )
pJoint->m_final.set( relativeFinal.getMatrix());
else
{
pJoint->m_final.set( m_pJoints[pJoint->m_parent].m_final.getMatrix());
pJoint->m_final.postMultiply( relativeFinal );
}
}
}


"If you don''''t like something, change it. If you can''''t change it, change the way you think about it!"

"He who asks is a fool for five minutes, but he who does not ask remains a fool forever."

"Imagination is more important than knowledge, for knowledge is limited while imagination embraces the entire world."(Einstein)

"The normal teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires."(William Arthur Ward)

"If you don''t like something, change it. If you can''t change it, change the way you think about it!""He who asks is a fool for five minutes, but he who does not ask remains a fool forever.""Imagination is more important than knowledge, for knowledge is limited while imagination embraces the entire world."(Einstein)"The normal teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires."(William Arthur Ward)
Hi,

OK, I'm assuming you want all the features of the AdvanceAnimation func? eg it does all the relevant transformations on the skeleton. The function also does timing (works out which frame is current) which you won't be able to do in the same way if you want to control which frame its on.

Well, the bit of brett's code that decides on the current frame is this:

"
while ( frame < pJoint->m_numTranslationKeyframes && pJoint->m_pTranslationKeyframes[frame].m_time < time ) {
frame++;
}
"

and its done again further down just before doing the rotations.

To make it just advance one frame all you do is advance the current frame counter ONCE, BEFORE doing any transformations. eg just do frame++ (no while loop). Other than that your AdvanceOneFrame will be the same as AdvanceAnimation.

(edit: this assumes the frame variable is created and initialised outside the function - eg its a class member or something.

BTW, you probably know this but... if you aren't using brett's timing (deciding which frame is current) code then you'll probably need your own if you want the animation to run at the same speed on different systems. If this isn't a problem for you then don't worry.

Just in case you missed it (I don't know how experienced you are, sorry) one of the coolest things about bretts code is that that key frames are interpolated, meaning you are very rarely on a specific frame, more likely you are at an interpolated point between 2 frames. Depending on your timing code you may miss this feature.


Hope this helps, feel free to ask again if you want to know more or i didn't explain too well ;¬)

Dan


[edited by - mrbastard on May 18, 2002 9:53:50 AM]
[size="1"]
Thanks alot for your help, i did read your post, and i did implement it, i have done that before, but i have done it again to be more sure; it's not working

your explaination is prefect and full of logic, it was exactly how i thought things go, but implenting the (Manual Addition of frames by a global Variable) gave unexpected results ... here is what i did :


frame = m_current_frame;
if (frame < pJoint->m_numRotationKeyframes)
inc_m_current_frame();
else
reset_m_current_frame();

pJoint->m_currentRotationKeyframe = frame;


Current_frame is a global Variable, which holds the current frame number, the function is called by pressing space, and so it's fully controled ...

i have added the same thing for the translation -just like the previous rotation code- ...

the result is that it pics a random frame from my squance of 40 frames and everytime i click space the model is animated to a frame, then another (space) advances it, another (space) advance it, and then it starts the animation from the start ...

so rather than having 40 animations, i have 5 animations that are non sequant that keeps repeating ... for example: frame 5, frame 18, frame 25, frame 38, then they repeat again ...

i think the problem is with the interpolation code ! ... because it still uses the (time) variable somewhere ...



what i need is to fully remove any code that deals with the time !!! including the interpolation ...

i need help badly ... thanks a lot ... and trust me, the code of the global frame is working perfect, and the code that increaments the frame is working perfectly ...

here is my new code ...

void Model::advanceAnimationOneStep()
{
double time = m_pTimer->getTime();

if ( time > m_totalTime )
{
if ( m_looping )
{
restart();
time = 0;
}
else
time = m_totalTime;
}

for ( int i = 0; i < m_numJoints; i++ )
{
float transVec[3];
Matrix transform;
int frame;
Joint *pJoint = &m_pJoints;

if ( pJoint->m_numRotationKeyframes == 0 && pJoint->m_numTranslationKeyframes == 0 )
{
pJoint->m_final.set( pJoint->m_absolute.getMatrix());
continue;
}

//frame = pJoint->m_currentTranslationKeyframe;
//while ( frame < pJoint->m_numTranslationKeyframes && pJoint->m_pTranslationKeyframes[frame].m_time < time )
//{
//frame++;
//}
//pJoint->m_currentTranslationKeyframe = frame;

frame = m_current_frame;
if (frame < pJoint->m_numTranslationKeyframes)
inc_m_current_frame();
else
reset_m_current_frame();

pJoint->m_currentTranslationKeyframe = frame;

if ( frame == 0 )
memcpy( transVec, pJoint->m_pTranslationKeyframes[0].m_parameter, sizeof ( float )*3 );
else if ( frame == pJoint->m_numTranslationKeyframes )
memcpy( transVec, pJoint->m_pTranslationKeyframes[frame-1].m_parameter, sizeof ( float )*3 );
else
{
assert( frame > 0 && frame < pJoint->m_numTranslationKeyframes );

const Model::Keyframe& curFrame = pJoint->m_pTranslationKeyframes[frame];
const Model::Keyframe& prevFrame = pJoint->m_pTranslationKeyframes[frame-1];

float timeDelta = curFrame.m_time-prevFrame.m_time;
float interpValue = ( float )(( time-prevFrame.m_time )/timeDelta );

transVec[0] = prevFrame.m_parameter[0]+( curFrame.m_parameter[0]-prevFrame.m_parameter[0] )*interpValue;
transVec[1] = prevFrame.m_parameter[1]+( curFrame.m_parameter[1]-prevFrame.m_parameter[1] )*interpValue;
transVec[2] = prevFrame.m_parameter[2]+( curFrame.m_parameter[2]-prevFrame.m_parameter[2] )*interpValue;
}

//frame = pJoint->m_currentRotationKeyframe;
//while ( frame < pJoint->m_numRotationKeyframes && pJoint->m_pRotationKeyframes[frame].m_time < time )
//{
//frame++;
//}
//pJoint->m_currentRotationKeyframe = frame;

frame = m_current_frame;
if (frame < pJoint->m_numRotationKeyframes)
inc_m_current_frame();
else
reset_m_current_frame();

pJoint->m_currentRotationKeyframe = frame;

if ( frame == 0 )
transform.setRotationRadians( pJoint->m_pRotationKeyframes[0].m_parameter );
else if ( frame == pJoint->m_numRotationKeyframes )
transform.setRotationRadians( pJoint->m_pRotationKeyframes[frame-1].m_parameter );
else
{
assert( frame > 0 && frame < pJoint->m_numRotationKeyframes );

const Model::Keyframe& curFrame = pJoint->m_pRotationKeyframes[frame];
const Model::Keyframe& prevFrame = pJoint->m_pRotationKeyframes[frame-1];

float timeDelta = curFrame.m_time-prevFrame.m_time;
float interpValue = ( float )(( time-prevFrame.m_time )/timeDelta );

assert( interpValue >= 0 && interpValue <= 1 );

#if 0
Quaternion qPrev( prevFrame.m_parameter );
Quaternion qCur( curFrame.m_parameter );
Quaternion qFinal( qPrev, qCur, interpValue );
transform.setRotationQuaternion( qFinal );
#else
float rotVec[3];

rotVec[0] = prevFrame.m_parameter[0]+( curFrame.m_parameter[0]-prevFrame.m_parameter[0] )*interpValue;
rotVec[1] = prevFrame.m_parameter[1]+( curFrame.m_parameter[1]-prevFrame.m_parameter[1] )*interpValue;
rotVec[2] = prevFrame.m_parameter[2]+( curFrame.m_parameter[2]-prevFrame.m_parameter[2] )*interpValue;

transform.setRotationRadians( rotVec );
#endif
}

transform.setTranslation( transVec );
Matrix relativeFinal( pJoint->m_relative );
relativeFinal.postMultiply( transform );

if ( pJoint->m_parent == -1 )
pJoint->m_final.set( relativeFinal.getMatrix());
else
{
pJoint->m_final.set( m_pJoints[pJoint->m_parent].m_final.getMatrix());
pJoint->m_final.postMultiply( relativeFinal );
}
}
}

[edited by - fixxxer on May 18, 2002 12:03:29 PM]


[edited by - fixxxer on May 18, 2002 12:07:15 PM]

"If you don''t like something, change it. If you can''t change it, change the way you think about it!""He who asks is a fool for five minutes, but he who does not ask remains a fool forever.""Imagination is more important than knowledge, for knowledge is limited while imagination embraces the entire world."(Einstein)"The normal teacher tells. The good teacher explains. The superior teacher demonstrates. The great teacher inspires."(William Arthur Ward)
Aha, sorry! You''re absolutely right.

The function still uses the time and previous and current keyframe to calculate the displayed frame. It should be a fairly simple job to just chop out the bits referring to prevFrame and interpValue if you read and understand the code. In effect it makes the code much simpler.

Find the bits of code for translation and rotation which use the current and previous frame and the interpolation value to decide on the final values. Change them so the final value used is actually just the value from the current frame.

Dan
[size="1"]

This topic is closed to new replies.

Advertisement