vrshoot

annotate libs/assimp/OgreSkeleton.cpp @ 2:334d17aed7de

visual studio project files
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 02 Feb 2014 18:36:38 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 Open Asset Import Library (assimp)
nuclear@0 3 ----------------------------------------------------------------------
nuclear@0 4
nuclear@0 5 Copyright (c) 2006-2012, assimp team
nuclear@0 6 All rights reserved.
nuclear@0 7
nuclear@0 8 Redistribution and use of this software in source and binary forms,
nuclear@0 9 with or without modification, are permitted provided that the
nuclear@0 10 following conditions are met:
nuclear@0 11
nuclear@0 12 * Redistributions of source code must retain the above
nuclear@0 13 copyright notice, this list of conditions and the
nuclear@0 14 following disclaimer.
nuclear@0 15
nuclear@0 16 * Redistributions in binary form must reproduce the above
nuclear@0 17 copyright notice, this list of conditions and the
nuclear@0 18 following disclaimer in the documentation and/or other
nuclear@0 19 materials provided with the distribution.
nuclear@0 20
nuclear@0 21 * Neither the name of the assimp team, nor the names of its
nuclear@0 22 contributors may be used to endorse or promote products
nuclear@0 23 derived from this software without specific prior
nuclear@0 24 written permission of the assimp team.
nuclear@0 25
nuclear@0 26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 37
nuclear@0 38 ----------------------------------------------------------------------
nuclear@0 39 */
nuclear@0 40
nuclear@0 41 #include "AssimpPCH.h"
nuclear@0 42
nuclear@0 43 #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
nuclear@0 44
nuclear@0 45 #include "OgreImporter.hpp"
nuclear@0 46 #include "TinyFormatter.h"
nuclear@0 47
nuclear@0 48 using namespace std;
nuclear@0 49
nuclear@0 50 namespace Assimp
nuclear@0 51 {
nuclear@0 52 namespace Ogre
nuclear@0 53 {
nuclear@0 54
nuclear@0 55
nuclear@0 56
nuclear@0 57 void OgreImporter::LoadSkeleton(std::string FileName, vector<Bone> &Bones, vector<Animation> &Animations) const
nuclear@0 58 {
nuclear@0 59 const aiScene* const m_CurrentScene=this->m_CurrentScene;//make sure, that we can access but not change the scene
nuclear@0 60 (void)m_CurrentScene;
nuclear@0 61
nuclear@0 62
nuclear@0 63 //most likely the skeleton file will only end with .skeleton
nuclear@0 64 //But this is a xml reader, so we need: .skeleton.xml
nuclear@0 65 FileName+=".xml";
nuclear@0 66
nuclear@0 67 DefaultLogger::get()->debug(string("Loading Skeleton: ")+FileName);
nuclear@0 68
nuclear@0 69 //Open the File:
nuclear@0 70 boost::scoped_ptr<IOStream> File(m_CurrentIOHandler->Open(FileName));
nuclear@0 71 if(NULL==File.get())
nuclear@0 72 throw DeadlyImportError("Failed to open skeleton file "+FileName+".");
nuclear@0 73
nuclear@0 74 //Read the Mesh File:
nuclear@0 75 boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(File.get()));
nuclear@0 76 XmlReader* SkeletonFile = irr::io::createIrrXMLReader(mIOWrapper.get());
nuclear@0 77 if(!SkeletonFile)
nuclear@0 78 throw DeadlyImportError(string("Failed to create XML Reader for ")+FileName);
nuclear@0 79
nuclear@0 80 XmlRead(SkeletonFile);
nuclear@0 81 if(string("skeleton")!=SkeletonFile->getNodeName())
nuclear@0 82 throw DeadlyImportError("No <skeleton> node in SkeletonFile: "+FileName);
nuclear@0 83
nuclear@0 84
nuclear@0 85
nuclear@0 86 //------------------------------------load bones-----------------------------------------
nuclear@0 87 XmlRead(SkeletonFile);
nuclear@0 88 if(string("bones")!=SkeletonFile->getNodeName())
nuclear@0 89 throw DeadlyImportError("No bones node in skeleton "+FileName);
nuclear@0 90
nuclear@0 91 XmlRead(SkeletonFile);
nuclear@0 92
nuclear@0 93 while(string("bone")==SkeletonFile->getNodeName())
nuclear@0 94 {
nuclear@0 95 //TODO: Maybe we can have bone ids for the errrors, but normaly, they should never appear, so what....
nuclear@0 96
nuclear@0 97 //read a new bone:
nuclear@0 98 Bone NewBone;
nuclear@0 99 NewBone.Id=GetAttribute<int>(SkeletonFile, "id");
nuclear@0 100 NewBone.Name=GetAttribute<string>(SkeletonFile, "name");
nuclear@0 101
nuclear@0 102 //load the position:
nuclear@0 103 XmlRead(SkeletonFile);
nuclear@0 104 if(string("position")!=SkeletonFile->getNodeName())
nuclear@0 105 throw DeadlyImportError("Position is not first node in Bone!");
nuclear@0 106 NewBone.Position.x=GetAttribute<float>(SkeletonFile, "x");
nuclear@0 107 NewBone.Position.y=GetAttribute<float>(SkeletonFile, "y");
nuclear@0 108 NewBone.Position.z=GetAttribute<float>(SkeletonFile, "z");
nuclear@0 109
nuclear@0 110 //Rotation:
nuclear@0 111 XmlRead(SkeletonFile);
nuclear@0 112 if(string("rotation")!=SkeletonFile->getNodeName())
nuclear@0 113 throw DeadlyImportError("Rotation is not the second node in Bone!");
nuclear@0 114 NewBone.RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
nuclear@0 115 XmlRead(SkeletonFile);
nuclear@0 116 if(string("axis")!=SkeletonFile->getNodeName())
nuclear@0 117 throw DeadlyImportError("No axis specified for bone rotation!");
nuclear@0 118 NewBone.RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
nuclear@0 119 NewBone.RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
nuclear@0 120 NewBone.RotationAxis.z=GetAttribute<float>(SkeletonFile, "z");
nuclear@0 121
nuclear@0 122 //append the newly loaded bone to the bone list
nuclear@0 123 Bones.push_back(NewBone);
nuclear@0 124
nuclear@0 125 //Proceed to the next bone:
nuclear@0 126 XmlRead(SkeletonFile);
nuclear@0 127 }
nuclear@0 128 //The bones in the file a not neccesarly ordered by there id's so we do it now:
nuclear@0 129 std::sort(Bones.begin(), Bones.end());
nuclear@0 130
nuclear@0 131 //now the id of each bone should be equal to its position in the vector:
nuclear@0 132 //so we do a simple check:
nuclear@0 133 {
nuclear@0 134 bool IdsOk=true;
nuclear@0 135 for(int i=0; i<static_cast<signed int>(Bones.size()); ++i)//i is signed, because all Id's are also signed!
nuclear@0 136 {
nuclear@0 137 if(Bones[i].Id!=i)
nuclear@0 138 IdsOk=false;
nuclear@0 139 }
nuclear@0 140 if(!IdsOk)
nuclear@0 141 throw DeadlyImportError("Bone Ids are not valid!"+FileName);
nuclear@0 142 }
nuclear@0 143 DefaultLogger::get()->debug((Formatter::format(),"Number of bones: ",Bones.size()));
nuclear@0 144 //________________________________________________________________________________
nuclear@0 145
nuclear@0 146
nuclear@0 147
nuclear@0 148
nuclear@0 149
nuclear@0 150
nuclear@0 151 //----------------------------load bonehierarchy--------------------------------
nuclear@0 152 if(string("bonehierarchy")!=SkeletonFile->getNodeName())
nuclear@0 153 throw DeadlyImportError("no bonehierarchy node in "+FileName);
nuclear@0 154
nuclear@0 155 DefaultLogger::get()->debug("loading bonehierarchy...");
nuclear@0 156 XmlRead(SkeletonFile);
nuclear@0 157 while(string("boneparent")==SkeletonFile->getNodeName())
nuclear@0 158 {
nuclear@0 159 string Child, Parent;
nuclear@0 160 Child=GetAttribute<string>(SkeletonFile, "bone");
nuclear@0 161 Parent=GetAttribute<string>(SkeletonFile, "parent");
nuclear@0 162
nuclear@0 163 unsigned int ChildId, ParentId;
nuclear@0 164 ChildId=find(Bones.begin(), Bones.end(), Child)->Id;
nuclear@0 165 ParentId=find(Bones.begin(), Bones.end(), Parent)->Id;
nuclear@0 166
nuclear@0 167 Bones[ChildId].ParentId=ParentId;
nuclear@0 168 Bones[ParentId].Children.push_back(ChildId);
nuclear@0 169
nuclear@0 170 XmlRead(SkeletonFile);
nuclear@0 171 }
nuclear@0 172 //_____________________________________________________________________________
nuclear@0 173
nuclear@0 174
nuclear@0 175 //--------- Calculate the WorldToBoneSpace Matrix recursively for all bones: ------------------
nuclear@0 176 BOOST_FOREACH(Bone &theBone, Bones)
nuclear@0 177 {
nuclear@0 178 if(-1==theBone.ParentId) //the bone is a root bone
nuclear@0 179 {
nuclear@0 180 theBone.CalculateBoneToWorldSpaceMatrix(Bones);
nuclear@0 181 }
nuclear@0 182 }
nuclear@0 183 //_______________________________________________________________________
nuclear@0 184
nuclear@0 185
nuclear@0 186 //---------------------------load animations-----------------------------
nuclear@0 187 if(string("animations")==SkeletonFile->getNodeName())//animations are optional values
nuclear@0 188 {
nuclear@0 189 DefaultLogger::get()->debug("Loading Animations");
nuclear@0 190 XmlRead(SkeletonFile);
nuclear@0 191 while(string("animation")==SkeletonFile->getNodeName())
nuclear@0 192 {
nuclear@0 193 Animation NewAnimation;
nuclear@0 194 NewAnimation.Name=GetAttribute<string>(SkeletonFile, "name");
nuclear@0 195 NewAnimation.Length=GetAttribute<float>(SkeletonFile, "length");
nuclear@0 196
nuclear@0 197 //Load all Tracks
nuclear@0 198 XmlRead(SkeletonFile);
nuclear@0 199 if(string("tracks")!=SkeletonFile->getNodeName())
nuclear@0 200 throw DeadlyImportError("no tracks node in animation");
nuclear@0 201 XmlRead(SkeletonFile);
nuclear@0 202 while(string("track")==SkeletonFile->getNodeName())
nuclear@0 203 {
nuclear@0 204 Track NewTrack;
nuclear@0 205 NewTrack.BoneName=GetAttribute<string>(SkeletonFile, "bone");
nuclear@0 206
nuclear@0 207 //Load all keyframes;
nuclear@0 208 XmlRead(SkeletonFile);
nuclear@0 209 if(string("keyframes")!=SkeletonFile->getNodeName())
nuclear@0 210 throw DeadlyImportError("no keyframes node!");
nuclear@0 211 XmlRead(SkeletonFile);
nuclear@0 212 while(string("keyframe")==SkeletonFile->getNodeName())
nuclear@0 213 {
nuclear@0 214 Keyframe NewKeyframe;
nuclear@0 215 NewKeyframe.Time=GetAttribute<float>(SkeletonFile, "time");
nuclear@0 216
nuclear@0 217 //loop over the attributes:
nuclear@0 218
nuclear@0 219 while(true) //will quit, if a Node is not a animationkey
nuclear@0 220 {
nuclear@0 221 XmlRead(SkeletonFile);
nuclear@0 222
nuclear@0 223 //If any property doesn't show up, it will keep its initialization value
nuclear@0 224
nuclear@0 225 //Position:
nuclear@0 226 if(string("translate")==SkeletonFile->getNodeName())
nuclear@0 227 {
nuclear@0 228 NewKeyframe.Position.x=GetAttribute<float>(SkeletonFile, "x");
nuclear@0 229 NewKeyframe.Position.y=GetAttribute<float>(SkeletonFile, "y");
nuclear@0 230 NewKeyframe.Position.z=GetAttribute<float>(SkeletonFile, "z");
nuclear@0 231 }
nuclear@0 232
nuclear@0 233 //Rotation:
nuclear@0 234 else if(string("rotate")==SkeletonFile->getNodeName())
nuclear@0 235 {
nuclear@0 236 float RotationAngle=GetAttribute<float>(SkeletonFile, "angle");
nuclear@0 237 aiVector3D RotationAxis;
nuclear@0 238 XmlRead(SkeletonFile);
nuclear@0 239 if(string("axis")!=SkeletonFile->getNodeName())
nuclear@0 240 throw DeadlyImportError("No axis for keyframe rotation!");
nuclear@0 241 RotationAxis.x=GetAttribute<float>(SkeletonFile, "x");
nuclear@0 242 RotationAxis.y=GetAttribute<float>(SkeletonFile, "y");
nuclear@0 243 RotationAxis.z=GetAttribute<float>(SkeletonFile, "z");
nuclear@0 244
nuclear@0 245 if(0==RotationAxis.x && 0==RotationAxis.y && 0==RotationAxis.z)//we have an invalid rotation axis
nuclear@0 246 {
nuclear@0 247 RotationAxis.x=1.0f;
nuclear@0 248 if(0!=RotationAngle)//if we don't rotate at all, the axis does not matter
nuclear@0 249 {
nuclear@0 250 DefaultLogger::get()->warn("Invalid Rotation Axis in Keyframe!");
nuclear@0 251 }
nuclear@0 252 }
nuclear@0 253 NewKeyframe.Rotation=aiQuaternion(RotationAxis, RotationAngle);
nuclear@0 254 }
nuclear@0 255
nuclear@0 256 //Scaling:
nuclear@0 257 else if(string("scale")==SkeletonFile->getNodeName())
nuclear@0 258 {
nuclear@0 259 NewKeyframe.Scaling.x=GetAttribute<float>(SkeletonFile, "x");
nuclear@0 260 NewKeyframe.Scaling.y=GetAttribute<float>(SkeletonFile, "y");
nuclear@0 261 NewKeyframe.Scaling.z=GetAttribute<float>(SkeletonFile, "z");
nuclear@0 262 }
nuclear@0 263
nuclear@0 264 //we suppose, that we read all attributes and this is a new keyframe or the end of the animation
nuclear@0 265 else
nuclear@0 266 break;
nuclear@0 267 }
nuclear@0 268
nuclear@0 269 NewTrack.Keyframes.push_back(NewKeyframe);
nuclear@0 270 }
nuclear@0 271
nuclear@0 272 NewAnimation.Tracks.push_back(NewTrack);
nuclear@0 273 }
nuclear@0 274
nuclear@0 275 Animations.push_back(NewAnimation);
nuclear@0 276 }
nuclear@0 277 }
nuclear@0 278 //_____________________________________________________________________________
nuclear@0 279
nuclear@0 280 }
nuclear@0 281
nuclear@0 282
nuclear@0 283 void OgreImporter::CreateAssimpSkeleton(const std::vector<Bone> &Bones, const std::vector<Animation> &/*Animations*/)
nuclear@0 284 {
nuclear@0 285 if(!m_CurrentScene->mRootNode)
nuclear@0 286 throw DeadlyImportError("No root node exists!!");
nuclear@0 287 if(0!=m_CurrentScene->mRootNode->mNumChildren)
nuclear@0 288 throw DeadlyImportError("Root Node already has childnodes!");
nuclear@0 289
nuclear@0 290
nuclear@0 291 //Createt the assimp bone hierarchy
nuclear@0 292 vector<aiNode*> RootBoneNodes;
nuclear@0 293 BOOST_FOREACH(const Bone &theBone, Bones)
nuclear@0 294 {
nuclear@0 295 if(-1==theBone.ParentId) //the bone is a root bone
nuclear@0 296 {
nuclear@0 297 //which will recursily add all other nodes
nuclear@0 298 RootBoneNodes.push_back(CreateAiNodeFromBone(theBone.Id, Bones, m_CurrentScene->mRootNode));
nuclear@0 299 }
nuclear@0 300 }
nuclear@0 301
nuclear@0 302 if(RootBoneNodes.size() > 0)
nuclear@0 303 {
nuclear@0 304 m_CurrentScene->mRootNode->mNumChildren=RootBoneNodes.size();
nuclear@0 305 m_CurrentScene->mRootNode->mChildren=new aiNode*[RootBoneNodes.size()];
nuclear@0 306 memcpy(m_CurrentScene->mRootNode->mChildren, &RootBoneNodes[0], sizeof(aiNode*)*RootBoneNodes.size());
nuclear@0 307 }
nuclear@0 308 }
nuclear@0 309
nuclear@0 310
nuclear@0 311 void OgreImporter::PutAnimationsInScene(const std::vector<Bone> &Bones, const std::vector<Animation> &Animations)
nuclear@0 312 {
nuclear@0 313 //-----------------Create the Assimp Animations --------------------
nuclear@0 314 if(Animations.size()>0)//Maybe the model had only a skeleton and no animations. (If it also has no skeleton, this function would'nt have been called
nuclear@0 315 {
nuclear@0 316 m_CurrentScene->mNumAnimations=Animations.size();
nuclear@0 317 m_CurrentScene->mAnimations=new aiAnimation*[Animations.size()];
nuclear@0 318 for(unsigned int i=0; i<Animations.size(); ++i)//create all animations
nuclear@0 319 {
nuclear@0 320 aiAnimation* NewAnimation=new aiAnimation();
nuclear@0 321 NewAnimation->mName=Animations[i].Name;
nuclear@0 322 NewAnimation->mDuration=Animations[i].Length;
nuclear@0 323 NewAnimation->mTicksPerSecond=1.0f;
nuclear@0 324
nuclear@0 325 //Create all tracks in this animation
nuclear@0 326 NewAnimation->mNumChannels=Animations[i].Tracks.size();
nuclear@0 327 NewAnimation->mChannels=new aiNodeAnim*[Animations[i].Tracks.size()];
nuclear@0 328 for(unsigned int j=0; j<Animations[i].Tracks.size(); ++j)
nuclear@0 329 {
nuclear@0 330 aiNodeAnim* NewNodeAnim=new aiNodeAnim();
nuclear@0 331 NewNodeAnim->mNodeName=Animations[i].Tracks[j].BoneName;
nuclear@0 332
nuclear@0 333 //we need this, to acces the bones default pose, which we need to make keys absolute to the default bone pose
nuclear@0 334 vector<Bone>::const_iterator CurBone=find(Bones.begin(), Bones.end(), NewNodeAnim->mNodeName);
nuclear@0 335 aiMatrix4x4 t0, t1;
nuclear@0 336 aiMatrix4x4 DefBonePose=aiMatrix4x4::Translation(CurBone->Position, t1)
nuclear@0 337 * aiMatrix4x4::Rotation(CurBone->RotationAngle, CurBone->RotationAxis, t0);
nuclear@0 338
nuclear@0 339
nuclear@0 340 //Create the keyframe arrays...
nuclear@0 341 unsigned int KeyframeCount=Animations[i].Tracks[j].Keyframes.size();
nuclear@0 342 NewNodeAnim->mNumPositionKeys=KeyframeCount;
nuclear@0 343 NewNodeAnim->mNumRotationKeys=KeyframeCount;
nuclear@0 344 NewNodeAnim->mNumScalingKeys =KeyframeCount;
nuclear@0 345 NewNodeAnim->mPositionKeys=new aiVectorKey[KeyframeCount];
nuclear@0 346 NewNodeAnim->mRotationKeys=new aiQuatKey[KeyframeCount];
nuclear@0 347 NewNodeAnim->mScalingKeys =new aiVectorKey[KeyframeCount];
nuclear@0 348
nuclear@0 349 //...and fill them
nuclear@0 350 for(unsigned int k=0; k<KeyframeCount; ++k)
nuclear@0 351 {
nuclear@0 352 aiMatrix4x4 t2, t3;
nuclear@0 353
nuclear@0 354 //Create a matrix to transfrom a vector from the bones default pose to the bone bones in this animation key
nuclear@0 355 aiMatrix4x4 PoseToKey=
nuclear@0 356 aiMatrix4x4::Translation(Animations[i].Tracks[j].Keyframes[k].Position, t3) //pos
nuclear@0 357 * aiMatrix4x4(Animations[i].Tracks[j].Keyframes[k].Rotation.GetMatrix()) //rot
nuclear@0 358 * aiMatrix4x4::Scaling(Animations[i].Tracks[j].Keyframes[k].Scaling, t2); //scale
nuclear@0 359
nuclear@0 360
nuclear@0 361 //calculate the complete transformation from world space to bone space
nuclear@0 362 aiMatrix4x4 CompleteTransform=DefBonePose * PoseToKey;
nuclear@0 363
nuclear@0 364 aiVector3D Pos;
nuclear@0 365 aiQuaternion Rot;
nuclear@0 366 aiVector3D Scale;
nuclear@0 367
nuclear@0 368 CompleteTransform.Decompose(Scale, Rot, Pos);
nuclear@0 369
nuclear@0 370 double Time=Animations[i].Tracks[j].Keyframes[k].Time;
nuclear@0 371
nuclear@0 372 NewNodeAnim->mPositionKeys[k].mTime=Time;
nuclear@0 373 NewNodeAnim->mPositionKeys[k].mValue=Pos;
nuclear@0 374
nuclear@0 375 NewNodeAnim->mRotationKeys[k].mTime=Time;
nuclear@0 376 NewNodeAnim->mRotationKeys[k].mValue=Rot;
nuclear@0 377
nuclear@0 378 NewNodeAnim->mScalingKeys[k].mTime=Time;
nuclear@0 379 NewNodeAnim->mScalingKeys[k].mValue=Scale;
nuclear@0 380 }
nuclear@0 381
nuclear@0 382 NewAnimation->mChannels[j]=NewNodeAnim;
nuclear@0 383 }
nuclear@0 384
nuclear@0 385 m_CurrentScene->mAnimations[i]=NewAnimation;
nuclear@0 386 }
nuclear@0 387 }
nuclear@0 388 //TODO: Auf nicht vorhandene Animationskeys achten!
nuclear@0 389 //#pragma warning (s.o.)
nuclear@0 390 //__________________________________________________________________
nuclear@0 391 }
nuclear@0 392
nuclear@0 393
nuclear@0 394 aiNode* OgreImporter::CreateAiNodeFromBone(int BoneId, const std::vector<Bone> &Bones, aiNode* ParentNode)
nuclear@0 395 {
nuclear@0 396 //----Create the node for this bone and set its values-----
nuclear@0 397 aiNode* NewNode=new aiNode(Bones[BoneId].Name);
nuclear@0 398 NewNode->mParent=ParentNode;
nuclear@0 399
nuclear@0 400 aiMatrix4x4 t0,t1;
nuclear@0 401 NewNode->mTransformation=
nuclear@0 402 aiMatrix4x4::Translation(Bones[BoneId].Position, t0)
nuclear@0 403 *aiMatrix4x4::Rotation(Bones[BoneId].RotationAngle, Bones[BoneId].RotationAxis, t1)
nuclear@0 404 ;
nuclear@0 405 //__________________________________________________________
nuclear@0 406
nuclear@0 407
nuclear@0 408 //---------- recursivly create all children Nodes: ----------
nuclear@0 409 NewNode->mNumChildren=Bones[BoneId].Children.size();
nuclear@0 410 NewNode->mChildren=new aiNode*[Bones[BoneId].Children.size()];
nuclear@0 411 for(unsigned int i=0; i<Bones[BoneId].Children.size(); ++i)
nuclear@0 412 {
nuclear@0 413 NewNode->mChildren[i]=CreateAiNodeFromBone(Bones[BoneId].Children[i], Bones, NewNode);
nuclear@0 414 }
nuclear@0 415 //____________________________________________________
nuclear@0 416
nuclear@0 417
nuclear@0 418 return NewNode;
nuclear@0 419 }
nuclear@0 420
nuclear@0 421
nuclear@0 422 void Bone::CalculateBoneToWorldSpaceMatrix(vector<Bone> &Bones)
nuclear@0 423 {
nuclear@0 424 //Calculate the matrix for this bone:
nuclear@0 425
nuclear@0 426 aiMatrix4x4 t0,t1;
nuclear@0 427 aiMatrix4x4 Transf= aiMatrix4x4::Rotation(-RotationAngle, RotationAxis, t1)
nuclear@0 428 * aiMatrix4x4::Translation(-Position, t0);
nuclear@0 429
nuclear@0 430 if(-1==ParentId)
nuclear@0 431 {
nuclear@0 432 BoneToWorldSpace=Transf;
nuclear@0 433 }
nuclear@0 434 else
nuclear@0 435 {
nuclear@0 436 BoneToWorldSpace=Transf*Bones[ParentId].BoneToWorldSpace;
nuclear@0 437 }
nuclear@0 438
nuclear@0 439
nuclear@0 440 //and recursivly for all children:
nuclear@0 441 BOOST_FOREACH(int theChildren, Children)
nuclear@0 442 {
nuclear@0 443 Bones[theChildren].CalculateBoneToWorldSpaceMatrix(Bones);
nuclear@0 444 }
nuclear@0 445 }
nuclear@0 446
nuclear@0 447
nuclear@0 448 }//namespace Ogre
nuclear@0 449 }//namespace Assimp
nuclear@0 450
nuclear@0 451 #endif // !! ASSIMP_BUILD_NO_OGRE_IMPORTER