public static Assimp.Matrix4x4 AssimpCalculateInverseMatrix(STBone bone) { Assimp.Matrix4x4 transf; //Get parent transform for a smooth matrix if (bone.Parent != null && bone.Parent is STBone) { transf = AssimpCalculateInverseMatrix((STBone)bone.Parent); } else { transf = Assimp.Matrix4x4.Identity; } //Now calculate the matrix with TK matrices var trans = Assimp.Matrix4x4.FromTranslation(new Vector3D(bone.position[0], bone.position[1], bone.position[2])); var scale = Assimp.Matrix4x4.FromScaling(new Vector3D(bone.scale[0], bone.scale[1], bone.scale[2])); var rotX = Assimp.Matrix4x4.FromRotationX(bone.rotation[0]); var rotY = Assimp.Matrix4x4.FromRotationY(bone.rotation[1]); var rotZ = Assimp.Matrix4x4.FromRotationZ(bone.rotation[2]); var result = scale * (rotX * rotY * rotZ) * trans; result.Inverse(); return(transf); }
public static Matrix4x4 GetBoneMatrix(STBone bone) { var pos = Matrix4x4.FromTranslation(new Vector3D(bone.position[0], bone.position[1], bone.position[2])); var rotx = Matrix4x4.FromRotationX(bone.rotation[0]); var roty = Matrix4x4.FromRotationY(bone.rotation[1]); var rotz = Matrix4x4.FromRotationZ(bone.rotation[2]); var sca = Matrix4x4.FromScaling(new Vector3D(bone.scale[0], bone.scale[1], bone.scale[2])); return(sca * (rotx * roty * rotz) * pos); }
private void SaveBones(Node parentBone, STBone bone, STSkeleton skeleton) { Node boneNode = new Node(bone.Text); parentBone.Children.Add(boneNode); boneNode.Transform = AssimpHelper.GetBoneMatrix(bone); foreach (STBone child in bone.GetChildren()) { SaveBones(boneNode, child, skeleton); } }
public Matrix4 GetBoneTransform(STBone Bone) { if (Bone == null) { return(Matrix4.Identity); } if (Bone.parentIndex == -1) { return(Bone.GetTransform()); } else { return(Bone.GetTransform() * GetBoneTransform(bones[Bone.parentIndex])); } }
public STBone CreateGenericBone(SELib.SEModel seModel, SELib.SEModelBone seBone) { STBone bone = new STBone(skeleton); bone.Text = seBone.BoneName; bone.parentIndex = seBone.BoneParent; bone.RotationType = STBone.BoneRotationType.Euler; Vector3 rotEular = ToEular(seBone.LocalRotation); bone.position = new float[] { (float)seBone.LocalPosition.X, (float)seBone.LocalPosition.Y, (float)seBone.LocalPosition.Z }; bone.scale = new float[] { (float)seBone.Scale.X, (float)seBone.Scale.Y, (float)seBone.Scale.Z }; bone.rotation = new float[] { rotEular.X, rotEular.Y, rotEular.Z, 0 }; return(bone); }
public List <STBone> getBoneTreeOrder() { List <STBone> bone = new List <STBone>(); Queue <STBone> q = new Queue <STBone>(); q.Enqueue(bones[0]); while (q.Count > 0) { STBone b = q.Dequeue(); foreach (STBone bo in b.GetChildren()) { q.Enqueue(bo); } bone.Add(b); } return(bone); }
public STBone CreateGenericBone(SELib.SEModel seModel, SELib.SEModelBone seBone) { STBone bone = new STBone(skeleton); bone.Text = seBone.BoneName; bone.parentIndex = seBone.BoneParent; bone.RotationType = STBone.BoneRotationType.Euler; bone.Position = new Vector3( (float)seBone.LocalPosition.X, (float)seBone.LocalPosition.Y, (float)seBone.LocalPosition.Z); bone.Scale = new Vector3( (float)seBone.Scale.X, (float)seBone.Scale.Y, (float)seBone.Scale.Z); bone.Rotation = new Quaternion( (float)seBone.LocalRotation.X, (float)seBone.LocalRotation.Y, (float)seBone.LocalRotation.Z, (float)seBone.LocalRotation.W); return(bone); }
private Mesh SaveMesh(STGenericObject genericObj, Scene scene, int index, STSkeleton skeleton, List <int> NodeArray) { //Assimp is weird so use mesh_# for the name. We'll change it back after save Mesh mesh = new Mesh($"mesh_{ index }", PrimitiveType.Triangle); if (genericObj.MaterialIndex < scene.MaterialCount && genericObj.MaterialIndex > 0) { mesh.MaterialIndex = genericObj.MaterialIndex; } else { mesh.MaterialIndex = 0; } List <Vector3D> textureCoords0 = new List <Vector3D>(); List <Vector3D> textureCoords1 = new List <Vector3D>(); List <Vector3D> textureCoords2 = new List <Vector3D>(); List <Color4D> vertexColors = new List <Color4D>(); int vertexID = 0; foreach (Vertex v in genericObj.vertices) { mesh.Vertices.Add(new Vector3D(v.pos.X, v.pos.Y, v.pos.Z)); mesh.Normals.Add(new Vector3D(v.nrm.X, v.nrm.Y, v.nrm.Z)); textureCoords0.Add(new Vector3D(v.uv0.X, v.uv0.Y, 0)); textureCoords1.Add(new Vector3D(v.uv1.X, v.uv1.Y, 0)); textureCoords2.Add(new Vector3D(v.uv2.X, v.uv2.Y, 0)); vertexColors.Add(new Color4D(v.col.X, v.col.Y, v.col.Z, v.col.W)); if (skeleton != null) { for (int j = 0; j < v.boneIds.Count; j++) { if (j < genericObj.VertexSkinCount) { STBone STbone = null; if (NodeArray != null) { //Get the bone via the node array and bone index from the vertex STbone = skeleton.bones[NodeArray[v.boneIds[j]]]; } else { STbone = skeleton.bones[v.boneIds[j]]; } //Find the index of a bone. If it doesn't exist then we add it int boneInd = mesh.Bones.FindIndex(x => x.Name == STbone.Text); if (boneInd == -1) { var matrices = Toolbox.Library.IO.MatrixExenstion.CalculateInverseMatrix(STbone); //Set the inverse matrix Matrix4x4 transform = matrices.inverse.FromNumerics(); //Create a new assimp bone Bone bone = new Bone(); bone.Name = STbone.Text; bone.OffsetMatrix = STbone.invert.ToMatrix4x4(); mesh.Bones.Add(bone); BoneNames.Add(bone.Name); boneInd = mesh.Bones.IndexOf(bone); //Set the index of the bone for the vertex weight } int MinWeightAmount = 0; //Check if the max amount of weights is higher than the current bone id if (v.boneWeights.Count > j && v.boneWeights[j] > MinWeightAmount) { if (v.boneWeights[j] <= 1) { mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, v.boneWeights[j])); } else { mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1)); } } else if (v.boneWeights.Count == 0 || v.boneWeights[j] > MinWeightAmount) { mesh.Bones[boneInd].VertexWeights.Add(new VertexWeight(vertexID, 1)); } } } } vertexID++; } if (genericObj.lodMeshes.Count != 0) { List <int> faces = genericObj.lodMeshes[genericObj.DisplayLODIndex].faces; for (int f = 0; f < faces.Count; f++) { mesh.Faces.Add(new Face(new int[] { faces[f++], faces[f++], faces[f] })); } } if (genericObj.PolygonGroups.Count != 0) { for (int p = 0; p < genericObj.PolygonGroups.Count; p++) { var polygonGroup = genericObj.PolygonGroups[p]; for (int f = 0; f < polygonGroup.faces.Count; f++) { if (f < polygonGroup.faces.Count - 2) { mesh.Faces.Add(new Face(new int[] { polygonGroup.faces[f++], polygonGroup.faces[f++], polygonGroup.faces[f] })); } } } } mesh.TextureCoordinateChannels.SetValue(textureCoords0, 0); mesh.TextureCoordinateChannels.SetValue(textureCoords1, 1); mesh.TextureCoordinateChannels.SetValue(textureCoords2, 2); mesh.VertexColorChannels.SetValue(vertexColors, 0); return(mesh); }
private void CreateByNode(Node node, STSkeleton skeleton, string ParentArmatureName, short SmoothIndex, short RigidIndex, bool IsRoot, ref Assimp.Matrix4x4 rootTransform) { Matrix4x4 trafo = node.Transform; Matrix4x4 world = trafo * rootTransform; var transformMat = AssimpHelper.TKMatrix(world); int matchedBoneIndex = skeleton.bones.FindIndex(item => item.Name == node.Name); if (matchedBoneIndex < 0) { tempBoneNodes.Add(node); STBone bone = new STBone(); bone.skeletonParent = skeleton; bone.RotationType = STBone.BoneRotationType.Euler; skeleton.bones.Add(bone); if (DaeHelper.IDMapToName.ContainsKey(node.Name)) { bone.Text = DaeHelper.IDMapToName[node.Name]; } else { bone.Text = node.Name; } bone.SmoothMatrixIndex = (short)skeleton.bones.IndexOf(bone); bone.RigidMatrixIndex = -1; //Todo calculate these if (IsRoot) { bone.parentIndex = -1; if (RotateSkeleton) { transformMat = AssimpHelper.TKMatrix(world * Matrix4x4.FromRotationX(MathHelper.DegreesToRadians(RotateSkeletonAmount))); } else { transformMat = AssimpHelper.TKMatrix(world); } } else { if (tempBoneNodes.Contains(node.Parent)) { bone.parentIndex = tempBoneNodes.IndexOf(node.Parent); } } var scale = transformMat.ExtractScale(); var rotation = transformMat.ExtractRotation(); var position = transformMat.ExtractTranslation(); STConsole.WriteLine($"-".Repeat(30)); STConsole.WriteLine($"Processing Bone {bone.Text}"); STConsole.WriteLine($"scale {scale}"); STConsole.WriteLine($"rotation {rotation}"); STConsole.WriteLine($"position {position}"); STConsole.WriteLine($"-".Repeat(30)); bone.FromTransform(transformMat); } else { STConsole.WriteLine($"Duplicate node name found for bone {node.Name}!", Color.Red); } var identity = Matrix4x4.Identity; foreach (Node child in node.Children) { CreateByNode(child, skeleton, ParentArmatureName, SmoothIndex, RigidIndex, false, ref identity); } }
public void update(bool reset = false) { Updated = true; List <STBone> nodesToProcess = new List <STBone>(); // Add all root nodes from the VBN foreach (STBone b in bones) { if (b.parentIndex == -1) { nodesToProcess.Add(b); } } // some special processing for the root bones before we start foreach (STBone b in nodesToProcess) { b.Transform = Matrix4.CreateScale(b.sca) * Matrix4.CreateFromQuaternion(b.rot) * Matrix4.CreateTranslation(b.pos); // scale down the model in its entirety only when mid-animation (i.e. reset == false) if (!reset) { b.Transform *= Matrix4.CreateScale(1); } } // Process as a tree from the root node's children and beyond. These // all use the same processing, unlike the root nodes. int numRootNodes = nodesToProcess.Count; for (int i = 0; i < numRootNodes; i++) { nodesToProcess.AddRange(nodesToProcess[0].GetChildren()); nodesToProcess.RemoveAt(0); } while (nodesToProcess.Count > 0) { // DFS STBone Bone = nodesToProcess[0]; nodesToProcess.RemoveAt(0); nodesToProcess.AddRange(Bone.GetChildren()); // Process this node Bone.Transform = Matrix4.CreateScale(Bone.sca) * Matrix4.CreateFromQuaternion(Bone.rot) * Matrix4.CreateTranslation(Bone.pos); if (Bone.parentIndex != -1) { if (Bone.UseSegmentScaleCompensate && Bone.Parent != null && Bone.Parent is STBone) { Bone.Transform *= Matrix4.CreateScale( 1f / ((STBone)Bone.Parent).GetScale().X, 1f / ((STBone)Bone.Parent).GetScale().Y, 1f / ((STBone)Bone.Parent).GetScale().Z); Bone.Transform *= ((STBone)Bone.Parent).Transform; } else { Bone.Transform = Bone.Transform * ((STBone)Bone.Parent).Transform; } } } }
public static Syroot.Maths.Matrix3x4 CalculateInverseMatrix(STBone bone) { return(FromAssimpMatrix(AssimpCalculateInverseMatrix(bone))); }
public static Matrix4x4 GetBoneMatrix(STBone bone) { return(AssimpFromTKMatrix(bone.Transform)); }
private static SELib.SEModelBone SaveBone(STBone bone) { var seBone = new SELib.SEModelBone(); return(seBone); }