Пример #1
0
		private Bone CreateBoneTree(ref Skeleton skele, Node node, Bone parent) {

			var internalNode = new Bone {
				Name = node.Name, Parent = parent,
			};
			if (boneNames.ContainsKey (node.Name)) {
				boneNames [node.Name].OffsetMatrix.Transpose ();
				internalNode.Offset = FromMatrix (boneNames [node.Name].OffsetMatrix);

			}if (internalNode.Name == "") {
				internalNode.Name = "bone_" + _i++;
			}
			//skele[internalNode.Name] = internalNode;
			var trans = node.Transform;
			trans.Transpose(); //drectx stuff
			internalNode.LocalTransform =FromMatrix(trans);
			internalNode.OriginalLocalTransform = internalNode.LocalTransform;
			CalculateBoneToWorldTransform(internalNode);
			internalNode.Children = new List<Bone> ();
			for (var i = 0; i < node.ChildCount; i++) {
				var child = CreateBoneTree(ref skele,node.Children[i], internalNode);
				if (child != null) {
					internalNode.Children.Add(child);
				}
			}

			return internalNode;
		}
Пример #2
0
		private static void CalculateBoneToWorldTransform(Bone child) {
			child.GlobalTransform = child.LocalTransform;
			var parent = child.Parent;
			while (parent != null) {
				child.GlobalTransform *= parent.LocalTransform;
				parent = parent.Parent;
			}
		}
Пример #3
0
        Bone GetBone(Mesh mesh, Assimp.Bone aBone)
        {
            var bone = mesh.Bones.FirstOrDefault(b => b.Name == aBone.Name);

            if (bone == null)
            {
                var offsetMatrix = aBone.OffsetMatrix;
                offsetMatrix.Transpose();

                bone               = new Bone();
                bone.Name          = aBone.Name;
                bone.Index         = mesh.Bones.Count;
                bone.Offset        = AssimpHelper.MatrixAssimpToXna(offsetMatrix);
                bone.OffsetInverse = Matrix.Invert(AssimpHelper.MatrixAssimpToXna(offsetMatrix));
                mesh.Bones.Add(bone);
            }
            return(bone);
        }
Пример #4
0
        private static BoneInfo ConvertBoneFromAiBone(Ai.Bone aiBone, Ai.Scene aiScene, int boneId)
        {
            Matrix4x4 inverseTransformation;

            var aiBoneNode = aiScene.RootNode.FindNode(aiBone.Name);

            if (aiBoneNode != null)
            {
                Matrix4x4.Invert(GetGlobalTransformation(aiBoneNode).ToNumerics(), out inverseTransformation);
            }
            else
            {
                inverseTransformation = aiBone.OffsetMatrix.ToNumerics();
            }

            return(new BoneInfo
            {
                Name = aiBone.Name,
                Id = boneId,
                InverseBindPoseMatrix = inverseTransformation,
            });
        }
Пример #5
0
        private static Bone ConvertBoneFromAiBone(Ai.Bone aiBone, Ai.Scene aiScene, int boneID)
        {
            Matrix4x4 inverseTransformation;

            var aiBoneNode = aiScene.RootNode.FindNode(aiBone.Name);

            if (aiBoneNode != null)
            {
                Matrix4x4.Invert(GetWorldTransformation(aiBoneNode, false), out inverseTransformation);
            }
            else
            {
                inverseTransformation = GetMatrix4x4FromAiMatrix4x4(aiBone.OffsetMatrix, false);
            }

            return(new Bone
            {
                Name = aiBone.Name,
                ID = boneID,
                Matrix = inverseTransformation,
            });
        }
Пример #6
0
        private static Ai.Node ConvertAiNodeFromMesh(Mesh mesh, Ai.Scene aiScene, bool appendTags = false)
        {
            var aiNode = new Ai.Node(mesh.Name);

            foreach (var subMesh in mesh.SubMeshes)
            {
                foreach (var indexTable in subMesh.IndexTables)
                {
                    var aiSubMeshNode = new Ai.Node(subMesh.Name);
                    var aiMesh        = new Ai.Mesh(subMesh.Name, Ai.PrimitiveType.Triangle);

                    var material = mesh.Materials[indexTable.MaterialIndex];
                    aiMesh.MaterialIndex = aiScene.Materials.FindIndex(x => x.Name.Equals(material.Name));

                    if (subMesh.Vertices != null)
                    {
                        aiMesh.Vertices.AddRange(subMesh.Vertices.Select(
                                                     x => new Ai.Vector3D(x.X, x.Y, x.Z)));
                    }

                    if (subMesh.Normals != null)
                    {
                        aiMesh.Normals.AddRange(subMesh.Normals.Select(
                                                    x => new Ai.Vector3D(x.X, x.Y, x.Z)));
                    }

                    if (subMesh.UVChannel1 != null)
                    {
                        aiMesh.TextureCoordinateChannels[0].AddRange(subMesh.UVChannel1.Select(
                                                                         x => new Ai.Vector3D(x.X, 1.0f - x.Y, 0.0f)));
                    }

                    if (subMesh.UVChannel2 != null)
                    {
                        aiMesh.TextureCoordinateChannels[1].AddRange(subMesh.UVChannel2.Select(
                                                                         x => new Ai.Vector3D(x.X, 1.0f - x.Y, 0.0f)));
                    }

                    // Why does 3DS Max go retarded when colors are exported?
                    if (subMesh.Colors != null)
                    {
                        aiMesh.VertexColorChannels[0].AddRange(subMesh.Colors.Select(
                                                                   x => new Ai.Color4D(x.R, x.G, x.B, x.A)));
                    }

                    foreach (var triangle in indexTable.GetTriangles())
                    {
                        var aiFace = new Ai.Face();
                        aiFace.Indices.Add(triangle.A);
                        aiFace.Indices.Add(triangle.B);
                        aiFace.Indices.Add(triangle.C);
                        aiMesh.Faces.Add(aiFace);
                    }

                    if (indexTable.BoneIndices != null)
                    {
                        for (int i = 0; i < indexTable.BoneIndices.Length; i++)
                        {
                            int boneIndex = indexTable.BoneIndices[i];
                            var bone      = mesh.Skin.Bones[boneIndex];
                            var aiBone    = new Ai.Bone();
                            aiBone.Name         = bone.Name;
                            aiBone.OffsetMatrix = bone.Matrix.ToAssimp();

                            if (appendTags)
                            {
                                aiBone.Name = $"{aiBone.Name}{Tag.Create( "ID", bone.Id )}";
                            }

                            for (int j = 0; j < subMesh.BoneWeights.Length; j++)
                            {
                                var weight = subMesh.BoneWeights[j];
                                if (weight.Index1 == i)
                                {
                                    aiBone.VertexWeights.Add(new Ai.VertexWeight
                                    {
                                        VertexID = j,
                                        Weight   = weight.Weight1
                                    });
                                }

                                if (weight.Index2 == i)
                                {
                                    aiBone.VertexWeights.Add(new Ai.VertexWeight
                                    {
                                        VertexID = j,
                                        Weight   = weight.Weight2
                                    });
                                }

                                if (weight.Index3 == i)
                                {
                                    aiBone.VertexWeights.Add(new Ai.VertexWeight
                                    {
                                        VertexID = j,
                                        Weight   = weight.Weight3
                                    });
                                }

                                if (weight.Index4 == i)
                                {
                                    aiBone.VertexWeights.Add(new Ai.VertexWeight
                                    {
                                        VertexID = j,
                                        Weight   = weight.Weight4
                                    });
                                }
                            }

                            aiMesh.Bones.Add(aiBone);
                        }
                    }

                    aiNode.Children.Add(aiSubMeshNode);
                    aiSubMeshNode.MeshIndices.Add(aiScene.MeshCount);
                    aiScene.Meshes.Add(aiMesh);
                }
            }

            if (appendTags)
            {
                aiNode.Name = $"{aiNode.Name}{Tag.Create( "ID", mesh.Id )}";
            }

            return(aiNode);
        }
Пример #7
0
        public void FillScene(Scene scene, VertexData vertData, List <Rigging.Bone> flatSkeleton, List <Matrix4> inverseBindMatrices)
        {
            for (int i = 0; i < Shapes.Count; i++)
            {
                Mesh mesh = new Mesh($"mesh_{ i }", PrimitiveType.Triangle);
                mesh.MaterialIndex = i;

                int   vertexID = 0;
                Shape curShape = Shapes[i];
                foreach (Packet pack in curShape.Packets)
                {
                    foreach (Primitive prim in pack.Primitives)
                    {
                        List <Vertex> triVertices = J3DUtility.PrimitiveToTriangles(prim);

                        for (int triIndex = 0; triIndex < triVertices.Count; triIndex += 3)
                        {
                            Face newFace = new Face(new int[] { vertexID + 2, vertexID + 1, vertexID });
                            mesh.Faces.Add(newFace);

                            for (int triVertIndex = 0; triVertIndex < 3; triVertIndex++)
                            {
                                Vertex vert = triVertices[triIndex + triVertIndex];

                                for (int j = 0; j < vert.VertexWeight.WeightCount; j++)
                                {
                                    Rigging.Bone curWeightBone = flatSkeleton[vert.VertexWeight.BoneIndices[j]];

                                    int assBoneIndex = mesh.Bones.FindIndex(x => x.Name == curWeightBone.Name);

                                    if (assBoneIndex == -1)
                                    {
                                        Assimp.Bone newBone = new Assimp.Bone();
                                        newBone.Name         = curWeightBone.Name;
                                        newBone.OffsetMatrix = curWeightBone.InverseBindMatrix.ToMatrix4x4();
                                        mesh.Bones.Add(newBone);
                                        assBoneIndex = mesh.Bones.IndexOf(newBone);
                                    }

                                    mesh.Bones[assBoneIndex].VertexWeights.Add(new VertexWeight(vertexID, vert.VertexWeight.Weights[j]));
                                }

                                OpenTK.Vector3 posVec    = vertData.Positions[(int)vert.GetAttributeIndex(GXVertexAttribute.Position)];
                                OpenTK.Vector4 openTKVec = new Vector4(posVec.X, posVec.Y, posVec.Z, 1);

                                Vector3D vertVec = new Vector3D(openTKVec.X, openTKVec.Y, openTKVec.Z);

                                if (vert.VertexWeight.WeightCount == 1)
                                {
                                    if (inverseBindMatrices.Count > vert.VertexWeight.BoneIndices[0])
                                    {
                                        Matrix4 test = inverseBindMatrices[vert.VertexWeight.BoneIndices[0]].Inverted();
                                        test.Transpose();
                                        Vector4 trans = OpenTK.Vector4.Transform(openTKVec, test);
                                        vertVec = new Vector3D(trans.X, trans.Y, trans.Z);
                                    }
                                    else
                                    {
                                        Vector4 trans = OpenTK.Vector4.Transform(openTKVec, flatSkeleton[vert.VertexWeight.BoneIndices[0]].TransformationMatrix);
                                        vertVec = new Vector3D(trans.X, trans.Y, trans.Z);
                                    }
                                }

                                /*else
                                 * {
                                 *  Matrix4 finalMatrix = Matrix4.Zero;
                                 *
                                 *  for (int m = 0; m < vert.VertexWeight.WeightCount; m++)
                                 *  {
                                 *      Matrix4 sm1 = inverseBindMatrices[vert.VertexWeight.BoneIndices[m]];
                                 *      //sm1.Transpose();
                                 *      Matrix4 sm2 = flatSkeleton[vert.VertexWeight.BoneIndices[m]].TransformationMatrix;
                                 *      //sm2.Transpose();
                                 *
                                 *      finalMatrix += Matrix4.Mult(sm1, vert.VertexWeight.Weights[m]);
                                 *  }
                                 *
                                 *  Vector4 final = Vector4.Transform(openTKVec, finalMatrix);
                                 *
                                 *  vertVec = new Vector3D(final.X, final.Y, final.Z);
                                 * }*/

                                mesh.Vertices.Add(vertVec);

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Normal))
                                {
                                    mesh.Normals.Add(vertData.Normals[(int)vert.NormalIndex].ToVector3D());
                                }

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Color0))
                                {
                                    mesh.VertexColorChannels[0].Add(vertData.Color_0[(int)vert.Color0Index].ToColor4D());
                                }

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Color1))
                                {
                                    mesh.VertexColorChannels[1].Add(vertData.Color_1[(int)vert.Color1Index].ToColor4D());
                                }

                                for (int texCoordNum = 0; texCoordNum < 8; texCoordNum++)
                                {
                                    if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Tex0 + texCoordNum))
                                    {
                                        Vector3D texCoord = new Vector3D();
                                        switch (texCoordNum)
                                        {
                                        case 0:
                                            texCoord = vertData.TexCoord_0[(int)vert.TexCoord0Index].ToVector2D();
                                            break;

                                        case 1:
                                            texCoord = vertData.TexCoord_1[(int)vert.TexCoord1Index].ToVector2D();
                                            break;

                                        case 2:
                                            texCoord = vertData.TexCoord_2[(int)vert.TexCoord2Index].ToVector2D();
                                            break;

                                        case 3:
                                            texCoord = vertData.TexCoord_3[(int)vert.TexCoord3Index].ToVector2D();
                                            break;

                                        case 4:
                                            texCoord = vertData.TexCoord_4[(int)vert.TexCoord4Index].ToVector2D();
                                            break;

                                        case 5:
                                            texCoord = vertData.TexCoord_5[(int)vert.TexCoord5Index].ToVector2D();
                                            break;

                                        case 6:
                                            texCoord = vertData.TexCoord_6[(int)vert.TexCoord6Index].ToVector2D();
                                            break;

                                        case 7:
                                            texCoord = vertData.TexCoord_7[(int)vert.TexCoord7Index].ToVector2D();
                                            break;
                                        }

                                        mesh.TextureCoordinateChannels[texCoordNum].Add(texCoord);
                                    }
                                }

                                vertexID++;
                            }
                        }
                    }
                }

                scene.Meshes.Add(mesh);
            }
        }
Пример #8
0
        private static Ai.Mesh CreateAiMeshFromSubMesh(SubMesh subMesh, Mesh mesh, Object obj, Ai.Scene aiScene, string name)
        {
            var aiMesh = new Ai.Mesh(name, Ai.PrimitiveType.Triangle);

            if (mesh.Positions != null)
            {
                aiMesh.Vertices.Capacity = mesh.Positions.Length;
                aiMesh.Vertices.AddRange(mesh.Positions.Select(x => x.ToAssimp()));
            }

            if (mesh.Normals != null)
            {
                aiMesh.Normals.Capacity = mesh.Normals.Length;
                aiMesh.Normals.AddRange(mesh.Normals.Select(x => x.ToAssimp()));
            }

            for (int i = 0; i < 4; i++)
            {
                var texCoords = mesh.GetTexCoordsChannel(i);

                if (texCoords == null)
                {
                    continue;
                }

                aiMesh.TextureCoordinateChannels[i].Capacity = texCoords.Length;
                aiMesh.TextureCoordinateChannels[i].AddRange(texCoords.Select(x => new Ai.Vector3D(x.ToAssimp(), 0)));
            }

            for (int i = 0; i < 2; i++)
            {
                var colors = mesh.GetColorsChannel(i);

                if (colors == null)
                {
                    continue;
                }

                aiMesh.VertexColorChannels[i].Capacity = colors.Length;
                aiMesh.VertexColorChannels[i].AddRange(colors.Select(x => x.ToAssimp()));
            }

            if (mesh.BoneWeights != null)
            {
                for (int i = 0; i < subMesh.BoneIndices.Length; i++)
                {
                    ushort boneIndex = subMesh.BoneIndices[i];
                    var    bone      = obj.Skin.Bones[boneIndex];

                    var aiBone = new Ai.Bone();

                    aiBone.Name         = bone.Name;
                    aiBone.OffsetMatrix = bone.InverseBindPoseMatrix.ToAssimpTransposed();

                    for (int j = 0; j < mesh.BoneWeights.Length; j++)
                    {
                        var boneWeight = mesh.BoneWeights[j];

                        if (boneWeight.Index1 == i)
                        {
                            aiBone.VertexWeights.Add(new Ai.VertexWeight(j, boneWeight.Weight1));
                        }

                        if (boneWeight.Index2 == i)
                        {
                            aiBone.VertexWeights.Add(new Ai.VertexWeight(j, boneWeight.Weight2));
                        }

                        if (boneWeight.Index3 == i)
                        {
                            aiBone.VertexWeights.Add(new Ai.VertexWeight(j, boneWeight.Weight3));
                        }

                        if (boneWeight.Index4 == i)
                        {
                            aiBone.VertexWeights.Add(new Ai.VertexWeight(j, boneWeight.Weight4));
                        }
                    }

                    aiMesh.Bones.Add(aiBone);
                }
            }

            var triangles = subMesh.GetTriangles();

            aiMesh.Faces.Capacity = triangles.Count;

            aiMesh.Faces.AddRange(triangles.Select(x =>
            {
                var aiFace = new Ai.Face();
                aiFace.Indices.Capacity = 3;
                aiFace.Indices.Add(( int )x.A);
                aiFace.Indices.Add(( int )x.B);
                aiFace.Indices.Add(( int )x.C);
                return(aiFace);
            }));

            var material = obj.Materials[( int )subMesh.MaterialIndex];

            int materialIndex = aiScene.Materials.FindIndex(x => x.Name == material.Name + "+" + obj.Name);

            if (materialIndex == -1)
            {
                materialIndex = aiScene.Materials.FindIndex(x => x.Name == material.Name);
            }

            aiMesh.MaterialIndex = materialIndex;

            return(aiMesh);
        }
Пример #9
0
        /// <summary>
        /// Constructs a new Mesh.
        /// </summary>
        /// <param name="mesh">Unmanaged AiMesh struct.</param>
        internal Mesh(AiMesh mesh)
        {
            _name = mesh.Name.GetString();
            _primitiveType = mesh.PrimitiveTypes;
            _vertexCount = (int) mesh.NumVertices;
            _materialIndex = (int) mesh.MaterialIndex;

            //Load per-vertex arrays
            if(mesh.NumVertices > 0) {
                if(mesh.Vertices != IntPtr.Zero) {
                    _vertices = MemoryHelper.MarshalArray<Vector3D>(mesh.Vertices, _vertexCount);
                }
                if(mesh.Normals != IntPtr.Zero) {
                    _normals = MemoryHelper.MarshalArray<Vector3D>(mesh.Normals, _vertexCount);
                }
                if(mesh.Tangents != IntPtr.Zero) {
                    _tangents = MemoryHelper.MarshalArray<Vector3D>(mesh.Tangents, _vertexCount);
                }
                if(mesh.BiTangents != IntPtr.Zero) {
                    _bitangents = MemoryHelper.MarshalArray<Vector3D>(mesh.BiTangents, _vertexCount);
                }
            }

            //Load faces
            if(mesh.NumFaces > 0 && mesh.Faces != IntPtr.Zero) {
                AiFace[] faces = MemoryHelper.MarshalArray<AiFace>(mesh.Faces, (int) mesh.NumFaces);
                _faces = new Face[faces.Length];
                for(int i = 0; i < _faces.Length; i++) {
                    _faces[i] = new Face(faces[i]);
                }
            }

            //Load UVW components - this should match the texture coordinate channels
            uint[] components = mesh.NumUVComponents;
            if(components != null) {
                _texComponentNumber = new List<uint>();
                foreach(uint num in components) {
                    if(num > 0) {
                        _texComponentNumber.Add(num);
                    }
                }
            }

            //Load texture coordinate channels
            IntPtr[] texCoords = mesh.TextureCoords;
            if(texCoords != null) {
                _texCoords = new List<Vector3D[]>();
                foreach(IntPtr texPtr in texCoords) {
                    if(texPtr != IntPtr.Zero) {
                        _texCoords.Add(MemoryHelper.MarshalArray<Vector3D>(texPtr, _vertexCount));
                    }
                }
            }

            //Load vertex color channels
            IntPtr[] vertexColors = mesh.Colors;
            if(vertexColors != null) {
                _colors = new List<Color4D[]>();
                foreach(IntPtr colorPtr in vertexColors) {
                    if(colorPtr != IntPtr.Zero) {
                        _colors.Add(MemoryHelper.MarshalArray<Color4D>(colorPtr, _vertexCount));
                    }
                }
            }

            //Load bones
            if(mesh.NumBones > 0 && mesh.Bones != IntPtr.Zero) {
                AiBone[] bones = MemoryHelper.MarshalArray<AiBone>(mesh.Bones, (int) mesh.NumBones, true);
                _bones = new Bone[bones.Length];
                for(int i = 0; i < _bones.Length; i++) {
                    _bones[i] = new Bone(bones[i]);
                }
            }

            //Load anim meshes (attachment meshes)
            if(mesh.NumAnimMeshes > 0 && mesh.AnimMeshes != IntPtr.Zero) {
                AiAnimMesh[] animMeshes = MemoryHelper.MarshalArray<AiAnimMesh>(mesh.AnimMeshes, (int) mesh.NumAnimMeshes, true);
                _meshAttachments = new MeshAnimationAttachment[animMeshes.Length];
                for(int i = 0; i < _meshAttachments.Length; i++) {
                    _meshAttachments[i] = new MeshAnimationAttachment(animMeshes[i]);
                }
            }
        }
Пример #10
0
        private Ai.Mesh ConvertGeometry(Scene scene, Node geometryNode, Geometry geometry)
        {
            var aiMesh = new Ai.Mesh(Ai.PrimitiveType.Triangle);

            if (geometry.Flags.HasFlag(GeometryFlags.HasMaterial))
            {
                aiMesh.MaterialIndex = mAiScene.Materials.FindIndex(x => x.Name == AssimpConverterCommon.EscapeName(geometry.MaterialName));
            }

            if (geometry.Flags.HasFlag(GeometryFlags.HasTriangles))
            {
                foreach (var triangle in geometry.Triangles)
                {
                    var aiFace = new Ai.Face();
                    aiFace.Indices.Add(( int )triangle.A);
                    aiFace.Indices.Add(( int )triangle.B);
                    aiFace.Indices.Add(( int )triangle.C);
                    aiMesh.Faces.Add(aiFace);
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Position))
            {
                foreach (var vertex in geometry.Vertices)
                {
                    aiMesh.Vertices.Add(new Ai.Vector3D(vertex.X, vertex.Y, vertex.Z));
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Normal))
            {
                foreach (var normal in geometry.Normals)
                {
                    aiMesh.Normals.Add(new Ai.Vector3D(normal.X, normal.Y, normal.Z));
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Tangent))
            {
                foreach (var tangent in geometry.Tangents)
                {
                    aiMesh.Tangents.Add(new Ai.Vector3D(tangent.X, tangent.Y, tangent.Z));
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.Binormal))
            {
                foreach (var binormal in geometry.Binormals)
                {
                    aiMesh.BiTangents.Add(new Ai.Vector3D(binormal.X, binormal.Y, binormal.Z));
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.TexCoord0))
            {
                foreach (var vertex in geometry.TexCoordsChannel0)
                {
                    aiMesh.TextureCoordinateChannels[0].Add(new Ai.Vector3D(vertex.X, vertex.Y, 0));
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.TexCoord1))
            {
                foreach (var vertex in geometry.TexCoordsChannel1)
                {
                    aiMesh.TextureCoordinateChannels[1].Add(new Ai.Vector3D(vertex.X, vertex.Y, 0));
                }
            }

            if (geometry.VertexAttributeFlags.HasFlag(VertexAttributeFlags.TexCoord2))
            {
                foreach (var vertex in geometry.TexCoordsChannel2)
                {
                    aiMesh.TextureCoordinateChannels[2].Add(new Ai.Vector3D(vertex.X, vertex.Y, 0));
                }
            }

            /* todo: colors
             * if ( geometry.VertexAttributeFlags.HasFlag( VertexAttributeFlags.Color0 ) )
             * {
             *  foreach ( var color in geometry.ColorChannel0 )
             *  {
             *      aiMesh.VertexColorChannels[0].Add( new Ai.Color4D( color. ))
             *  }
             * }
             */

            if (geometry.Flags.HasFlag(GeometryFlags.HasVertexWeights))
            {
                var boneMap = new Dictionary <int, Ai.Bone>();

                for (int i = 0; i < geometry.VertexWeights.Length; i++)
                {
                    var vertexWeight = geometry.VertexWeights[i];

                    for (int j = 0; j < 4; j++)
                    {
                        var boneWeight = vertexWeight.Weights[j];
                        if (boneWeight == 0f)
                        {
                            continue;
                        }

                        var boneIndex = vertexWeight.Indices[j];
                        var nodeIndex = scene.BonePalette.BoneToNodeIndices[boneIndex];

                        if (!boneMap.ContainsKey(nodeIndex))
                        {
                            var aiBone   = new Ai.Bone();
                            var boneNode = scene.GetNode(nodeIndex);

                            aiBone.Name = AssimpConverterCommon.EscapeName(boneNode.Name);
                            aiBone.VertexWeights.Add(new Ai.VertexWeight(i, boneWeight));

                            Matrix4x4.Invert(geometryNode.WorldTransform, out Matrix4x4 invGeometryNodeWorldTransform);
                            Matrix4x4.Invert(boneNode.WorldTransform * invGeometryNodeWorldTransform, out Matrix4x4 offsetMatrix);
                            aiBone.OffsetMatrix = new Ai.Matrix4x4(offsetMatrix.M11, offsetMatrix.M21, offsetMatrix.M31, offsetMatrix.M41,
                                                                   offsetMatrix.M12, offsetMatrix.M22, offsetMatrix.M32, offsetMatrix.M42,
                                                                   offsetMatrix.M13, offsetMatrix.M23, offsetMatrix.M33, offsetMatrix.M43,
                                                                   offsetMatrix.M14, offsetMatrix.M24, offsetMatrix.M34, offsetMatrix.M44);
                            boneMap[nodeIndex] = aiBone;
                        }
                        else
                        {
                            boneMap[nodeIndex].VertexWeights.Add(new Ai.VertexWeight(i, boneWeight));
                        }
                    }
                }

                aiMesh.Bones.AddRange(boneMap.Values);
            }

            return(aiMesh);
        }
Пример #11
0
        public void FillScene(Scene scene, VertexData vertData, List <Rigging.Bone> flatSkeleton, List <Matrix4> inverseBindMatrices)
        {
            for (int i = 0; i < Shapes.Count; i++)
            {
                int   vertexID = 0;
                Shape curShape = Shapes[i];

                Console.Write("Mesh " + i + ": ");
                string meshname = $"mesh_{ i }";

                switch (curShape.MatrixType)
                {
                case MatrixType.BillboardX:
                    meshname += "_BillX";
                    Console.Write("Billboarding Detected! ");
                    break;

                case MatrixType.BillboardXY:
                    meshname += "_BillXY";
                    Console.Write("Billboarding Detected! ");
                    break;

                default:
                    break;
                }

                Mesh mesh = new Mesh($"mesh_{ i }", PrimitiveType.Triangle);
                mesh.MaterialIndex = i;

                foreach (Packet pack in curShape.Packets)
                {
                    foreach (Primitive prim in pack.Primitives)
                    {
                        List <Vertex> triVertices = J3DUtility.PrimitiveToTriangles(prim);

                        for (int triIndex = 0; triIndex < triVertices.Count; triIndex += 3)
                        {
                            Face newFace = new Face(new int[] { vertexID + 2, vertexID + 1, vertexID });
                            mesh.Faces.Add(newFace);

                            for (int triVertIndex = 0; triVertIndex < 3; triVertIndex++)
                            {
                                Vertex vert = triVertices[triIndex + triVertIndex];

                                for (int j = 0; j < vert.VertexWeight.WeightCount; j++)
                                {
                                    Rigging.Bone curWeightBone = flatSkeleton[vert.VertexWeight.BoneIndices[j]];

                                    int assBoneIndex = mesh.Bones.FindIndex(x => x.Name == curWeightBone.Name);

                                    if (assBoneIndex == -1)
                                    {
                                        Assimp.Bone newBone = new Assimp.Bone();
                                        newBone.Name         = curWeightBone.Name;
                                        newBone.OffsetMatrix = curWeightBone.InverseBindMatrix.ToMatrix4x4();
                                        mesh.Bones.Add(newBone);
                                        assBoneIndex = mesh.Bones.IndexOf(newBone);
                                    }

                                    mesh.Bones[assBoneIndex].VertexWeights.Add(new VertexWeight(vertexID, vert.VertexWeight.Weights[j]));
                                }

                                OpenTK.Vector3 posVec    = vertData.Positions[(int)vert.GetAttributeIndex(GXVertexAttribute.Position)];
                                OpenTK.Vector4 openTKVec = new Vector4(posVec.X, posVec.Y, posVec.Z, 1);

                                Vector3D vertVec = new Vector3D(openTKVec.X, openTKVec.Y, openTKVec.Z);

                                if (vert.VertexWeight.WeightCount == 1)
                                {
                                    if (inverseBindMatrices.Count > vert.VertexWeight.BoneIndices[0])
                                    {
                                        Matrix4 test = inverseBindMatrices[vert.VertexWeight.BoneIndices[0]].Inverted();
                                        test.Transpose();
                                        Vector4 trans = OpenTK.Vector4.Transform(openTKVec, test);
                                        vertVec = new Vector3D(trans.X, trans.Y, trans.Z);
                                    }
                                    else
                                    {
                                        Vector4 trans = OpenTK.Vector4.Transform(openTKVec, flatSkeleton[vert.VertexWeight.BoneIndices[0]].TransformationMatrix);
                                        vertVec = new Vector3D(trans.X, trans.Y, trans.Z);
                                    }
                                }

                                mesh.Vertices.Add(vertVec);

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Normal))
                                {
                                    OpenTK.Vector3 nrmVec    = vertData.Normals[(int)vert.NormalIndex];
                                    OpenTK.Vector4 openTKNrm = new Vector4(nrmVec.X, nrmVec.Y, nrmVec.Z, 1);
                                    Vector3D       vertNrm   = new Vector3D(nrmVec.X, nrmVec.Y, nrmVec.Z);

                                    if (vert.VertexWeight.WeightCount == 1)
                                    {
                                        if (inverseBindMatrices.Count > vert.VertexWeight.BoneIndices[0])
                                        {
                                            Matrix4 test = inverseBindMatrices[vert.VertexWeight.BoneIndices[0]].Inverted();
                                            vertNrm = Vector3.TransformNormalInverse(nrmVec, test).ToVector3D();
                                        }
                                        else
                                        {
                                            Vector4 trans = OpenTK.Vector4.Transform(openTKNrm, flatSkeleton[vert.VertexWeight.BoneIndices[0]].TransformationMatrix);
                                            vertNrm = new Vector3D(trans.X, trans.Y, trans.Z);
                                        }
                                    }

                                    mesh.Normals.Add(vertNrm);
                                }

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Color0))
                                {
                                    mesh.VertexColorChannels[0].Add(vertData.Color_0[(int)vert.Color0Index].ToColor4D());
                                }

                                if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Color1))
                                {
                                    mesh.VertexColorChannels[1].Add(vertData.Color_1[(int)vert.Color1Index].ToColor4D());
                                }

                                for (int texCoordNum = 0; texCoordNum < 8; texCoordNum++)
                                {
                                    if (curShape.Descriptor.CheckAttribute(GXVertexAttribute.Tex0 + texCoordNum))
                                    {
                                        Vector3D texCoord = new Vector3D();
                                        switch (texCoordNum)
                                        {
                                        case 0:
                                            texCoord = vertData.TexCoord_0[(int)vert.TexCoord0Index].ToVector2D();
                                            break;

                                        case 1:
                                            texCoord = vertData.TexCoord_1[(int)vert.TexCoord1Index].ToVector2D();
                                            break;

                                        case 2:
                                            texCoord = vertData.TexCoord_2[(int)vert.TexCoord2Index].ToVector2D();
                                            break;

                                        case 3:
                                            texCoord = vertData.TexCoord_3[(int)vert.TexCoord3Index].ToVector2D();
                                            break;

                                        case 4:
                                            texCoord = vertData.TexCoord_4[(int)vert.TexCoord4Index].ToVector2D();
                                            break;

                                        case 5:
                                            texCoord = vertData.TexCoord_5[(int)vert.TexCoord5Index].ToVector2D();
                                            break;

                                        case 6:
                                            texCoord = vertData.TexCoord_6[(int)vert.TexCoord6Index].ToVector2D();
                                            break;

                                        case 7:
                                            texCoord = vertData.TexCoord_7[(int)vert.TexCoord7Index].ToVector2D();
                                            break;
                                        }

                                        mesh.TextureCoordinateChannels[texCoordNum].Add(texCoord);
                                    }
                                }

                                vertexID++;
                            }
                        }
                    }
                    Console.Write("...");
                }

                scene.Meshes.Add(mesh);
                Console.Write("✓");
                Console.WriteLine();
            }
        }
Пример #12
0
        private void BuildBones(Mesh mainMesh, Node rootNodeAnim)
        {
            Bone bone = new Bone();
            bone.Name = rootNodeAnim.Name;
            mainMesh.Bones.Add(bone);

            foreach (Node childNode in rootNodeAnim.Children)
                BuildBones(mainMesh, childNode);
        }
Пример #13
0
        /// <summary>
        /// internal.
        /// </summary>
        internal static Scene ConvertFromAssimp(Assimp.Scene _Scene)
        {
            Scene Result = new Scene();

            LoadTextures(_Scene);
            Result.CompileEnable = false;
            for (int i = 0; i < _Scene.Meshes.Count; i++)
            {
                D3DMesh _M = new D3DMesh();
                _M.CompileEnable = false;
                Assimp.Mesh M        = _Scene.Meshes[i];
                List <int>  _Indices = new List <int>(M.Faces.Count * 4);
                if (M.Faces.Count > 0)
                {
                    for (int j = 0; j < M.Faces.Count; j++)
                    {
                        if (M.Faces[j].Indices.Count > 4)
                        {
                            _Indices.Add(M.Faces[j].Indices[0]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[4]);
                            _Indices.Add(M.Faces[j].Indices[4]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                            _Indices.Add(M.Faces[j].Indices[4]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                            _Indices.Add(M.Faces[j].Indices[3]);
                        }
                        else
                        if (M.Faces[j].Indices.Count > 3)
                        {
                            _Indices.Add(M.Faces[j].Indices[0]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[3]);
                            _Indices.Add(M.Faces[j].Indices[3]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                        }
                        else
                        {
                            _Indices.Add(M.Faces[j].Indices[0]);
                            _Indices.Add(M.Faces[j].Indices[1]);
                            _Indices.Add(M.Faces[j].Indices[2]);
                        }
                    }
                    _M.Indices = _Indices.ToArray();
                }

                Result.Meshes.Add(_M);
                //----------------Indices--------------------

                int[] Indices = M.GetIndices();

                _M.Material = AssimpConv.ConvertMaterial(_Scene.Materials[M.MaterialIndex]);
                _M.Texture  = LoadTexture(_Scene.Materials[M.MaterialIndex]);
                List <Vector3D> Vertices = M.Vertices;
                _M.Position = new xyzf[Vertices.Count];
                for (int j = 0; j < Vertices.Count; j++)
                {
                    Vector3D V = Vertices[j];
                    _M.Position[j] = new xyzf(V.X, V.Y, V.Z);
                }
                List <Vector3D> Normals = M.Normals;
                _M.Normals = new xyzf[Normals.Count];

                for (int j = 0; j < Normals.Count; j++)
                {
                    Vector3D V = Normals[j];
                    _M.Normals[j] = new xyzf(V.X, V.Y, V.Z).normalized();
                }
                if (M.TextureCoordinateChannelCount > 0)
                {
                    _M.TextureCoords = new xyf[M.TextureCoordinateChannels[0].Count];
                    for (int j = 0; j < M.TextureCoordinateChannels[0].Count; j++)
                    {
                        Vector3D V = M.TextureCoordinateChannels[0][j];
                        _M.TextureCoords[j] = new xyf(V.X, V.Y);
                    }
                }


                _M.Bones = new List <Bone>();
                for (int k = 0; k < M.BoneCount; k++)
                {
                    Assimp.Bone    B  = M.Bones[k];
                    VertexWeight[] VW = new VertexWeight[B.VertexWeights.Count];
                    for (int g = 0; g < VW.Length; g++)
                    {
                        VW[g] = new VertexWeight(B.VertexWeights[g].VertexID, B.VertexWeights[g].Weight);
                    }
                    Bone _B = new Bone(B.Name, AssimpConv.ConvertTransform(B.OffsetMatrix), VW);
                    _M.Bones.Add(_B);
                }
            }

            LoadNode(_Scene, Result);
            MoveTranslucentAtEnd(Result);
            Result._Scene        = _Scene;
            Result.SceneAnimator = new SceneAnimator(Result);
            return(Result);
        }