コード例 #1
0
ファイル: Mesh.cs プロジェクト: LongJohnCoder/NMSMV
        public override Assimp.Node assimpExport(ref Assimp.Scene scn, ref Dictionary <int, int> meshImportStatus)
        {
            Assimp.Mesh amesh = new Assimp.Mesh();
            Assimp.Node node;
            amesh.Name = name;

            int meshHash = meshVao.GetHashCode();

            //TESTING
            if (scn.MeshCount > 20)
            {
                node = base.assimpExport(ref scn, ref meshImportStatus);
                return(node);
            }

            if (!meshImportStatus.ContainsKey(meshHash))
            //if (false)
            {
                meshImportStatus[meshHash] = scn.MeshCount;

                int          vertcount = metaData.vertrend_graphics - metaData.vertrstart_graphics + 1;
                MemoryStream vms       = new MemoryStream(gobject.meshDataDict[metaData.Hash].vs_buffer);
                MemoryStream ims       = new MemoryStream(gobject.meshDataDict[metaData.Hash].is_buffer);
                BinaryReader vbr       = new BinaryReader(vms);
                BinaryReader ibr       = new BinaryReader(ims);


                //Initialize Texture Component Channels
                if (gobject.bufInfo[1] != null)
                {
                    List <Assimp.Vector3D> textureChannel = new List <Assimp.Vector3D>();
                    amesh.TextureCoordinateChannels.Append(textureChannel);
                    amesh.UVComponentCount[0] = 2;
                }

                //Generate bones only for the joints related to the mesh
                Dictionary <int, Assimp.Bone> localJointDict = new Dictionary <int, Assimp.Bone>();

                //Export Bone Structure
                if (Skinned)
                //if (false)
                {
                    for (int i = 0; i < meshVao.BoneRemapIndicesCount; i++)
                    {
                        int joint_id = meshVao.BoneRemapIndices[i];
                        //Fetch name
                        Joint relJoint = null;

                        foreach (Joint jnt in parentScene.jointDict.Values)
                        {
                            if (jnt.jointIndex == joint_id)
                            {
                                relJoint = jnt;
                                break;
                            }
                        }

                        //Generate bone
                        Assimp.Bone b = new Assimp.Bone();
                        if (relJoint != null)
                        {
                            b.Name         = relJoint.name;
                            b.OffsetMatrix = MathUtils.convertMatrix(relJoint.invBMat);
                        }


                        localJointDict[i] = b;
                        amesh.Bones.Add(b);
                    }
                }



                //Write geometry info

                vbr.BaseStream.Seek(0, SeekOrigin.Begin);
                for (int i = 0; i < vertcount; i++)
                {
                    Assimp.Vector3D v, vN;

                    for (int j = 0; j < gobject.bufInfo.Count; j++)
                    {
                        bufInfo buf = gobject.bufInfo[j];
                        if (buf is null)
                        {
                            continue;
                        }

                        switch (buf.semantic)
                        {
                        case 0:     //vPosition
                        {
                            switch (buf.type)
                            {
                            case VertexAttribPointerType.HalfFloat:
                                uint v1 = vbr.ReadUInt16();
                                uint v2 = vbr.ReadUInt16();
                                uint v3 = vbr.ReadUInt16();
                                uint v4 = vbr.ReadUInt16();

                                //Transform vector with worldMatrix
                                v = new Assimp.Vector3D(Utils.Half.decompress(v1), Utils.Half.decompress(v2), Utils.Half.decompress(v3));
                                break;

                            case VertexAttribPointerType.Float:             //This is used in my custom vbos
                                float f1 = vbr.ReadSingle();
                                float f2 = vbr.ReadSingle();
                                float f3 = vbr.ReadSingle();
                                //Transform vector with worldMatrix
                                v = new Assimp.Vector3D(f1, f2, f3);
                                break;

                            default:
                                throw new Exception("Unimplemented Vertex Type");
                            }
                            amesh.Vertices.Add(v);
                            break;
                        }

                        case 1:     //uvPosition
                        {
                            Assimp.Vector3D uv;
                            uint            v1 = vbr.ReadUInt16();
                            uint            v2 = vbr.ReadUInt16();
                            uint            v3 = vbr.ReadUInt16();
                            uint            v4 = vbr.ReadUInt16();
                            //uint v4 = Convert.ToUInt16(vbr.ReadUInt16());
                            uv = new Assimp.Vector3D(Utils.Half.decompress(v1), Utils.Half.decompress(v2), 0.0f);

                            amesh.TextureCoordinateChannels[0].Add(uv);         //Add directly to the first channel
                            break;
                        }

                        case 2:     //nPosition
                        case 3:     //tPosition
                        {
                            switch (buf.type)
                            {
                            case (VertexAttribPointerType.Float):
                                float f1, f2, f3;
                                f1 = vbr.ReadSingle();
                                f2 = vbr.ReadSingle();
                                f3 = vbr.ReadSingle();
                                vN = new Assimp.Vector3D(f1, f2, f3);
                                break;

                            case (VertexAttribPointerType.HalfFloat):
                                uint v1, v2, v3;
                                v1 = vbr.ReadUInt16();
                                v2 = vbr.ReadUInt16();
                                v3 = vbr.ReadUInt16();
                                vN = new Assimp.Vector3D(Utils.Half.decompress(v1), Utils.Half.decompress(v2), Utils.Half.decompress(v3));
                                break;

                            case (VertexAttribPointerType.Int2101010Rev):
                                int    i1, i2, i3;
                                uint   value;
                                byte[] a32 = new byte[4];
                                a32 = vbr.ReadBytes(4);

                                value = BitConverter.ToUInt32(a32, 0);
                                //Convert Values
                                i1 = _2sComplement.toInt((value >> 00) & 0x3FF, 10);
                                i2 = _2sComplement.toInt((value >> 10) & 0x3FF, 10);
                                i3 = _2sComplement.toInt((value >> 20) & 0x3FF, 10);
                                //int i4 = _2sComplement.toInt((value >> 30) & 0x003, 10);
                                float norm = (float)Math.Sqrt(i1 * i1 + i2 * i2 + i3 * i3);

                                vN = new Assimp.Vector3D(Convert.ToSingle(i1) / norm,
                                                         Convert.ToSingle(i2) / norm,
                                                         Convert.ToSingle(i3) / norm);

                                //Debug.WriteLine(vN);
                                break;

                            default:
                                throw new Exception("UNIMPLEMENTED NORMAL TYPE. PLEASE REPORT");
                            }

                            if (j == 2)
                            {
                                amesh.Normals.Add(vN);
                            }
                            else if (j == 3)
                            {
                                amesh.Tangents.Add(vN);
                                amesh.BiTangents.Add(new Assimp.Vector3D(0.0f, 0.0f, 1.0f));
                            }
                            break;
                        }

                        case 4:               //bPosition
                            vbr.ReadBytes(4); // skip
                            break;

                        case 5:     //BlendIndices + BlendWeights
                        {
                            int[]   joint_ids = new int[4];
                            float[] weights   = new float[4];

                            for (int k = 0; k < 4; k++)
                            {
                                joint_ids[k] = vbr.ReadByte();
                            }


                            for (int k = 0; k < 4; k++)
                            {
                                weights[k] = Utils.Half.decompress(vbr.ReadUInt16());
                            }

                            if (Skinned)
                            //if (false)
                            {
                                for (int k = 0; k < 4; k++)
                                {
                                    int joint_id = joint_ids[k];

                                    Assimp.VertexWeight vw = new Assimp.VertexWeight();
                                    vw.VertexID = i;
                                    vw.Weight   = weights[k];
                                    localJointDict[joint_id].VertexWeights.Add(vw);
                                }
                            }


                            break;
                        }

                        case 6:
                            break;     //Handled by 5

                        default:
                        {
                            throw new Exception("UNIMPLEMENTED BUF Info. PLEASE REPORT");
                            break;
                        }
                        }
                    }
                }

                //Export Faces
                //Get indices
                ibr.BaseStream.Seek(0, SeekOrigin.Begin);
                bool start  = false;
                int  fstart = 0;
                for (int i = 0; i < metaData.batchcount / 3; i++)
                {
                    int f1, f2, f3;
                    //NEXT models assume that all gstream meshes have uint16 indices
                    f1 = ibr.ReadUInt16();
                    f2 = ibr.ReadUInt16();
                    f3 = ibr.ReadUInt16();

                    if (!start && this.type != TYPES.COLLISION)
                    {
                        fstart = f1; start = true;
                    }
                    else if (!start && this.type == TYPES.COLLISION)
                    {
                        fstart = 0; start = true;
                    }

                    int f11, f22, f33;
                    f11 = f1 - fstart;
                    f22 = f2 - fstart;
                    f33 = f3 - fstart;


                    Assimp.Face face = new Assimp.Face();
                    face.Indices.Add(f11);
                    face.Indices.Add(f22);
                    face.Indices.Add(f33);


                    amesh.Faces.Add(face);
                }

                scn.Meshes.Add(amesh);
            }

            node = base.assimpExport(ref scn, ref meshImportStatus);
            node.MeshIndices.Add(meshImportStatus[meshHash]);

            return(node);
        }
コード例 #2
0
        protected override void ConvertGeometry(IGeometry iGeometry, ref Matrix4x4 nodeWorldTransform)
        {
            if (iGeometry.Format != GeometryFormat.Basic && iGeometry.Format != GeometryFormat.BasicDX)
            {
                throw new InvalidOperationException();
            }

            var geometry         = ( Geometry )iGeometry;
            var materialIndexMap = new int[Math.Max(1, geometry.Materials.Length)];

            if (geometry.HasMaterials)
            {
                for (var i = 0; i < geometry.Materials.Length; i++)
                {
                    // Convert material
                    var material = geometry.Materials[i];
                    if (!mConvertedMaterialCache.TryGetValue(material, out var aiMaterialIndex))
                    {
                        var textureName = material.UseTexture ? FormatTextureName(material.TextureId) : null;
                        var aiMaterial  = CreateMaterial(material.Diffuse, material.Specular, Color.Gray, textureName, material.ClampU,
                                                         material.ClampV, material.FlipU, material.FlipV, material.UseAlpha);

                        aiMaterialIndex = Scene.MaterialCount;
                        Scene.Materials.Add(aiMaterial);
                        mConvertedMaterialCache[material] = aiMaterialIndex;
                    }

                    materialIndexMap[i] = aiMaterialIndex;
                }
            }
            else
            {
                materialIndexMap[0] = GetNoMaterialMaterialIndex();
            }

            foreach (var mesh in geometry.Meshes)
            {
                var aiMesh = new Assimp.Mesh();

                // Convert mesh
                var hasNormals      = geometry.HasNormals || mesh.HasNormals;
                var triangleIndices = mesh.ToTriangles();
                var vertices        = new List <Vertex>();
                for (var i = 0; i < triangleIndices.Length; i += 3)
                {
                    var aiFace = new Assimp.Face();

                    for (int j = 0; j < 3; j++)
                    {
                        var index  = triangleIndices[i + j];
                        var vertex = new Vertex {
                            Position = geometry.VertexPositions[index.VertexIndex]
                        };

                        if (hasNormals)
                        {
                            vertex.Normal = geometry.HasNormals ? geometry.VertexNormals[index.VertexIndex] : index.Normal;
                        }

                        if (mesh.HasColors)
                        {
                            vertex.Color = index.Color;
                        }

                        if (mesh.HasUVs)
                        {
                            vertex.UV = UVCodec.Decode255(index.UV);
                        }

                        var vertexIndex = vertices.IndexOf(vertex);
                        if (vertexIndex == -1)
                        {
                            vertexIndex = vertices.Count;
                            vertices.Add(vertex);
                        }

                        aiFace.Indices.Add(vertexIndex);
                    }

                    aiMesh.Faces.Add(aiFace);
                }

                aiMesh.Vertices.AddRange(vertices.Select(x => ToAssimp(x.Position)));

                if (hasNormals)
                {
                    aiMesh.Normals.AddRange(vertices.Select(x => ToAssimp(x.Normal)));
                }

                if (mesh.HasColors)
                {
                    aiMesh.VertexColorChannels[0].AddRange(vertices.Select(x => ToAssimp(x.Color)));
                }

                if (mesh.HasUVs)
                {
                    aiMesh.TextureCoordinateChannels[0].AddRange(vertices.Select(x => ToAssimp(x.UV)));
                }

                // Set mesh material index
                aiMesh.MaterialIndex = materialIndexMap[Math.Min(mesh.MaterialId, materialIndexMap.Length - 1)];

                // Add mesh to scene
                Scene.Meshes.Add(aiMesh);
            }
        }
コード例 #3
0
        private void ConvertMeshes(List <Mesh> meshes, VertexPositionBuffer positionBuffer, VertexNormalBuffer normalBuffer, VertexColorBuffer colorBuffer, VertexUVBuffer uvBuffer)
        {
            var state = new MeshRenderState();

            for (var i = 0; i < meshes.Count; i++)
            {
                var mesh = meshes[i];

                if (mesh.Parameters != null && mesh.Parameters.Count > 0)
                {
                    ProcessMeshParameters(mesh.Parameters, ref state);
                }

                var stateCopy = state;
                stateCopy.TextureId = 0;
                stateCopy.TileMode  = 0;
                //stateCopy.IndexFlags = 0;
                stateCopy.AmbientColor = new Color();
                sUniqueStates.Add(stateCopy);

                var aiMesh      = new Assimp.Mesh();
                var vertexCache = new List <Vertex>();

                Debug.Assert(state.IndexFlags.HasFlag(IndexAttributeFlags.HasPosition) ? positionBuffer != null : true);
                Debug.Assert(state.IndexFlags.HasFlag(IndexAttributeFlags.HasNormal) ? normalBuffer != null : true);
                Debug.Assert(state.IndexFlags.HasFlag(IndexAttributeFlags.HasColor) ? colorBuffer != null : true);
                Debug.Assert(state.IndexFlags.HasFlag(IndexAttributeFlags.HasUV) ? uvBuffer != null : true);

                // Extract all vertices used by the triangles, and build a new vertex list
                // with each vertex attribute clumped together
                var aiFace = new Assimp.Face();
                foreach (var index in mesh.DisplayLists.SelectMany(x => x.ToTriangles()))
                {
                    var vertex = new Vertex();

                    if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasPosition))
                    {
                        vertex.Position = positionBuffer.Elements[index.PositionIndex];
                    }

                    if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasNormal))
                    {
                        vertex.Normal = normalBuffer.Elements[index.NormalIndex];
                    }

                    if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasColor))
                    {
                        vertex.Color = colorBuffer.Elements[index.ColorIndex];
                    }

                    if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasUV))
                    {
                        vertex.UV = uvBuffer.Elements[index.UVIndex];
                    }

                    // Find index of this vertex in the list in case it already exists
                    var vertexIndex = vertexCache.IndexOf(vertex);
                    if (vertexIndex == -1)
                    {
                        vertexIndex = vertexCache.Count;
                        vertexCache.Add(vertex);
                    }

                    aiFace.Indices.Add(vertexIndex);

                    if (aiFace.IndexCount == 3)
                    {
                        // Done with this face, move on to the next one
                        aiMesh.Faces.Add(aiFace);
                        aiFace = new Assimp.Face();
                    }
                }

                // Convert vertices
                aiMesh.Vertices.AddRange(vertexCache.Select(x => ToAssimp(x.Position)));

                if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasNormal))
                {
                    aiMesh.Normals.AddRange(vertexCache.Select(x => ToAssimp(x.Normal)));
                }

                if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasUV))
                {
                    aiMesh.TextureCoordinateChannels[0].AddRange(vertexCache.Select(x => ToAssimp(UVCodec.Decode1023(x.UV))));
                }

                if (state.IndexFlags.HasFlag(IndexAttributeFlags.HasColor))
                {
                    aiMesh.VertexColorChannels[0].AddRange(vertexCache.Select(x => ToAssimp(x.Color)));
                }

                // Convert material
                if (!mConvertedMaterialCache.TryGetValue(state, out var aiMaterialIndex))
                {
                    // Not in cache, so create a new one and add it
                    aiMaterialIndex = Scene.MaterialCount;
                    Scene.Materials.Add(CreateMaterial(Color.Gray, Color.Gray, Color.Gray, FormatTextureName(state.TextureId), false, false,
                                                       state.TileMode.HasFlag(TileMode.MirrorU),
                                                       state.TileMode.HasFlag(TileMode.MirrorV),
                                                       state.BlendAlphaFlags.HasFlag(BlendAlphaFlags.UseAlpha)));

                    mConvertedMaterialCache[state] = aiMaterialIndex;
                }

                aiMesh.MaterialIndex = aiMaterialIndex;

                // Add mesh to scene.
                Scene.Meshes.Add(aiMesh);
            }
        }
コード例 #4
0
ファイル: RWClumpNode.cs プロジェクト: zarroboogs/Amicitia
        public static Assimp.Scene ToAssimpScene(RwClumpNode clumpNode)
        {
            // Scene
            var aiScene = new Assimp.Scene();

            // RootNode
            var rootFrame  = clumpNode.FrameList[0];
            var aiRootNode = new Assimp.Node("RootNode", null);

            aiRootNode.Transform = new Assimp.Matrix4x4(rootFrame.Transform.M11, rootFrame.Transform.M21, rootFrame.Transform.M31, rootFrame.Transform.M41,
                                                        rootFrame.Transform.M12, rootFrame.Transform.M22, rootFrame.Transform.M32, rootFrame.Transform.M42,
                                                        rootFrame.Transform.M13, rootFrame.Transform.M23, rootFrame.Transform.M33, rootFrame.Transform.M43,
                                                        rootFrame.Transform.M14, rootFrame.Transform.M24, rootFrame.Transform.M34, rootFrame.Transform.M44);

            aiScene.RootNode = aiRootNode;

            for (int i = 1; i < clumpNode.FrameList.Count; i++)
            {
                var frame     = clumpNode.FrameList[i];
                var frameName = "_" + frame.HAnimFrameExtensionNode.NameId;

                Assimp.Node aiParentNode = null;
                if (frame.Parent != null)
                {
                    string parentName = "RootNode";
                    if (frame.Parent.HasHAnimExtension)
                    {
                        parentName = "_" + frame.Parent.HAnimFrameExtensionNode.NameId;
                    }

                    aiParentNode = aiRootNode.FindNode(parentName);
                }

                var aiNode = new Assimp.Node(frameName, aiParentNode);
                aiNode.Transform = new Assimp.Matrix4x4(frame.Transform.M11, frame.Transform.M21, frame.Transform.M31, frame.Transform.M41,
                                                        frame.Transform.M12, frame.Transform.M22, frame.Transform.M32, frame.Transform.M42,
                                                        frame.Transform.M13, frame.Transform.M23, frame.Transform.M33, frame.Transform.M43,
                                                        frame.Transform.M14, frame.Transform.M24, frame.Transform.M34, frame.Transform.M44);
                aiParentNode.Children.Add(aiNode);
            }

            // Meshes, Materials
            for (int atomicIndex = 0; atomicIndex < clumpNode.Atomics.Count; atomicIndex++)
            {
                var atomic   = clumpNode.Atomics[atomicIndex];
                var geometry = clumpNode.GeometryList[atomic.GeometryIndex];
                var frame    = clumpNode.FrameList[atomic.FrameIndex];

                var aiNodeName          = $"Atomic{atomicIndex}";
                var aiNode              = new Assimp.Node(aiNodeName, aiScene.RootNode);
                var frameWorldTransform = frame.WorldTransform;
                aiNode.Transform = new Assimp.Matrix4x4(frameWorldTransform.M11, frameWorldTransform.M21, frameWorldTransform.M31, frameWorldTransform.M41,
                                                        frameWorldTransform.M12, frameWorldTransform.M22, frameWorldTransform.M32, frameWorldTransform.M42,
                                                        frameWorldTransform.M13, frameWorldTransform.M23, frameWorldTransform.M33, frameWorldTransform.M43,
                                                        frameWorldTransform.M14, frameWorldTransform.M24, frameWorldTransform.M34, frameWorldTransform.M44);
                aiScene.RootNode.Children.Add(aiNode);

                bool hasVertexWeights = geometry.SkinNode != null;

                for (int meshIndex = 0; meshIndex < geometry.MeshListNode.MaterialMeshes.Length; meshIndex++)
                {
                    var mesh   = geometry.MeshListNode.MaterialMeshes[meshIndex];
                    var aiMesh = new Assimp.Mesh($"Atomic{atomicIndex}_Geometry{atomic.GeometryIndex}_Mesh{meshIndex}", Assimp.PrimitiveType.Triangle);

                    // get triangle list indices
                    int[] indices;

                    if (geometry.MeshListNode.PrimitiveType == RwPrimitiveType.TriangleList)
                    {
                        indices = mesh.Indices;
                    }
                    else
                    {
                        indices = MeshUtilities.ToTriangleList(mesh.Indices, false);
                    }

                    // Faces
                    for (int i = 0; i < indices.Length; i += 3)
                    {
                        var faceIndices = new[] { i, i + 1, i + 2 };
                        var aiFace      = new Assimp.Face(faceIndices);
                        aiMesh.Faces.Add(aiFace);
                    }

                    // TextureCoordinateChannels, VertexColorChannels, Vertices, MaterialIndex, Normals
                    for (int triIdx = 0; triIdx < indices.Length; triIdx += 3)
                    {
                        for (int triVertIdx = 0; triVertIdx < 3; triVertIdx++)
                        {
                            int vertexIndex = indices[triIdx + triVertIdx];

                            // TextureCoordinateChannels
                            if (geometry.HasTextureCoordinates)
                            {
                                for (int channelIdx = 0; channelIdx < geometry.TextureCoordinateChannelCount; channelIdx++)
                                {
                                    var textureCoordinate   = geometry.TextureCoordinateChannels[channelIdx][vertexIndex];
                                    var aiTextureCoordinate = new Assimp.Vector3D(textureCoordinate.X, textureCoordinate.Y, 0f);
                                    aiMesh.TextureCoordinateChannels[channelIdx].Add(aiTextureCoordinate);
                                }
                            }

                            // VertexColorChannels
                            if (geometry.HasColors)
                            {
                                var color   = geometry.Colors[vertexIndex];
                                var aiColor = new Assimp.Color4D(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
                                aiMesh.VertexColorChannels[0].Add(aiColor);
                            }

                            // Vertices
                            if (geometry.HasVertices)
                            {
                                var vertex   = geometry.Vertices[vertexIndex];
                                var aiVertex = new Assimp.Vector3D(vertex.X, vertex.Y, vertex.Z);
                                aiMesh.Vertices.Add(aiVertex);
                            }

                            // Normals
                            if (geometry.HasNormals)
                            {
                                var normal   = geometry.Normals[vertexIndex];
                                var aiNormal = new Assimp.Vector3D(normal.X, normal.Y, normal.Z);
                                aiMesh.Normals.Add(aiNormal);
                            }
                        }
                    }

                    // Bones
                    if (hasVertexWeights)
                    {
                        var skinNode  = geometry.SkinNode;
                        var aiBoneMap = new Dictionary <int, Assimp.Bone>();

                        for (int i = 0; i < indices.Length; i++)
                        {
                            var vertexIndex     = indices[i];
                            int realVertexIndex = i;

                            for (int j = 0; j < 4; j++)
                            {
                                var boneIndex  = skinNode.VertexBoneIndices[vertexIndex][j];
                                var boneWeight = skinNode.VertexBoneWeights[vertexIndex][j];

                                if (boneWeight == 0.0f)
                                {
                                    continue;
                                }

                                if (!aiBoneMap.Keys.Contains(boneIndex))
                                {
                                    var aiBone    = new Assimp.Bone();
                                    var boneFrame = clumpNode.FrameList.GetFrameByHierarchyIndex(boneIndex);

                                    aiBone.Name = boneFrame.HasHAnimExtension ? "_" + boneFrame.HAnimFrameExtensionNode.NameId : "RootNode";
                                    aiBone.VertexWeights.Add(new Assimp.VertexWeight(realVertexIndex, boneWeight));

                                    Matrix4x4.Invert(frame.WorldTransform, out Matrix4x4 invertedFrameWorldTransform);
                                    Matrix4x4.Invert(boneFrame.WorldTransform * invertedFrameWorldTransform, out Matrix4x4 offsetMatrix);
                                    aiBone.OffsetMatrix = new Assimp.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);
                                    aiBoneMap[boneIndex] = aiBone;
                                }

                                if (!aiBoneMap[boneIndex].VertexWeights.Any(x => x.VertexID == realVertexIndex))
                                {
                                    aiBoneMap[boneIndex].VertexWeights.Add(new Assimp.VertexWeight(realVertexIndex, boneWeight));
                                }
                            }
                        }

                        aiMesh.Bones.AddRange(aiBoneMap.Values);
                    }
                    else
                    {
                        var aiBone = new Assimp.Bone();

                        // Name
                        aiBone.Name = frame.HasHAnimExtension ? "_" + frame.HAnimFrameExtensionNode.NameId : "RootNode";

                        // VertexWeights
                        for (int i = 0; i < aiMesh.Vertices.Count; i++)
                        {
                            var aiVertexWeight = new Assimp.VertexWeight(i, 1f);
                            aiBone.VertexWeights.Add(aiVertexWeight);
                        }

                        // OffsetMatrix

                        /*
                         * Matrix4x4.Invert( frame.WorldTransform, out Matrix4x4 offsetMatrix );
                         * aiBone.OffsetMatrix = new Assimp.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 );
                         */
                        aiBone.OffsetMatrix = Assimp.Matrix4x4.Identity;

                        aiMesh.Bones.Add(aiBone);
                    }

                    var material   = geometry.Materials[mesh.MaterialIndex];
                    var aiMaterial = new Assimp.Material();

                    if (material.IsTextured)
                    {
                        // TextureDiffuse
                        var texture = material.TextureReferenceNode;
                        aiMaterial.TextureDiffuse = new Assimp.TextureSlot(
                            texture.Name + ".png", Assimp.TextureType.Diffuse, 0, Assimp.TextureMapping.FromUV, 0, 0, Assimp.TextureOperation.Add, Assimp.TextureWrapMode.Wrap, Assimp.TextureWrapMode.Wrap, 0);
                    }

                    // Name
                    aiMaterial.Name = material.Name ?? $"Geometry{atomic.GeometryIndex}_Material{mesh.MaterialIndex}";
                    if (material.IsTextured && material.Name == null)
                    {
                        aiMaterial.Name = material.TextureReferenceNode.Name;
                    }

                    aiMaterial.ShadingMode = Assimp.ShadingMode.Phong;

                    // Add mesh to meshes
                    aiScene.Meshes.Add(aiMesh);

                    // Add material to materials
                    aiScene.Materials.Add(aiMaterial);

                    // MaterialIndex
                    aiMesh.MaterialIndex = aiScene.Materials.Count - 1;

                    // Add mesh index to node
                    aiNode.MeshIndices.Add(aiScene.Meshes.Count - 1);
                }
            }

            return(aiScene);
        }
コード例 #5
0
ファイル: Model.cs プロジェクト: TGEnigma/SAModelTools
        public void ExportCollada(string filepath)
        {
            var aiScene = AssimpHelper.CreateDefaultScene();

            foreach (var geometry in Geometries)
            {
                for (var meshIndex = 0; meshIndex < geometry.Meshes.Count; meshIndex++)
                {
                    var aiMeshNode = new Assimp.Node(geometry.Meshes.Count > 1 ? $"{geometry.Name}_mesh_{meshIndex}" : geometry.Name,
                                                     aiScene.RootNode);
                    aiScene.RootNode.Children.Add(aiMeshNode);

                    var mesh   = geometry.Meshes[meshIndex];
                    var aiMesh = new Assimp.Mesh();

                    var aiMaterial = new Assimp.Material
                    {
                        Name = mesh.Material.Name,
                        //ColorDiffuse      = AssimpHelper.ToAssimp( mesh.Material.Diffuse ),
                        //ColorSpecular     = AssimpHelper.ToAssimp( mesh.Material.Specular ),
                        //ColorAmbient      = AssimpHelper.ToAssimp( mesh.Material.Ambient ),
                        Shininess         = 0,
                        ShininessStrength = 0,
                        Reflectivity      = 0,
                        TextureDiffuse    = new Assimp.TextureSlot
                        {
                            TextureType = Assimp.TextureType.Diffuse,
                            FilePath    = mesh.Material.TextureName,
                            WrapModeU   = Assimp.TextureWrapMode.Wrap,
                            WrapModeV   = Assimp.TextureWrapMode.Wrap,
                        }
                    };

                    aiMesh.MaterialIndex = aiScene.MaterialCount;
                    aiScene.Materials.Add(aiMaterial);

                    foreach (var vertex in mesh.Vertices)
                    {
                        aiMesh.Vertices.Add(AssimpHelper.ToAssimp(vertex.Position));
                        aiMesh.Normals.Add(AssimpHelper.ToAssimp(vertex.Normal));
                        aiMesh.VertexColorChannels[0].Add(AssimpHelper.ToAssimp(vertex.Color));
                        aiMesh.TextureCoordinateChannels[0].Add(AssimpHelper.ToAssimp(vertex.UV));
                    }

                    for (int i = 0; i < mesh.Indices.Length; i += 3)
                    {
                        var aiFace = new Assimp.Face();
                        for (int j = 0; j < 3; j++)
                        {
                            aiFace.Indices.Add(mesh.Indices[i + j]);
                        }

                        aiMesh.Faces.Add(aiFace);
                    }

                    aiMeshNode.MeshIndices.Add(aiScene.MeshCount);
                    aiScene.Meshes.Add(aiMesh);
                }
            }

            AssimpHelper.ExportCollada(aiScene, filepath);
        }