public override void Read(BinaryReader b) { base.Read(b); this.SkipBytes(b, 32); // Padding between the chunk header and the first bone. Vector3 localTranslation; Matrix33 localRotation; // Read the first bone with ReadCompiledBone, then recursively grab all the children for each bone you find. // Each bone structure is 584 bytes, so will need to seek childOffset * 584 each time, and go back. NumBones = (int)((this.Size - 32) / 584); for (int i = 0; i < NumBones; i++) { CompiledBone tempBone = new CompiledBone(); tempBone.ReadCompiledBone(b); if (RootBone == null) // First bone read is root bone { this.RootBone = tempBone; } tempBone.LocalTranslation = tempBone.boneToWorld.GetBoneToWorldTranslationVector(); // World positions of the bone tempBone.LocalRotation = tempBone.boneToWorld.GetBoneToWorldRotationMatrix(); // World rotation of the bone. //tempBone.ParentBone = BoneMap[i + tempBone.offsetParent]; tempBone.ParentBone = GetParentBone(tempBone, i); if (tempBone.ParentBone != null) { tempBone.parentID = tempBone.ParentBone.ControllerID; } else { tempBone.parentID = 0; } if (tempBone.parentID != 0) { localRotation = GetParentBone(tempBone, i).boneToWorld.GetBoneToWorldRotationMatrix().ConjugateTransposeThisAndMultiply(tempBone.boneToWorld.GetBoneToWorldRotationMatrix()); localTranslation = GetParentBone(tempBone, i).LocalRotation *(tempBone.LocalTranslation - GetParentBone(tempBone, i).boneToWorld.GetBoneToWorldTranslationVector()); } else { localTranslation = tempBone.boneToWorld.GetBoneToWorldTranslationVector(); localRotation = tempBone.boneToWorld.GetBoneToWorldRotationMatrix(); } tempBone.LocalTransform = GetTransformFromParts(localTranslation, localRotation); BoneList.Add(tempBone); BoneDictionary[i] = tempBone; } // Add the ChildID to the parent bone. This will help with navigation. Also set up the TransformSoFar foreach (CompiledBone bone in BoneList) { AddChildIDToParent(bone); } SkinningInfo skin = GetSkinningInfo(); skin.CompiledBones = new List <CompiledBone>(); skin.HasSkinningInfo = true; skin.CompiledBones = BoneList; }
public void GetCompiledBones(BinaryReader b, String parent) // Recursive call to read the bone at the current seek, and all children. { // Start reading all the properties of this bone. CompiledBone tempBone = new CompiledBone(); // Utils.Log(LogLevelEnum.Debug, "** Current offset {0:X}", b.BaseStream.Position); tempBone.offset = b.BaseStream.Position; tempBone.ReadCompiledBone(b); tempBone.parentID = parent; //tempBone.WriteCompiledBone(); tempBone.childNames = new String[tempBone.numChildren]; this.BoneDictionary[tempBone.boneName] = tempBone; // Add this bone to the dictionary. for (Int32 i = 0; i < tempBone.numChildren; i++) { // If child offset is 1, then we're at the right position anyway. If it's 2, you want to 584 bytes. 3 is (584*2)... // Move to the offset of child. If there are no children, we shouldn't move at all. b.BaseStream.Seek(tempBone.offset + 584 * tempBone.offsetChild + (i * 584), 0); this.GetCompiledBones(b, tempBone.boneName); } // Need to set the seek position back to the parent at this point? Can use parent offset * 584... Parent offset is a neg number //Utils.Log(LogLevelEnum.Debug, "Parent offset: {0}", tempBone.offsetParent); }