Example #1
0
        /// <summary>
        /// Gets the model information in this scene as an IO Model
        /// </summary>
        /// <returns></returns>
        public override IOModel GetIOModel()
        {
            IOModel iomodel = new IOModel();

            iomodel.Skeleton = (SBSkeleton)Skeleton;

            foreach (var mesh in Model.Meshes)
            {
                var iomesh = new IOMesh();
                iomesh.Name = mesh.Name;
                iomodel.Meshes.Add(iomesh);

                iomesh.HasPositions = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.Position0);
                iomesh.HasNormals   = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.Normal0);
                iomesh.HasUV0       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.map1);
                iomesh.HasUV1       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.uvSet);
                iomesh.HasUV2       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.uvSet1);
                iomesh.HasUV3       = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.uvSet2);
                iomesh.HasColor     = mesh.ExportAttributes.Contains(SSBHLib.Tools.MESHAttribute.colorSet1);

                iomesh.HasBoneWeights = true;

                iomesh.Indices.AddRange(mesh.Indices);

                foreach (var vertex in mesh.Vertices)
                {
                    var iovertex = new IOVertex();

                    iovertex.Position    = vertex.Position0;
                    iovertex.Normal      = vertex.Normal0;
                    iovertex.Tangent     = vertex.Tangent0;
                    iovertex.UV0         = vertex.Map1;
                    iovertex.UV1         = vertex.UvSet;
                    iovertex.UV2         = vertex.UvSet1;
                    iovertex.Color       = vertex.ColorSet1;
                    iovertex.BoneIndices = new Vector4(vertex.BoneIndices.X, vertex.BoneIndices.Y, vertex.BoneIndices.Z, vertex.BoneIndices.W);
                    iovertex.BoneWeights = vertex.BoneWeights;

                    // single bind fix
                    if (mesh.ParentBone != "" && Skeleton != null)
                    {
                        var parentBone = Skeleton[mesh.ParentBone];
                        if (parentBone != null)
                        {
                            iovertex.Position    = Vector3.TransformPosition(vertex.Position0, parentBone.WorldTransform);
                            iovertex.Normal      = Vector3.TransformNormal(vertex.Normal0, parentBone.WorldTransform);
                            iovertex.BoneIndices = new Vector4(Skeleton.IndexOfBone(parentBone), 0, 0, 0);
                            iovertex.BoneWeights = new Vector4(1, 0, 0, 0);
                        }
                    }

                    iomesh.Vertices.Add(iovertex);
                }
            }

            return(iomodel);
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="type"></param>
        /// <param name="vertices"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        private List <IOVertex> ConvertGXDLtoTriangleList(GXPrimitiveType type, List <SBHsdVertex> vertices, SBHsdBone parent)
        {
            var list = new List <IOVertex>();

            foreach (var v in vertices)
            {
                var vertex = new IOVertex()
                {
                    Position = new System.Numerics.Vector3(v.POS.X, v.POS.Y, v.POS.Z),
                    Normal   = new System.Numerics.Vector3(v.NRM.X, v.NRM.Y, v.NRM.Z),
                };
                vertex.SetUV(v.UV0.X, v.UV0.Y, 0);

                for (int i = 0; i < 4; i++)
                {
                    if (v.Weight[i] > 0)
                    {
                        vertex.Envelope.Weights.Add(new IOBoneWeight()
                        {
                            BoneName = "JOBJ_" + (int)v.Bone[i],
                            Weight   = v.Weight[i]
                        });
                    }
                }

                if (parent != null)
                {
                    vertex.Transform(TktoNumeric(parent.WorldTransform));

                    if (vertex.Envelope.Weights.Count == 0)
                    {
                        vertex.Envelope.Weights.Add(new IOBoneWeight()
                        {
                            BoneName = parent.Name,
                            Weight   = 1
                        });
                    }
                }
                if (v.Weight.X == 1)
                {
                    vertex.Transform(TktoNumeric(Skeleton.Bones[(int)v.Bone.X].WorldTransform));
                }
                list.Add(vertex);
            }

            if (type == GXPrimitiveType.TriangleStrip)
            {
                TriangleConvert.StripToList(list, out list);
            }

            if (type == GXPrimitiveType.Quads)
            {
                TriangleConvert.QuadToList(list, out list);
            }

            return(list);
        }
Example #3
0
 private static UltimateVertex IOToUltimateVertex(IOVertex iov)
 {
     return(new UltimateVertex(iov.Position, iov.Normal, iov.Tangent, Vector3.Zero, iov.UV0, iov.UV1,
                               iov.UV2, new IVec4()
     {
         X = (int)iov.BoneIndices.X,
         Y = (int)iov.BoneIndices.Y,
         Z = (int)iov.BoneIndices.Z,
         W = (int)iov.BoneIndices.W
     },
                               iov.BoneWeights, Vector2.Zero, Vector4.One, Vector4.One));
 }
Example #4
0
        private List <IOVertex> ConvertGXDLtoTriangleList(GXPrimitiveType type, List <SBHsdVertex> vertices, SBHsdBone parent)
        {
            var list = new List <IOVertex>();

            foreach (var v in vertices)
            {
                var vertex = new IOVertex()
                {
                    Position    = GXtoGL.GLVector3(v.POS),
                    Normal      = GXtoGL.GLVector3(v.NRM),
                    UV0         = GXtoGL.GLVector2(v.UV0),
                    BoneIndices = v.Bone,
                    BoneWeights = v.Weight,
                };
                if (parent != null)
                {
                    vertex.Position = Vector3.TransformPosition(vertex.Position, parent.WorldTransform);
                    vertex.Normal   = Vector3.TransformNormal(vertex.Normal, parent.WorldTransform);

                    if (vertex.BoneWeights.X == 0)
                    {
                        vertex.BoneWeights.X = 1;
                        vertex.BoneIndices.X = Skeleton.IndexOfBone(parent);
                    }
                }
                if (v.Weight.X == 1)
                {
                    vertex.Position = Vector3.TransformPosition(vertex.Position, Skeleton.Bones[(int)v.Bone.X].WorldTransform);
                    vertex.Normal   = Vector3.TransformNormal(vertex.Normal, Skeleton.Bones[(int)v.Bone.X].WorldTransform);
                }
                list.Add(vertex);
            }

            if (type == GXPrimitiveType.TriangleStrip)
            {
                TriangleConvert.StripToList(list, out list);
            }

            if (type == GXPrimitiveType.Quads)
            {
                TriangleConvert.QuadToList(list, out list);
            }

            return(list);
        }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private static IOVertex ParseVertex(string line, Dictionary <int, IOBone> idxToBones, out IOBone parentBone)
        {
            var args = Regex.Replace(line.Trim(), @"\s+", " ").Split(' ');

            IOVertex vertex = new IOVertex();

            // parse parent index
            int parent = int.Parse(args[0]);

            // parse attributes
            vertex.Position = new System.Numerics.Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3]));
            vertex.Normal   = new System.Numerics.Vector3(float.Parse(args[4]), float.Parse(args[5]), float.Parse(args[6]));
            vertex.UVs.Add(new System.Numerics.Vector2(float.Parse(args[7]), float.Parse(args[8])));

            // transform by parent so we can ignore it
            if (parent != -1)
            {
                vertex.Transform(idxToBones[parent].WorldTransform);
                parentBone = idxToBones[parent];
            }
            else
            {
                parentBone = null;
            }

            // parse weights
            if (args.Length >= 10)
            {
                int links = int.Parse(args[9]);

                for (int i = 0; i < links; i++)
                {
                    vertex.Envelope.Weights.Add(new IOBoneWeight()
                    {
                        BoneName = idxToBones[int.Parse(args[10 + i * 2])].Name,
                        Weight   = float.Parse(args[11 + i * 2])
                    });
                }
            }

            return(vertex);
        }
Example #6
0
        private static SMDVertex IOVertexToSMDVertex(IOVertex iovertex)
        {
            var smdvertex = new SMDVertex();

            smdvertex.Position = iovertex.Position;
            smdvertex.Normal   = iovertex.Normal;
            smdvertex.UV       = iovertex.UV0;

            int weightCount = CountWeights(iovertex.BoneWeights);

            smdvertex.Bones   = new int[weightCount];
            smdvertex.Weights = new float[weightCount];
            for (int i = 0; i < weightCount; i++)
            {
                smdvertex.Bones[0]   = (int)iovertex.BoneIndices[i];
                smdvertex.Weights[0] = iovertex.BoneWeights[i];
            }

            return(smdvertex);
        }
Example #7
0
        private static IOVertex ReadVertex(string[] args)
        {
            var vertex = new IOVertex()
            {
                Position = new Vector3(float.Parse(args[1]), float.Parse(args[2]), float.Parse(args[3])),
                Normal   = new Vector3(float.Parse(args[4]), float.Parse(args[5]), float.Parse(args[6])),
                UV0      = new Vector2(float.Parse(args[7]), float.Parse(args[8])),
            };

            vertex.Color = Vector4.One;

            int InfluenceCount = int.Parse(args[9]);

            for (int i = 0; i < InfluenceCount * 2; i += 2)
            {
                int   boneIndex = int.Parse(args[10 + i]);
                float weight    = float.Parse(args[10 + i + 1]);
                if (i / 2 == 0)
                {
                    vertex.BoneIndices.X = boneIndex;
                    vertex.BoneWeights.X = weight;
                }
                if (i / 2 == 1)
                {
                    vertex.BoneIndices.Y = boneIndex;
                    vertex.BoneWeights.Y = weight;
                }
                if (i / 2 == 2)
                {
                    vertex.BoneIndices.Z = boneIndex;
                    vertex.BoneWeights.Z = weight;
                }
                if (i / 2 == 3)
                {
                    vertex.BoneIndices.W = boneIndex;
                    vertex.BoneWeights.W = weight;
                }
            }

            return(vertex);
        }
Example #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="semantic"></param>
        /// <param name="values"></param>
        /// <param name="vertex"></param>
        /// <param name="vertices"></param>
        private void ProcessInput(Input_Semantic semantic, string source, int set, IOVertex vertex, Vertices vertices, int index, SourceManager srcs, List <IOEnvelope> vertexEnvelopes)
        {
            var values = srcs.GetFloatValue(source, index);

            switch (semantic)
            {
            case Input_Semantic.VERTEX:
                // process per vertex input
                foreach (var vertInput in vertices.Input)
                {
                    ProcessInput(vertInput.Semantic, vertInput.source, 0, vertex, vertices, index, srcs, vertexEnvelopes);
                }

                // load envelopes if availiable
                if (vertexEnvelopes != null && index < vertexEnvelopes.Count)
                {
                    // copy bone weights
                    var en = vertexEnvelopes[index];
                    for (int i = 0; i < en.Weights.Count; i++)
                    {
                        vertex.Envelope.Weights.Add(new IOBoneWeight()
                        {
                            BoneName   = en.Weights[i].BoneName,
                            Weight     = en.Weights[i].Weight,
                            BindMatrix = en.Weights[i].BindMatrix
                        });
                    }

                    // make the bind matrix as being used
                    vertex.Envelope.UseBindMatrix = true;
                }
                break;

            case Input_Semantic.POSITION:
                vertex.Position = new Vector3(
                    values.Length > 0 ? values[0] : 0,
                    values.Length > 1 ? values[1] : 0,
                    values.Length > 2 ? values[2] : 0);
                break;

            case Input_Semantic.NORMAL:
                vertex.Normal = new Vector3(
                    values.Length > 0 ? values[0] : 0,
                    values.Length > 1 ? values[1] : 0,
                    values.Length > 2 ? values[2] : 0);
                break;

            case Input_Semantic.TANGENT:
                vertex.Tangent = new Vector3(
                    values.Length > 0 ? values[0] : 0,
                    values.Length > 1 ? values[1] : 0,
                    values.Length > 2 ? values[2] : 0);
                break;

            case Input_Semantic.BINORMAL:
                vertex.Binormal = new Vector3(
                    values.Length > 0 ? values[0] : 0,
                    values.Length > 1 ? values[1] : 0,
                    values.Length > 2 ? values[2] : 0);
                break;

            case Input_Semantic.TEXCOORD:
                vertex.SetUV(
                    values.Length > 0 ? values[0] : 0,
                    values.Length > 1 ? values[1] : 0,
                    set);
                break;

            case Input_Semantic.COLOR:
                vertex.SetColor(
                    values.Length > 0 ? values[0] : 0,
                    values.Length > 1 ? values[1] : 0,
                    values.Length > 2 ? values[2] : 0,
                    values.Length > 3 ? values[3] : 0,
                    set);
                break;
            }
        }
Example #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="n"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public IOMesh LoadGeometryFromID(Node n, string id, List <IOEnvelope> vertexEnvelopes = null)
        {
            // sanitize
            id = ColladaHelper.SanitizeID(id);

            // find geometry by id
            var geom = _collada.Library_Geometries.Geometry.First(e => e.ID == id);

            // not found
            if (geom == null)
            {
                return(null);
            }

            // create new mesh
            IOMesh mesh = new IOMesh()
            {
                Name = n.Name
            };

            // create source manager helper
            SourceManager srcs = new SourceManager();

            if (geom.Mesh.Source != null)
            {
                foreach (var src in geom.Mesh.Source)
                {
                    srcs.AddSource(src);
                }
            }


            // load geomtry meshes
            if (geom.Mesh.Triangles != null)
            {
                foreach (var tri in geom.Mesh.Triangles)
                {
                    var stride = tri.Input.Max(e => e.Offset) + 1;
                    var poly   = new IOPolygon()
                    {
                        PrimitiveType = IOPrimitive.TRIANGLE,
                        MaterialName  = tri.Material
                    };

                    var p = tri.P.GetValues();

                    for (int i = 0; i < tri.Count * 3; i++)
                    {
                        IOVertex vertex = new IOVertex();

                        for (int j = 0; j < tri.Input.Length; j++)
                        {
                            var input = tri.Input[j];

                            var index = p[i * stride + input.Offset];

                            ProcessInput(input.Semantic, input.source, input.Set, vertex, geom.Mesh.Vertices, index, srcs, vertexEnvelopes);
                        }

                        poly.Indicies.Add(mesh.Vertices.Count);
                        mesh.Vertices.Add(vertex);
                    }

                    mesh.Polygons.Add(poly);
                }
            }

            //TODO: collada trifan

            //TODO: collada  tristrip

            //TODO: collada linestrip

            //TODO: collada polylist

            //TODO: collada polygon

            return(mesh);
        }
Example #10
0
        /// <summary>
        ///
        /// </summary>
        private void ProcessGeometry(FbxNode node, out IOPolygon poly, out List <IOVertex> verts)
        {
            double[] vertices;
            int[]    indices;

            // load vertices
            if (node["Vertices"].Value is double[])
            {
                vertices = (double[])node["Vertices"].Value;
            }
            else
            {
                vertices = node["Vertices"].Properties.Select(e => (double)e).ToArray();
            }


            // load vertex indices
            if (node["PolygonVertexIndex"].Value is int[])
            {
                indices = (int[])node["PolygonVertexIndex"].Value;
            }
            else
            {
                indices = node["PolygonVertexIndex"].Properties.Select(e => (int)e).ToArray();
            }


            // get binds
            var deformers = GetChildConnections(node).Where(e => e.Name == "Deformer");

            List <Dictionary <int, Tuple <float, string> > > deforms = new List <Dictionary <int, Tuple <float, string> > >();

            foreach (var par in deformers)
            {
                foreach (var sub in GetChildConnections(par))
                {
                    // get bone name
                    var name = "";
                    foreach (var mod in GetChildConnections(sub))
                    {
                        if (mod.Name == "Model")
                        {
                            name = GetNameWithoutNamespace(mod.Properties[NodeDescSize - 2].ToString());
                        }
                    }

                    if (!string.IsNullOrEmpty(name) && sub["Indexes"] != null)
                    {
                        // create deform map
                        Dictionary <int, Tuple <float, string> > deformmap = new Dictionary <int, Tuple <float, string> >();

                        // indices
                        int[] ind;
                        if (sub["Indexes"].Value is int[])
                        {
                            ind = (int[])sub["Indexes"].Value;
                        }
                        else
                        {
                            ind = sub["Indexes"].Properties.Select(e => (int)e).ToArray();
                        }

                        // weights
                        float[] weights;
                        if (sub["Weights"].Value is double[])
                        {
                            weights = ((double[])sub["Weights"].Value).Select(e => (float)e).ToArray();
                        }
                        else
                        {
                            weights = sub["Weights"].Properties.Select(e => (float)(double)e).ToArray();
                        }

                        // generate map
                        for (int i = 0; i < weights.Length; i++)
                        {
                            deformmap.Add(ind[i], new Tuple <float, string>(weights[i], name));
                        }

                        // add deform entry
                        deforms.Add(deformmap);
                    }
                }
            }

            // generate polygon
            poly  = new IOPolygon();
            verts = new List <IOVertex>();

            poly.PrimitiveType = IOPrimitive.TRIANGLE;

            // process primitives and convert to triangles
            var primLength = 0;

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

                primLength++;

                if (idx1 < 0)
                {
                    switch (primLength)
                    {
                    case 4:
                        // convert quad to triangle
                        poly.Indicies.Add(i - 3);
                        poly.Indicies.Add(i - 2);
                        poly.Indicies.Add(i - 1);
                        poly.Indicies.Add(i - 3);
                        poly.Indicies.Add(i - 1);
                        poly.Indicies.Add(i);
                        break;

                    case 3:
                        // triangle
                        poly.Indicies.Add(i - 2);
                        poly.Indicies.Add(i - 1);
                        poly.Indicies.Add(i);
                        break;

                    default:
                        // tri strip
                        for (var vi = i - primLength; vi < i - 2; vi++)
                        {
                            if ((vi & 1) != 0)
                            {
                                poly.Indicies.Add(vi);
                                poly.Indicies.Add(vi + 1);
                                poly.Indicies.Add(vi + 2);
                            }
                            else
                            {
                                poly.Indicies.Add(vi);
                                poly.Indicies.Add(vi + 2);
                                poly.Indicies.Add(vi + 1);
                            }
                        }
                        break;
                    }

                    idx1 = Math.Abs(idx1) - 1; // xor -1

                    primLength = 0;
                }

                IOVertex v = new IOVertex()
                {
                    Position = new Vector3((float)vertices[idx1 * 3], (float)vertices[idx1 * 3 + 1], (float)vertices[idx1 * 3 + 2])
                };

                // find deforms
                foreach (var map in deforms)
                {
                    if (map.ContainsKey(idx1))
                    {
                        v.Envelope.Weights.Add(new Core.IOBoneWeight()
                        {
                            Weight   = map[idx1].Item1,
                            BoneName = map[idx1].Item2,
                        });
                    }
                }


                verts.Add(v);
            }


            // get layer information
            ProcessLayer(node, "Normal", indices, verts);
            ProcessLayer(node, "Tangent", indices, verts);
            ProcessLayer(node, "Binormal", indices, verts);
            ProcessLayer(node, "UV", indices, verts);
            ProcessLayer(node, "Color", indices, verts);
        }
Example #11
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);
        }
Example #12
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 = ((NumsbhNode)n).mesh;
                }
                if (n.Text.Equals(model.SkeletonFileName))
                {
                    outModel.Skeleton = (RSkeleton)((SkelNode)n).GetRenderableNode();
                }
                if (n.Text.Equals(model.MaterialFileNames[0].MaterialFileName))
                {
                    materialFile = ((MatlNode)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.ShaderLabel, materialIndex++);
                    IOMaterial material = new IOMaterial
                    {
                        Name = entry.ShaderLabel
                    };
                    outModel.Materials.Add(material);

                    foreach (var attr in entry.Attributes)
                    {
                        if (attr.ParamId == MatlEnums.ParamId.Texture0)
                        {
                            IOTexture dif = new IOTexture
                            {
                                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.MaterialLabel];
                                    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);
        }
Example #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public IOScene GetScene(string filePath)
        {
            // create scene and model
            IOScene scene = new IOScene();

            // load materials
            var mtlFile = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".mtl");

            if (File.Exists(mtlFile))
            {
                LoadMaterialLibrary(scene, mtlFile);
            }

            // parse obj file
            using (FileStream stream = new FileStream(filePath, FileMode.Open))
                using (StreamReader r = new StreamReader(stream))
                {
                    List <Vector3> v  = new List <Vector3>();
                    List <Vector2> vt = new List <Vector2>();
                    List <Vector3> vn = new List <Vector3>();

                    List <Tuple <string, string, Dictionary <IOPrimitive, List <int[]> > > > objects = new List <Tuple <string, string, Dictionary <IOPrimitive, List <int[]> > > >();

                    var objName = "Mesh";
                    var matNam  = "";
                    Dictionary <IOPrimitive, List <int[]> > polygons = new Dictionary <IOPrimitive, List <int[]> >();

                    while (!r.EndOfStream)
                    {
                        var args = Regex.Replace(r.ReadLine().Trim(), @"\s+", " ").Split(' ');

                        if (args.Length > 0)
                        {
                            switch (args[0])
                            {
                            case "v":
                                v.Add(new Vector3(
                                          args.Length > 1 ? float.Parse(args[1]) : 0,
                                          args.Length > 2 ? float.Parse(args[2]) : 0,
                                          args.Length > 3 ? float.Parse(args[3]) : 0));
                                break;

                            case "vt":
                                vt.Add(new Vector2(
                                           args.Length > 1 ? float.Parse(args[1]) : 0,
                                           args.Length > 2 ? float.Parse(args[2]) : 0));
                                break;

                            case "vn":
                                vn.Add(new Vector3(
                                           args.Length > 1 ? float.Parse(args[1]) : 0,
                                           args.Length > 2 ? float.Parse(args[2]) : 0,
                                           args.Length > 3 ? float.Parse(args[3]) : 0));
                                break;

                            case "f":
                                var faces = ParseFaces(args);

                                if (args.Length == 2)
                                {
                                    // point
                                    if (!polygons.ContainsKey(IOPrimitive.POINT))
                                    {
                                        polygons.Add(IOPrimitive.POINT, new List <int[]>());
                                    }
                                    polygons[IOPrimitive.POINT].AddRange(faces);
                                }
                                if (args.Length == 3)
                                {
                                    // line
                                    if (!polygons.ContainsKey(IOPrimitive.LINE))
                                    {
                                        polygons.Add(IOPrimitive.LINE, new List <int[]>());
                                    }
                                    polygons[IOPrimitive.LINE].AddRange(faces);
                                }
                                if (args.Length == 4)
                                {
                                    // triangle
                                    if (!polygons.ContainsKey(IOPrimitive.TRIANGLE))
                                    {
                                        polygons.Add(IOPrimitive.TRIANGLE, new List <int[]>());
                                    }
                                    polygons[IOPrimitive.TRIANGLE].AddRange(faces);
                                }
                                if (args.Length == 5)
                                {
                                    // quad
                                    if (!polygons.ContainsKey(IOPrimitive.QUAD))
                                    {
                                        polygons.Add(IOPrimitive.QUAD, new List <int[]>());
                                    }
                                    polygons[IOPrimitive.QUAD].AddRange(faces);
                                }
                                if (args.Length == 6)
                                {
                                    // strip
                                    if (!polygons.ContainsKey(IOPrimitive.TRISTRIP))
                                    {
                                        polygons.Add(IOPrimitive.TRISTRIP, new List <int[]>());
                                    }
                                    polygons[IOPrimitive.TRISTRIP].AddRange(faces);
                                }
                                break;

                            case "o":
                                if (polygons.Count > 0)
                                {
                                    objects.Add(new Tuple <string, string, Dictionary <IOPrimitive, List <int[]> > >(objName, matNam, polygons));
                                }
                                objName  = args[1];
                                matNam   = "";
                                polygons = new Dictionary <IOPrimitive, List <int[]> >();
                                break;

                            case "usemtl":
                                matNam = args[1];
                                break;
                            }
                        }
                    }

                    objects.Add(new Tuple <string, string, Dictionary <IOPrimitive, List <int[]> > >(objName, matNam, polygons));

                    // generate model
                    IOModel model = new IOModel();
                    scene.Models.Add(model);

                    // dummy bone
                    model.Skeleton.RootBones.Add(new Core.Skeleton.IOBone()
                    {
                        Name = "Root"
                    });

                    // convert and add polygons
                    foreach (var obj in objects)
                    {
                        IOMesh mesh = new IOMesh()
                        {
                            Name = obj.Item1
                        };

                        foreach (var p in obj.Item3)
                        {
                            IOPolygon poly = new IOPolygon()
                            {
                                PrimitiveType = p.Key,
                                MaterialName  = obj.Item2,
                            };

                            for (int i = 0; i < p.Value.Count; i++)
                            {
                                var face = p.Value[i];

                                IOVertex vert = new IOVertex()
                                {
                                    Position = face[0] != -1 ? v[face[0]] : Vector3.Zero,
                                    Normal   = face[2] != -1 ? vn[face[2]] : Vector3.Zero,
                                };
                                if (face[1] != -1)
                                {
                                    vert.UVs.Add(vt[face[1]]);
                                }

                                poly.Indicies.Add(mesh.Vertices.Count);
                                mesh.Vertices.Add(vert);
                            }

                            mesh.Polygons.Add(poly);
                        }

                        // add mesh to model
                        model.Meshes.Add(mesh);
                    }
                    ;
                }

            return(scene);
        }
Example #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="geometry"></param>
        /// <param name="Index"></param>
        /// <returns></returns>
        private static IOVertex CreateVertex(Matrix4 transform, FbxGeometry geometry, int Index, Vector4[] boneIndices, Vector4[] boneWeights, float scale)
        {
            int VertexIndex = geometry.Indices[Index];

            if ((Index + 1) % 3 == 0)
            {
                VertexIndex = (geometry.Indices[Index] + 1) * -1;
            }

            IOVertex vertex = new IOVertex()
            {
                Position = Vector3.TransformPosition(
                    new Vector3(
                        (float)geometry.Vertices[VertexIndex * 3],
                        (float)geometry.Vertices[VertexIndex * 3 + 1],
                        (float)geometry.Vertices[VertexIndex * 3 + 2]),
                    transform) * scale,
                BoneIndices = boneIndices[VertexIndex],
                BoneWeights = boneWeights[VertexIndex]
            };

            vertex.Color = Vector4.One;

            //Deforming

            foreach (var layer in geometry.Layers)
            {
                int layerIndex = Index;
                if (!layer.ReferenceInformationType.Equals("Direct"))
                {
                    layerIndex = layer.Indices[Index];
                }
                switch (layer.Name)
                {
                case "LayerElementNormal":
                    if (layer.Data.Length == geometry.Vertices.Length)
                    {
                        vertex.Normal = new Vector3((float)layer.Data[VertexIndex * 3], (float)layer.Data[VertexIndex * 3 + 1], (float)layer.Data[VertexIndex * 3 + 2]);
                        vertex.Normal = Vector3.TransformNormal(vertex.Normal, transform);
                        vertex.Normal.Normalize();
                        break;
                    }
                    else
                    {
                        vertex.Normal = new Vector3((float)layer.Data[layerIndex * 3], (float)layer.Data[layerIndex * 3 + 1], (float)layer.Data[layerIndex * 3 + 2]);
                        vertex.Normal = Vector3.TransformNormal(vertex.Normal, transform);
                        vertex.Normal.Normalize();
                        break;
                    }

                case "LayerElementColor":
                    vertex.Color = new Vector4((float)layer.Data[layerIndex * 4], (float)layer.Data[layerIndex * 4 + 1], (float)layer.Data[layerIndex * 4 + 2], (float)layer.Data[layerIndex * 4 + 3]);
                    break;

                case "LayerElementUV":
                    Vector2 uv = new Vector2((float)layer.Data[layerIndex * 2], 1 - (float)layer.Data[layerIndex * 2 + 1]);
                    if (layer.Layer == 0)
                    {
                        vertex.UV0 = uv;
                    }
                    if (layer.Layer == 1)
                    {
                        vertex.UV1 = uv;
                    }
                    if (layer.Layer == 2)
                    {
                        vertex.UV2 = uv;
                    }
                    if (layer.Layer == 3)
                    {
                        vertex.UV3 = uv;
                    }
                    break;
                }
            }

            return(vertex);
        }