Esempio n. 1
0
        public static void Open(string FileName, SBScene Scene)
        {
            ISSBH_File File;

            if (SSBH.TryParseSSBHFile(FileName, out File))
            {
                if (File is MESH mesh)
                {
                    if (mesh.VersionMajor != 1 && mesh.VersionMinor != 10)
                    {
                        SBConsole.WriteLine($"Mesh Version {mesh.VersionMajor}.{mesh.VersionMinor} not supported");
                        return;
                    }
                    if (mesh.UnknownOffset != 0 || mesh.UnknownSize != 0)
                    {
                        SBConsole.WriteLine($"Warning: Unknown Mesh format detected");
                    }

                    SBUltimateModel model = new SBUltimateModel();
                    model.Name           = mesh.ModelName;
                    model.BoundingSphere = new Vector4(mesh.BoundingSphereX, mesh.BoundingSphereY, mesh.BoundingSphereZ, mesh.BoundingSphereRadius);

                    ((SBSceneSSBH)Scene).Model = model;

                    SSBHVertexAccessor accessor = new SSBHVertexAccessor(mesh);
                    {
                        foreach (var meshObject in mesh.Objects)
                        {
                            SBUltimateMesh sbMesh = new SBUltimateMesh();
                            foreach (var attr in meshObject.Attributes)
                            {
                                foreach (var atstring in attr.AttributeStrings)
                                {
                                    UltimateVertexAttribute at;
                                    if (Enum.TryParse(atstring.Name, out at))
                                    {
                                        sbMesh.EnableAttribute(at);
                                    }
                                }
                            }
                            sbMesh.Name       = meshObject.Name;
                            sbMesh.ParentBone = meshObject.ParentBoneName;

                            sbMesh.BoundingSphere = new BoundingSphere(meshObject.BoundingSphereX, meshObject.BoundingSphereY, meshObject.BoundingSphereZ, meshObject.BoundingSphereRadius);
                            sbMesh.AABoundingBox  = new AABoundingBox(new Vector3(meshObject.MinBoundingBoxX, meshObject.MinBoundingBoxY, meshObject.MinBoundingBoxZ),
                                                                      new Vector3(meshObject.MaxBoundingBoxX, meshObject.MaxBoundingBoxY, meshObject.MaxBoundingBoxZ));
                            sbMesh.OrientedBoundingBox = new OrientedBoundingBox(new Vector3(meshObject.OBBCenterX, meshObject.OBBCenterY, meshObject.OBBCenterZ),
                                                                                 new Vector3(meshObject.OBBSizeX, meshObject.OBBSizeY, meshObject.OBBSizeZ),
                                                                                 new Matrix3(meshObject.M11, meshObject.M12, meshObject.M13,
                                                                                             meshObject.M21, meshObject.M22, meshObject.M23,
                                                                                             meshObject.M31, meshObject.M32, meshObject.M33));

                            sbMesh.Indices  = new List <uint>(accessor.ReadIndices(0, meshObject.IndexCount, meshObject));
                            sbMesh.Vertices = CreateVertices(mesh, Scene.Skeleton, meshObject, accessor, sbMesh.Indices.ToArray());
                            model.Meshes.Add(sbMesh);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        public RModel GetRenderModel(RSkeleton Skeleton = null)
        {
            RModel model = new RModel();

            // The bounding sphere containing all meshes.
            var modelSphere = mesh.GetBoundingSphere();

            model.BoundingSphere = new Vector4(modelSphere.Item1, modelSphere.Item2, modelSphere.Item3, modelSphere.Item4);

            foreach (MeshObject meshObject in mesh.Objects)
            {
                PrintAttributeInformation(meshObject);

                RMesh rMesh = new RMesh
                {
                    Name           = meshObject.Name,
                    SingleBindName = meshObject.ParentBoneName,
                };

                // Get bounding sphere.
                var sphere = meshObject.GetBoundingSphere();
                rMesh.BoundingSphere = new Vector4(sphere.Item1, sphere.Item2, sphere.Item3, sphere.Item4);

                // Get vertex data.
                var vertexAccessor           = new SSBHVertexAccessor(mesh);
                var vertexIndices            = vertexAccessor.ReadIndices(0, meshObject.IndexCount, meshObject);
                List <CustomVertex> vertices = CreateVertices(Skeleton, meshObject, vertexAccessor, vertexIndices);

                rMesh.RenderMesh = new RenderMesh(vertices, new List <uint>(vertexIndices));

                model.subMeshes.Add(rMesh);
            }

            return(model);
        }
Esempio n. 3
0
        public static void Open(string FileName, SBScene Scene)
        {
            ISSBH_File File;

            if (SSBH.TryParseSSBHFile(FileName, out File))
            {
                if (File is MESH mesh)
                {
                    if (mesh.VersionMajor != 1 && mesh.VersionMinor != 10)
                    {
                        SBConsole.WriteLine($"Mesh Version {mesh.VersionMajor}.{mesh.VersionMinor} not supported");
                        return;
                    }
                    if (mesh.UnknownOffset != 0 || mesh.UnknownSize != 0)
                    {
                        SBConsole.WriteLine($"Warning: Unknown Mesh format detected");
                    }

                    SBUltimateModel model = new SBUltimateModel();
                    model.Name           = mesh.ModelName;
                    model.BoundingSphere = new Vector4(mesh.BoundingSphereX, mesh.BoundingSphereY, mesh.BoundingSphereZ, mesh.BoundingSphereRadius / 2);

                    Vector3 min = new Vector3(mesh.MinBoundingBoxX, mesh.MinBoundingBoxY, mesh.MinBoundingBoxZ);
                    Vector3 max = new Vector3(mesh.MaxBoundingBoxX, mesh.MaxBoundingBoxY, mesh.MaxBoundingBoxZ);

                    model.VolumeCenter = (max + min) / 2;
                    model.VolumeSize   = (max - min) / 2;

                    ((SBSceneSSBH)Scene).Model = model;

                    using (SSBHVertexAccessor accessor = new SSBHVertexAccessor(mesh))
                    {
                        foreach (var meshObject in mesh.Objects)
                        {
                            SBUltimateMesh <UltimateVertex> sbMesh = new SBUltimateMesh <UltimateVertex>();
                            foreach (var attr in meshObject.Attributes)
                            {
                                foreach (var atstring in attr.AttributeStrings)
                                {
                                    MESHAttribute at;
                                    if (Enum.TryParse <MESHAttribute>(atstring.Name, out at))
                                    {
                                        //SBConsole.WriteLine("\tLoaded:" + at.ToString());
                                        sbMesh.ExportAttributes.Add(at);
                                    }
                                }
                            }
                            sbMesh.Name           = meshObject.Name;
                            sbMesh.BoundingSphere = new Vector4(meshObject.BoundingSphereX, meshObject.BoundingSphereY, meshObject.BoundingSphereZ, meshObject.BoundingSphereRadius);
                            sbMesh.ParentBone     = meshObject.ParentBoneName;

                            sbMesh.Indices  = new List <uint>(accessor.ReadIndices(0, meshObject.IndexCount, meshObject));
                            sbMesh.Vertices = CreateVertices(mesh, Scene.Skeleton, meshObject, accessor, sbMesh.Indices.ToArray());
                            model.Meshes.Add(sbMesh);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        private RenderMesh GetRenderMesh(RSkeleton Skeleton, MeshObject meshObject, RMesh rMesh)
        {
            var vertexAccessor = new SSBHVertexAccessor(mesh);
            {
                var vertexIndices = vertexAccessor.ReadIndices(0, meshObject.IndexCount, meshObject);

                System.Diagnostics.Debug.WriteLine($"Vertex Count: {vertexIndices.Length}");

                List <CustomVertex> vertices = CreateVertices(Skeleton, meshObject, vertexAccessor, vertexIndices);

                /*if(obs.IndexOf(meshObject) != 0x2B && ExtendedMesh != null && ExtendedMesh.MeshToIndexBuffer.ContainsKey(obs.IndexOf(meshObject)))
                 * {
                 *  rMesh.RenderMesh = new RenderMesh(vertices, new List<uint>(ExtendedMesh.MeshToIndexBuffer[obs.IndexOf(meshObject)]), PrimitiveType.TriangleFan);
                 * }
                 * else*/
                return(new RenderMesh(vertices, new List <uint>(vertexIndices)));
            }
        }
Esempio n. 5
0
        private List <CustomVertex> CreateVertices(RSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices)
        {
            // Read attribute values.
            var positions       = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject);
            var normals         = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject);
            var tangents        = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject);
            var map1Values      = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject);
            var bake1Values     = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject);
            var colorSet1Values = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject);
            var colorSet5Values = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject);


            Vector3[] generatedBitangents = GenerateBitangents(vertexIndices, positions, map1Values);

            var boneIndices = new IVec4[positions.Length];
            var boneWeights = new Vector4[positions.Length];

            var riggingAccessor = new SSBHRiggingAccessor(mesh);

            SSBHVertexInfluence[]    influences      = riggingAccessor.ReadRiggingBuffer(meshObject.Name, (int)meshObject.SubMeshIndex);
            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (Skeleton != null)
            {
                for (int i = 0; i < Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(Skeleton.Bones[i].Name, i);
                }
            }

            foreach (SSBHVertexInfluence influence in influences)
            {
                // Some influences refer to bones that don't exist in the skeleton.
                // _eff bones?
                if (!indexByBoneName.ContainsKey(influence.BoneName))
                {
                    continue;
                }

                if (boneWeights[influence.VertexIndex].X == 0)
                {
                    boneIndices[influence.VertexIndex].X = indexByBoneName[influence.BoneName];
                    boneWeights[influence.VertexIndex].X = influence.Weight;
                }
                else if (boneWeights[influence.VertexIndex].Y == 0)
                {
                    boneIndices[influence.VertexIndex].Y = indexByBoneName[influence.BoneName];
                    boneWeights[influence.VertexIndex].Y = influence.Weight;
                }
                else if (boneWeights[influence.VertexIndex].Z == 0)
                {
                    boneIndices[influence.VertexIndex].Z = indexByBoneName[influence.BoneName];
                    boneWeights[influence.VertexIndex].Z = influence.Weight;
                }
                else if (boneWeights[influence.VertexIndex].W == 0)
                {
                    boneIndices[influence.VertexIndex].W = indexByBoneName[influence.BoneName];
                    boneWeights[influence.VertexIndex].W = influence.Weight;
                }
            }

            var vertices = new List <CustomVertex>();

            for (int i = 0; i < positions.Length; i++)
            {
                var position = GetVector4(positions[i]).Xyz;

                var normal    = GetVector4(normals[i]).Xyz;
                var tangent   = GetVector4(tangents[i]).Xyz;
                var bitangent = GetBitangent(generatedBitangents, i, normal);

                var map1 = GetVector4(map1Values[i]).Xy;

                var bones   = boneIndices[i];
                var weights = boneWeights[i];

                // Accessors return length 0 when the attribute isn't present.
                var bake1 = new Vector2(0);
                if (bake1Values.Length != 0)
                {
                    bake1 = GetVector4(bake1Values[i]).Xy;
                }

                // The values are read as float, so we can't use OpenGL to convert.
                // Convert the range [0, 128] to [0, 255].
                var colorSet1 = new Vector4(1);
                if (colorSet1Values.Length != 0)
                {
                    colorSet1 = GetVector4(colorSet1Values[i]) / 128.0f;
                }

                var colorSet5 = new Vector4(1);
                if (colorSet5Values.Length != 0)
                {
                    colorSet5 = GetVector4(colorSet5Values[i]) / 128.0f;
                }

                vertices.Add(new CustomVertex(position, normal, tangent, bitangent, map1, bones, weights, bake1, colorSet1, colorSet5));
            }

            return(vertices);
        }
Esempio n. 6
0
        private static List <UltimateVertex> CreateVertices(MESH mesh, ISBSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices)
        {
            // Read attribute values.
            var positions       = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject);
            var normals         = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject);
            var tangents        = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject);
            var map1Values      = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject);
            var uvSetValues     = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject);
            var uvSet1Values    = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject);
            var bake1Values     = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject);
            var colorSet1Values = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject);
            var colorSet5Values = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject);

            var generatedBitangents = GenerateBitangents(vertexIndices, positions, map1Values);

            var riggingAccessor = new SSBHRiggingAccessor(mesh);
            var influences      = riggingAccessor.ReadRiggingBuffer(meshObject.Name, (int)meshObject.SubMeshIndex);
            var indexByBoneName = new Dictionary <string, int>();

            if (Skeleton != null)
            {
                var Bones = Skeleton.Bones;
                for (int i = 0; i < Bones.Length; i++)
                {
                    indexByBoneName.Add(Bones[i].Name, i);
                }
            }

            GetRiggingData(positions, influences, indexByBoneName, out IVec4[] boneIndices, out Vector4[] boneWeights);
Esempio n. 7
0
        public IOModel GetIOModel()
        {
            IOModel outModel = new IOModel();

            MESH meshFile = null;

            foreach (FileNode n in Parent.Nodes)
            {
                if (n.Text.Equals(_model.MeshString))
                {
                    meshFile = ((NUMSHB_Node)n).mesh;
                }
                if (n.Text.Equals(_model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SKEL_Node)n).GetRenderableNode();
                }
            }

            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (outModel.Skeleton != null)
            {
                for (int i = 0; i < outModel.Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i);
                }
            }

            if (meshFile != null)
            {
                using (SSBHVertexAccessor vertexAccessor = new SSBHVertexAccessor(meshFile))
                {
                    SSBHRiggingAccessor riggingAccessor = new SSBHRiggingAccessor(meshFile);
                    foreach (MeshObject obj in meshFile.Objects)
                    {
                        IOMesh outMesh = new IOMesh()
                        {
                            Name = obj.Name,
                        };
                        outModel.Meshes.Add(outMesh);

                        IOVertex[] vertices = new IOVertex[obj.VertexCount];
                        for (int i = 0; i < vertices.Length; i++)
                        {
                            vertices[i] = new IOVertex();
                        }

                        foreach (MeshAttribute attr in obj.Attributes)
                        {
                            SSBHVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj);

                            if (attr.AttributeStrings[0].Name.Equals("Position0"))
                            {
                                outMesh.HasPositions = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("Normal0"))
                            {
                                outMesh.HasNormals = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("map1"))
                            {
                                outMesh.HasUV0 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV0 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet"))
                            {
                                outMesh.HasUV1 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV1 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet1"))
                            {
                                outMesh.HasUV2 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV2 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet2"))
                            {
                                outMesh.HasUV3 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV3 = new OpenTK.Vector2(values[i].X, values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("colorSet1"))
                            {
                                outMesh.HasColor = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W);
                                }
                            }
                        }

                        // Fix SingleBinds
                        if (outModel.Skeleton != null && !obj.ParentBoneName.Equals(""))
                        {
                            int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName);
                            if (parentIndex != -1)
                            {
                                for (int i = 0; i < vertices.Length; i++)
                                {
                                    vertices[i].Position      = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].Normal        = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName];
                                    vertices[i].BoneWeights.X = 1;
                                }
                            }
                        }

                        // Apply Rigging
                        SSBHVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex);

                        foreach (SSBHVertexInfluence influence in influences)
                        {
                            // Some influences refer to bones that don't exist in the skeleton.
                            // _eff bones?
                            if (!indexByBoneName.ContainsKey(influence.BoneName))
                            {
                                continue;
                            }

                            if (vertices[influence.VertexIndex].BoneWeights.X == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.X = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Y == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Z == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.W == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.W = influence.Weight;
                            }
                        }

                        outMesh.Vertices.AddRange(vertices);
                        outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj));
                    }
                }
            }


            return(outModel);
        }
Esempio n. 8
0
        private List <CustomVertex> CreateVertices(RSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices)
        {
            // Read attribute values.
            var positions       = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject);
            var normals         = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject);
            var tangents        = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject);
            var map1Values      = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject);
            var uvSetValues     = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject);
            var uvSet1Values    = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject);
            var bake1Values     = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject);
            var colorSet1Values = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject);
            var colorSet5Values = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject);

            // TODO: Convert vectors.
            var intIndices = new List <int>();

            foreach (var value in vertexIndices)
            {
                intIndices.Add((int)value);
            }
            SFGraphics.Utils.TriangleListUtils.CalculateTangentsBitangents(GetVectors3d(positions), GetVectors3d(normals), GetVectors2d(map1Values), intIndices, out Vector3[] newTangents, out Vector3[] bitangents);
Esempio n. 9
0
        private static List <UltimateVertex> CreateVertices(MESH mesh, ISBSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices)
        {
            // Read attribute values.
            var positions        = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject);
            var normals          = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject);
            var tangents         = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject);
            var map1Values       = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject);
            var uvSetValues      = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject);
            var uvSet1Values     = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject);
            var uvSet2Values     = vertexAccessor.ReadAttribute("uvSet2", 0, meshObject.VertexCount, meshObject);
            var bake1Values      = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject);
            var colorSet1Values  = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject);
            var colorSet2Values  = vertexAccessor.ReadAttribute("colorSet2", 0, meshObject.VertexCount, meshObject);
            var colorSet21Values = vertexAccessor.ReadAttribute("colorSet21", 0, meshObject.VertexCount, meshObject);
            var colorSet22Values = vertexAccessor.ReadAttribute("colorSet22", 0, meshObject.VertexCount, meshObject);
            var colorSet23Values = vertexAccessor.ReadAttribute("colorSet23", 0, meshObject.VertexCount, meshObject);
            var colorSet3Values  = vertexAccessor.ReadAttribute("colorSet3", 0, meshObject.VertexCount, meshObject);
            var colorSet4Values  = vertexAccessor.ReadAttribute("colorSet4", 0, meshObject.VertexCount, meshObject);
            var colorSet5Values  = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject);
            var colorSet6Values  = vertexAccessor.ReadAttribute("colorSet6", 0, meshObject.VertexCount, meshObject);
            var colorSet7Values  = vertexAccessor.ReadAttribute("colorSet7", 0, meshObject.VertexCount, meshObject);

            // Generate bitangents.
            // TODO: Use vec4 tangents instead.
            var positionVectors = GetVectors3d(positions);
            var normalVectors   = GetVectors3d(normals);
            var map1Vectors     = GetVectors2d(map1Values);

            SFGraphics.Utils.TriangleListUtils.CalculateTangentsBitangents(positionVectors, normalVectors, map1Vectors, (int[])(object)vertexIndices, out Vector3[] tangentVectors, out Vector3[] bitangentVectors);
Esempio n. 10
0
        public IOModel GetIOModel()
        {
            IOModel outModel = new IOModel();

            MESH meshFile     = null;
            MATL materialFile = null;

            foreach (FileNode n in Parent.Nodes)
            {
                if (n.Text.Equals(_model.MeshString))
                {
                    meshFile = ((NUMSHB_Node)n).mesh;
                }
                if (n.Text.Equals(_model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SKEL_Node)n).GetRenderableNode();
                }
                if (n.Text.Equals(_model.MaterialFileNames[0].MaterialFileName))
                {
                    materialFile = ((MATL_Node)n).Material;
                }
            }

            Dictionary <string, int> indexByBoneName = new Dictionary <string, int>();

            if (outModel.Skeleton != null)
            {
                for (int i = 0; i < outModel.Skeleton.Bones.Count; i++)
                {
                    indexByBoneName.Add(outModel.Skeleton.Bones[i].Name, i);
                }
            }

            Dictionary <string, int> materialNameToIndex = new Dictionary <string, int>();

            if (materialFile != null)
            {
                int materialIndex = 0;
                foreach (var entry in materialFile.Entries)
                {
                    materialNameToIndex.Add(entry.MaterialLabel, materialIndex++);
                    IOMaterial material = new IOMaterial();
                    material.Name = entry.MaterialLabel;
                    outModel.Materials.Add(material);

                    foreach (var attr in entry.Attributes)
                    {
                        if (attr.ParamID == MatlEnums.ParamId.Texture0)
                        {
                            IOTexture dif = new IOTexture();
                            dif.Name = attr.DataObject.ToString();
                            material.DiffuseTexture = dif;
                        }
                    }
                }
            }

            if (meshFile != null)
            {
                SSBHVertexAccessor vertexAccessor = new SSBHVertexAccessor(meshFile);
                {
                    SSBHRiggingAccessor riggingAccessor = new SSBHRiggingAccessor(meshFile);
                    foreach (MeshObject obj in meshFile.Objects)
                    {
                        IOMesh outMesh = new IOMesh()
                        {
                            Name = obj.Name,
                        };
                        outModel.Meshes.Add(outMesh);

                        // get material
                        if (materialFile != null)
                        {
                            foreach (var entry in _model.ModelEntries)
                            {
                                if (entry.MeshName.Equals(obj.Name) && entry.SubIndex == obj.SubMeshIndex)
                                {
                                    outMesh.MaterialIndex = materialNameToIndex[entry.MaterialName];
                                    break;
                                }
                            }
                        }

                        IOVertex[] vertices = new IOVertex[obj.VertexCount];
                        for (int i = 0; i < vertices.Length; i++)
                        {
                            vertices[i] = new IOVertex();
                        }

                        foreach (MeshAttribute attr in obj.Attributes)
                        {
                            SSBHVertexAttribute[] values = vertexAccessor.ReadAttribute(attr.AttributeStrings[0].Name, 0, obj.VertexCount, obj);

                            if (attr.AttributeStrings[0].Name.Equals("Position0"))
                            {
                                outMesh.HasPositions = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Position = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("Normal0"))
                            {
                                outMesh.HasNormals = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Normal = new OpenTK.Vector3(values[i].X, values[i].Y, values[i].Z);
                                }
                            }

                            // Flip UVs vertically for export.
                            if (attr.AttributeStrings[0].Name.Equals("map1"))
                            {
                                outMesh.HasUV0 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV0 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet"))
                            {
                                outMesh.HasUV1 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV1 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet1"))
                            {
                                outMesh.HasUV2 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV2 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("uvSet2"))
                            {
                                outMesh.HasUV3 = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].UV3 = new OpenTK.Vector2(values[i].X, 1 - values[i].Y);
                                }
                            }
                            if (attr.AttributeStrings[0].Name.Equals("colorSet1"))
                            {
                                outMesh.HasColor = true;
                                for (int i = 0; i < values.Length; i++)
                                {
                                    vertices[i].Color = new OpenTK.Vector4(values[i].X, values[i].Y, values[i].Z, values[i].W) / 127f;
                                }
                            }
                        }

                        // Fix SingleBinds
                        if (outModel.Skeleton != null && !obj.ParentBoneName.Equals(""))
                        {
                            int parentIndex = outModel.Skeleton.GetBoneIndex(obj.ParentBoneName);
                            if (parentIndex != -1)
                            {
                                for (int i = 0; i < vertices.Length; i++)
                                {
                                    vertices[i].Position      = OpenTK.Vector3.TransformPosition(vertices[i].Position, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].Normal        = OpenTK.Vector3.TransformNormal(vertices[i].Normal, outModel.Skeleton.Bones[parentIndex].WorldTransform);
                                    vertices[i].BoneIndices.X = indexByBoneName[obj.ParentBoneName];
                                    vertices[i].BoneWeights.X = 1;
                                    outMesh.HasBoneWeights    = true;
                                }
                            }
                        }

                        // Apply Rigging
                        SSBHVertexInfluence[] influences = riggingAccessor.ReadRiggingBuffer(obj.Name, (int)obj.SubMeshIndex);

                        foreach (SSBHVertexInfluence influence in influences)
                        {
                            outMesh.HasBoneWeights = true;

                            // Some influences refer to bones that don't exist in the skeleton.
                            // _eff bones?
                            if (!indexByBoneName.ContainsKey(influence.BoneName))
                            {
                                continue;
                            }

                            if (vertices[influence.VertexIndex].BoneWeights.X == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.X = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.X = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Y == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Y = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Y = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.Z == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.Z = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.Z = influence.Weight;
                            }
                            else if (vertices[influence.VertexIndex].BoneWeights.W == 0)
                            {
                                vertices[influence.VertexIndex].BoneIndices.W = indexByBoneName[influence.BoneName];
                                vertices[influence.VertexIndex].BoneWeights.W = influence.Weight;
                            }
                        }

                        outMesh.Vertices.AddRange(vertices);
                        outMesh.Indices.AddRange(vertexAccessor.ReadIndices(0, obj.IndexCount, obj));
                    }
                }
            }


            return(outModel);
        }