/// <summary> /// Computes the absolute position for all the bones in this skeleton. /// </summary> /// <param name="bone">The bone to start with, should always be the ROOT bone.</param> /// <param name="world">A world matrix to use in the calculation.</param> public void ComputeBonePositions(Bone bone, Matrix world) { var translateMatrix = Matrix.CreateTranslation(bone.Translation); var rotationMatrix = FindQuaternionMatrix(bone.Rotation); var myWorld = (rotationMatrix * translateMatrix) * world; bone.AbsolutePosition = Vector3.Transform(Vector3.Zero, myWorld); bone.AbsoluteMatrix = myWorld; foreach (var child in bone.Children) { ComputeBonePositions(child, myWorld); } }
public Bone Clone() { var result = new Bone { Unknown = this.Unknown, Name = this.Name, ParentName = this.ParentName, HasProps = this.HasProps, Properties = this.Properties, Translation = this.Translation, Rotation = this.Rotation, CanTranslate = this.CanTranslate, CanRotate = this.CanRotate, CanBlend = this.CanBlend, WiggleValue = this.WiggleValue, WigglePower = this.WigglePower }; return result; }
public void Read(Stream stream) { using (var io = IoBuffer.FromStream(stream)){ var version = io.ReadUInt32(); Name = io.ReadPascalString(); var boneCount = io.ReadInt16(); Bones = new Bone[boneCount]; for (var i = 0; i < boneCount; i++) { Bones[i] = ReadBone(io); } /** Construct tree **/ foreach (var bone in Bones) { bone.Children = Bones.Where(x => x.ParentName == bone.Name).ToArray(); } RootBone = Bones.FirstOrDefault(x => x.ParentName == "NULL"); ComputeBonePositions(RootBone, Matrix.Identity); } }
private Bone ReadBone(IoBuffer reader) { var bone = new Bone(); bone.Unknown = reader.ReadInt32(); bone.Name = reader.ReadPascalString(); bone.ParentName = reader.ReadPascalString(); bone.HasProps = reader.ReadByte(); if (bone.HasProps != 0) { var propertyCount = reader.ReadInt32(); var property = new PropertyListItem(); for (var i = 0; i < propertyCount; i++) { var pairCount = reader.ReadInt32(); for (var x = 0; x < pairCount; x++) { property.KeyPairs.Add(new KeyValuePair<string, string>( reader.ReadPascalString(), reader.ReadPascalString() )); } } bone.Properties.Add(property); } var xx = -reader.ReadFloat(); bone.Translation = new Vector3( xx, reader.ReadFloat(), reader.ReadFloat() ); bone.Rotation = new Vector4( reader.ReadFloat(), -reader.ReadFloat(), -reader.ReadFloat(), reader.ReadFloat() ); bone.CanTranslate = reader.ReadInt32(); bone.CanRotate = reader.ReadInt32(); bone.CanBlend = reader.ReadInt32(); bone.WiggleValue = reader.ReadFloat(); bone.WigglePower = reader.ReadFloat(); return bone; }
/// <summary> /// Transforms the verticies making up this mesh into /// the designated bone positions. /// </summary> /// <param name="bone">The bone to start with. Should always be the ROOT bone.</param> public void Transform(Bone bone) { var binding = BoneBindings.FirstOrDefault(x => x.BoneName == bone.Name); if (binding != null) { for (var i = 0; i < binding.RealVertexCount; i++) { var vertexIndex = binding.FirstRealVertex + i; var blendVertexIndex = vertexIndex;//binding.FirstBlendVertex + i; var realVertex = RealVertexBuffer[vertexIndex]; var matrix = Matrix.CreateTranslation(realVertex.Position) * bone.AbsoluteMatrix; //Position var newPosition = Vector3.Transform(Vector3.Zero, matrix); BlendVertexBuffer[blendVertexIndex].Position = newPosition; //Normals matrix = Matrix.CreateTranslation( new Vector3(realVertex.Normal.X, realVertex.Normal.Y, realVertex.Normal.Z)) * bone.AbsoluteMatrix; } } foreach (var child in bone.Children) { Transform(child); } if (bone.Name == "ROOT") { InvalidateMesh(); } }