History: Sample code
Source of version: 2 (current)
Copy to clipboard
Here is some sample code demonstrating how to read the anim XML file exported by the ((Maya Animation Exporter)) plug-in:
{CODE(wrap="1", colors="c++")}
AnimationState* AnimationManager::createAnimationFromFile(const string& animationName,const string& filename,const string& trackName)
{
// Get resource dirs
DataStreamPtr stream = ResourceGroupManager::getSingleton().openResource(filename.c_str());
if (stream.isNull())
return NULL;
// Parse xml file
TiXmlDocument doc;
doc.Parse(stream.get()->getAsString().c_str());
TiXmlElement* xmlAnim=doc.FirstChildElement("anim");
if (xmlAnim==NULL) // cant find any animation track in this file
return NULL;
while (xmlAnim->Attribute("id")==NULL || trackName!=xmlAnim->Attribute("id") )
{
xmlAnim=xmlAnim->NextSiblingElement("anim");
if (xmlAnim==NULL) //can't find animtion track named trackName
return NULL;
}
//get type end max time of nodes
double animationLength=0;
double nodeLength=0;
string type;
TiXmlElement* xmlNode=xmlAnim->FirstChildElement("node");
if (xmlNode==NULL)
return NULL;
TiXmlElement* frame;
while (xmlNode!=NULL) {
type=xmlNode->Attribute("type");
frame=xmlNode->LastChild("keyframe")->ToElement();
if (frame==NULL || frame->Attribute("time",&nodeLength)==NULL) // no time attribute on this frame
return NULL;
if (animationLength<nodeLength)
animationLength=nodeLength;
if (xmlNode->NextSibling("node"))
xmlNode=xmlNode->NextSibling("node")->ToElement();
else
xmlNode=NULL;
}
Ogre::Animation* anim = m_sceneManager->createAnimation(animationName , animationLength);
if (type=="spline")
anim->setInterpolationMode(Ogre::Animation::IM_SPLINE);
else
anim->setInterpolationMode(Ogre::Animation::IM_LINEAR);
// parse nodes
Ogre::SceneNode* node;
Ogre::SceneNode* pivotNode=m_sceneManager->getRootSceneNode()->createChildSceneNode("TmpPivotNode");
Ogre::SceneNode* tmpNode=pivotNode->createChildSceneNode();
xmlNode=xmlAnim->FirstChildElement("node");
int trackNum=0;
while (xmlNode!=NULL)
{
string nodeName=xmlNode->Attribute("name");
if (m_sceneManager->hasSceneNode(nodeName))
{
node=m_sceneManager->getSceneNode(nodeName);
Ogre::Vector3 pivot=Ogre::Vector3::ZERO;
double number;
if (xmlNode->Attribute("pivotx",&number))
pivot.x=number;
if (xmlNode->Attribute("pivoty",&number))
pivot.y=number;
if (xmlNode->Attribute("pivotz",&number))
pivot.z=number;
int numOfFrames;
if (xmlNode->Attribute("numKeys",&numOfFrames)!=NULL && numOfFrames!=0) // no frames in the curent animation track
{
Ogre::NodeAnimationTrack* track = anim->createNodeTrack(trackNum++, node);
Ogre::TransformKeyFrame* kf;
frame=xmlNode->FirstChildElement("keyframe")->ToElement();
double time;
while (frame!=NULL)
{
if (frame->Attribute("time",&time)!=NULL)
{
// building the animation track
Ogre::Vector3 translation=Ogre::Vector3::ZERO;
Ogre::Vector3 rotation=Ogre::Vector3::ZERO;
if (frame->Attribute("x",&number))
translation.x=number;
if (frame->Attribute("y",&number))
translation.y=number;
if (frame->Attribute("z",&number))
translation.z=number;
if (frame->Attribute("rx",&number))
rotation.x=number;
if (frame->Attribute("ry",&number))
rotation.y=number;
if (frame->Attribute("rz",&number))
rotation.z=number;
// calculate transformation using pivot
pivotNode->resetToInitialState();
tmpNode->resetToInitialState();
pivotNode->setPosition(translation);
tmpNode->setPosition(-pivot);
pivotNode->roll(Ogre::Radian(rotation[2]));
pivotNode->yaw(Ogre::Radian(rotation[1]));
pivotNode->pitch(Ogre::Radian(rotation[0]));
pivotNode->translate(pivot);
tmpNode->needUpdate();
// set the transformation in the keyframe
kf=track->createNodeKeyFrame(time);
kf->setRotation(tmpNode->getWorldOrientation());
kf->setTranslate(tmpNode->getWorldPosition());
}
frame=frame->NextSiblingElement("keyframe");
}
}
}
if (xmlNode->NextSibling("node"))
xmlNode=xmlNode->NextSibling("node")->ToElement();
else
xmlNode=NULL;
}
m_sceneManager->getRootSceneNode()->removeAndDestroyChild("TmpPivotNode");
Ogre::AnimationState* animState = m_sceneManager->createAnimationState(animationName);
if (animState==NULL) //unknown error
{
m_sceneManager->destroyAnimation(animationName);
return NULL;
}
return animState;
}
{CODE}