//~SceneAnimator(){ Release(); } void Init(Scene pScene) { // this must be called to fill the SceneAnimator with valid data if(!pScene.HasAnimations) return; Release(); Skeleton = CreateBoneTree(pScene.RootNode, null); ExtractAnimations(pScene); for (int i = 0; i < pScene.MeshCount; ++i) { Mesh mesh = pScene.Meshes[i]; for (int n = 0; n < mesh.BoneCount; ++n) { Bone bone = mesh.Bones[n]; //std::map<std::string, cBone*>::iterator found = BonesByName.find(bone->mName.data); if(BonesByName.ContainsKey(bone.Name)) { // FOUND IT!!! woohoo, make sure its not already in the bone list bool skip = false; for(int j = 0; j < Bones.Count; j++) { string bname = bone.Name; if(Bones[j].Name == bname) { skip = true;// already inserted, skip this so as not to insert the same bone multiple times break; } } if(!skip) { // only insert the bone if it has not already been inserted var found = BonesByName[bone.Name]; string tes = found.Name; //this line may require a custom TransposeMatrix function found.Offset = bone.OffsetMatrix; found.Offset.Transpose(); // transpose their matrix to get in the correct format Bones.Add(found); BonesToIndex[bone.Name] = Bones.Count()-1; } } } } float timestep = 1.0f/30.0f;// 30 per second for(int i = 0; i< Animations.Count(); i++) { // pre calculate the animations SetAnimIndex(i); float dt = 0; for(float ticks = 0; ticks < Animations[i].Duration; ticks += Animations[i].TicksPerSecond/30.0f) { dt +=timestep; Calculate(dt); List<Matrix4x4> trans = new List<Matrix4x4>(); for (int a = 0; a < Transforms.Count(); ++a) { Matrix4x4 rotationMatrix = Bones[a].Offset * Bones[a].GlobalTransform; trans.Add(rotationMatrix); } Animations[i].Transforms.Add(trans); } } //OUTPUT_DEBUG_MSG("Finished loading animations with "<<Bones.size()<<" bones"); }
/*protected cBone LoadSkeleton(StreamReader file, cBone pNode) { cBone* internalNode = new cBone();// create a node internalNode->Parent = parent; //set the parent, in the case this is theroot node, it will be null uint32_t nsize=0; file.read(reinterpret_cast<char*>(&nsize), sizeof(uint32_t));// the number of chars char temp[250]; file.read(temp, nsize);// the name of the bone temp[nsize]=0; internalNode->Name = temp; BonesByName[internalNode->Name] = internalNode;// use the name as a key file.read(reinterpret_cast<char*>(&internalNode->Offset), sizeof(internalNode->Offset));// the bone offsets file.read(reinterpret_cast<char*>(&internalNode->OriginalLocalTransform), sizeof(internalNode->OriginalLocalTransform));// original bind pose internalNode->LocalTransform = internalNode->OriginalLocalTransform;// a copy saved CalculateBoneToWorldTransform(internalNode); file.read(reinterpret_cast<char*>(&nsize), sizeof(uint32_t));// the number of children // continue for all child nodes and assign the created internal nodes as our children for( unsigned int a = 0; a < nsize && file; a++){// recursivly call this function on all children internalNode->Children.push_back(LoadSkeleton(file, internalNode)); } return internalNode; }*/ protected void UpdateTransforms(cBone pNode) { CalculateBoneToWorldTransform(pNode); // update global transform as well foreach(cBone c in pNode.Children) { UpdateTransforms(c); } }
protected void SaveSkeleton(StreamWriter file, cBone pNode) { }
protected cBone CreateBoneTree(Node pNode, cBone pParent) { // Recursively creates an internal node structure matching the current scene and animation. cBone internalNode = new cBone();// create a node internalNode.Name = pNode.Name; // get the name of the bone internalNode.Parent = pParent; //set the parent, in the case this is theroot node, it will be null BonesByName[internalNode.Name] = internalNode; // use the name as a key //this may require a custom MatrixTranpose function internalNode.LocalTransform = pNode.Transform; internalNode.LocalTransform.Transpose(); internalNode.OriginalLocalTransform = internalNode.LocalTransform;// a copy saved CalculateBoneToWorldTransform(internalNode); // continue for all child nodes and assign the created internal nodes as our children for(int a = 0; a < pNode.ChildCount; a++) {// recursivly call this function on all children internalNode.Children.Add(CreateBoneTree(pNode.Children[a], internalNode)); } return internalNode; }
protected void CalculateBoneToWorldTransform(cBone child) { /** Calculates the global transformation matrix for the given internal node */ child.GlobalTransform = child.LocalTransform; cBone parent = child.Parent; while (parent != null) {// this will climb the nodes up along through the parents concentating all the matrices to get the Object to World transform, or in this case, the Bone To World transform child.GlobalTransform *= parent.LocalTransform; parent = parent.Parent;// get the parent of the bone we are working on } }
public cBone() { Parent = null; }