Пример #1
0
        public static HsfFile Import(STGenericScene scene, ImportSettings settings)
        {
            HsfFile hsf  = new HsfFile();
            var     root = ObjectDataSection.CreateNewObject(ObjectType.Root);

            hsf.ObjectData.Objects.Add(root);
            hsf.ObjectData.ObjectNames.Add("Root");

            foreach (var tex in scene.Models[0].Textures)
            {
                Console.WriteLine($"tex {tex.Name}");

                var newtex = CreateTexture(tex);
                newtex.Name = tex.Name;
                hsf.Textures.Add(newtex);
            }

            if (hsf.Textures.Count == 0)
            {
            }

            var newtex2 = CreateTexture(new GenericBitmapTexture("dummy.png"));

            newtex2.Name = "dummy";
            hsf.Textures.Add(newtex2);

            hsf.FogData.Count      = 1;
            hsf.FogData.ColorStart = new Vector4(77, 77, 77, 128);
            hsf.FogData.ColorEnd   = new Vector4(255, 0, 0, 255);
            hsf.FogData.Start      = 0;
            hsf.FogData.End        = 10000;

            Console.WriteLine("Importing Models");

            foreach (var model in scene.Models)
            {
                foreach (var material in model.GetMaterials())
                {
                    var mat = HSF_MaterialConverter.Import($"mat1.json");
                    mat.MaterialData.VertexMode = 2;
                    mat.Name = material.Name;
                    hsf.Materials.Add(mat);

                    if (material.TextureMaps.Count > 0)
                    {
                        var texMap = material.TextureMaps[0].Name;
                        int index  = hsf.Textures.FindIndex(x => x.Name == texMap);
                        if (index != -1)
                        {
                            mat.Textures[0].Item2.TextureIndex = index;
                        }
                    }
                    mat.Textures[0].Item2.WrapS = 1;
                    mat.Textures[0].Item2.WrapT = 1;
                }

                if (hsf.Materials.Count == 0)
                {
                    var mat = HSF_MaterialConverter.Import($"mat1.json");
                    mat.MaterialData.VertexMode = 2;
                    mat.Name = "Basic";
                    hsf.Materials.Add(mat);
                }

                foreach (var mesh in model.Meshes)
                {
                    root.ChildrenCount += 1;

                    List <Vector3> positions = new List <Vector3>();
                    List <Vector3> normals   = new List <Vector3>();
                    List <Vector2> texCoords = new List <Vector2>();
                    List <Vector4> colors    = new List <Vector4>();

                    for (int v = 0; v < mesh.Vertices.Count; v++)
                    {
                        var vertex = mesh.Vertices[v];

                        if (!positions.Contains(vertex.Position))
                        {
                            positions.Add(vertex.Position);
                        }

                        if (!normals.Contains(vertex.Normal))
                        {
                            normals.Add(vertex.Normal);
                        }

                        if (vertex.Colors.Length > 0)
                        {
                            if (!colors.Contains(vertex.Colors[0]))
                            {
                                colors.Add(vertex.Colors[0]);
                            }
                        }
                        if (vertex.TexCoords.Length > 0)
                        {
                            if (!texCoords.Contains(vertex.TexCoords[0]))
                            {
                                texCoords.Add(vertex.TexCoords[0]);
                            }
                        }
                    }

                    var bounding = GenerateBoundingBox(mesh);

                    ObjectData objData = ObjectDataSection.CreateNewObject(ObjectType.Mesh);
                    objData.CullBoxMax     = bounding.Max;
                    objData.CullBoxMin     = bounding.Min;
                    objData.AttributeIndex = 0;
                    objData.ParentIndex    = 0;
                    hsf.ObjectData.Objects.Add(objData);
                    hsf.ObjectData.ObjectNames.Add(mesh.Name);

                    Mesh msh = new Mesh(objData, mesh.Name);
                    msh.Positions.AddRange(positions);
                    msh.Normals.AddRange(normals);
                    msh.TexCoords.AddRange(texCoords);
                    msh.Colors.AddRange(colors);

                    foreach (var group in mesh.PolygonGroups)
                    {
                        int materialIndex = 0;
                        if (group.MaterialIndex != -1 && hsf.Materials.Count > group.MaterialIndex)
                        {
                            materialIndex = group.MaterialIndex;
                        }

                        byte mode = 2;
                        if (colors.Count > 0)
                        {
                            mode = 5;
                        }

                        hsf.Materials[materialIndex].MaterialData.VertexMode = mode;

                        Weight[] weightList = new Weight[mesh.Vertices.Count];
                        for (int i = 0; i < mesh.Vertices.Count; i++)
                        {
                            Weight vertWeight = new Weight();
                            for (int j = 0; j < mesh.Vertices[i].BoneIndices.Count; j++)
                            {
                                int   boneId     = mesh.Vertices[i].BoneIndices[j];
                                float boneWeight = mesh.Vertices[i].BoneWeights[j];
                                vertWeight.AddWeight(boneWeight, boneId);
                            }
                            weightList[i] = vertWeight;
                        }

                        List <PrimitiveBrawl> primlist = new List <PrimitiveBrawl>();

                        //Turn triangle set into triangle strips
                        if (settings.UseTriStrips)
                        {
                            TriStripper stripper = new TriStripper(mesh.Faces.ToArray(), weightList);
                            primlist = stripper.Strip();
                        }
                        else
                        {
                            primlist = new List <PrimitiveBrawl>();
                            for (int i = 0; i < mesh.Faces.Count; i++)
                            {
                                PrimitiveBrawl prim = new PrimitiveBrawl(PrimType.TriangleList); // Trilist
                                prim.Indices.Add(mesh.Faces[i++]);
                                prim.Indices.Add(mesh.Faces[i++]);
                                prim.Indices.Add(mesh.Faces[i]);
                                primlist.Add(prim);
                            }
                        }

                        foreach (var primitive in primlist)
                        {
                            PrimitiveObject prim = new PrimitiveObject();
                            prim.Type = PrimitiveType.Triangle;
                            if (settings.UseTriStrips)
                            {
                                prim.Type = PrimitiveType.TriangleStrip;
                            }

                            prim.Flags   = 0;
                            prim.NbtData = new OpenTK.Vector3(1, 0, 0);
                            if (hsf.Materials.Count > materialIndex)
                            {
                                prim.MaterialIndex = materialIndex;
                            }

                            if (settings.UseTriStrips)
                            {
                                prim.Vertices = new VertexGroup[primitive.Indices.Count + 1];
                            }
                            else
                            {
                                prim.Vertices    = new VertexGroup[4];
                                prim.Vertices[3] = new VertexGroup(); //Empty last grou
                            }
                            msh.Primitives.Add(prim);

                            if (prim.Type == PrimitiveType.TriangleStrip)
                            {
                                for (int i = 0; i < 3; i++)
                                {
                                    var vertexIndex = (int)primitive.Indices[i];
                                    var vertex      = mesh.Vertices[vertexIndex];

                                    short colorIndex    = -1;
                                    short texCoordIndex = -1;
                                    short positionIndex = (short)positions.IndexOf(vertex.Position);
                                    short normaIndex    = (short)normals.IndexOf(vertex.Normal);

                                    if (vertex.Colors.Length > 0)
                                    {
                                        colorIndex = (short)colors.IndexOf(vertex.Colors[0]);
                                    }
                                    if (vertex.TexCoords.Length > 0)
                                    {
                                        texCoordIndex = (short)texCoords.IndexOf(vertex.TexCoords[0]);
                                    }

                                    prim.Vertices[i] = new VertexGroup()
                                    {
                                        PositionIndex = positionIndex,
                                        UVIndex       = texCoordIndex,
                                        ColorIndex    = colorIndex,
                                        NormalIndex   = normaIndex,
                                    };
                                }

                                prim.Vertices[3] = new VertexGroup();
                                for (int i = 4; i < prim.Vertices.Length; i++)
                                {
                                    var vertexIndex = (int)primitive.Indices[i - 1];
                                    var vertex      = mesh.Vertices[vertexIndex];

                                    short colorIndex    = -1;
                                    short texCoordIndex = -1;
                                    short positionIndex = (short)positions.IndexOf(vertex.Position);
                                    short normaIndex    = (short)normals.IndexOf(vertex.Normal);

                                    if (vertex.Colors.Length > 0)
                                    {
                                        colorIndex = (short)colors.IndexOf(vertex.Colors[0]);
                                    }
                                    if (vertex.TexCoords.Length > 0)
                                    {
                                        texCoordIndex = (short)texCoords.IndexOf(vertex.TexCoords[0]);
                                    }

                                    prim.Vertices[i] = new VertexGroup()
                                    {
                                        PositionIndex = positionIndex,
                                        UVIndex       = texCoordIndex,
                                        ColorIndex    = colorIndex,
                                        NormalIndex   = normaIndex,
                                    };
                                }
                            }
                            else
                            {
                                for (int i = 0; i < primitive.Indices.Count; i++)
                                {
                                    var vertexIndex = (int)primitive.Indices[i];
                                    var vertex      = mesh.Vertices[vertexIndex];

                                    short colorIndex    = -1;
                                    short texCoordIndex = -1;
                                    short positionIndex = (short)positions.IndexOf(vertex.Position);
                                    short normaIndex    = (short)normals.IndexOf(vertex.Normal);

                                    if (vertex.Colors.Length > 0)
                                    {
                                        colorIndex = (short)colors.IndexOf(vertex.Colors[0]);
                                    }
                                    if (vertex.TexCoords.Length > 0)
                                    {
                                        texCoordIndex = (short)texCoords.IndexOf(vertex.TexCoords[0]);
                                    }

                                    prim.Vertices[i] = new VertexGroup()
                                    {
                                        PositionIndex = positionIndex,
                                        UVIndex       = texCoordIndex,
                                        ColorIndex    = colorIndex,
                                        NormalIndex   = normaIndex,
                                    };
                                }
                            }
                        }
                    }

                    hsf.Meshes.Add(msh);
                }
            }

            Console.WriteLine("Finished generating HSF binary!");

            return(hsf);
        }
Пример #2
0
        public void Read(FileReader reader)
        {
            reader.SetByteOrder(true);

            //First get the string table so we can use it for the sections before it
            using (reader.TemporarySeek(0x0A8, System.IO.SeekOrigin.Begin)) {
                StringTableOffset = reader.ReadUInt32();
                StringTableSize   = reader.ReadUInt32();
            }

            //Next get object data. This section is necessary to link data
            using (reader.TemporarySeek(72, System.IO.SeekOrigin.Begin)) {
                ObjectData = ReadSection <ObjectDataSection>(reader, this); //Nodes/bones
            }

            //Create a list of all the meshes from objects
            for (int i = 0; i < ObjectData.Objects.Count; i++)
            {
                if (ObjectData.Objects[i].Type == ObjectType.Mesh)
                {
                    Meshes.Add(new Mesh(ObjectData.Objects[i], ObjectData.ObjectNames[i]));
                }
            }

            reader.ReadSignature(3, "HSF");
            Version = reader.ReadString(4, Encoding.ASCII); //Always V037?
            reader.ReadByte();
            FogData       = ReadSection <FogSection>(reader, this);
            ColorData     = ReadSection <ColorSection>(reader, this);
            MaterialData  = ReadSection <MaterialSection>(reader, this);
            AttributeData = ReadSection <AttributeSection>(reader, this);
            PositionData  = ReadSection <PositionSection>(reader, this);
            NormalData    = ReadSection <NormalSection>(reader, this);
            TexCoordData  = ReadSection <TexCoordSection>(reader, this);
            FaceData      = ReadSection <FaceDataSection>(reader, this); //Primative face data
            reader.Seek(8);                                              //Object data (already read from above)
            TextureData  = ReadSection <TextureSection>(reader, this);
            PaletteData  = ReadSection <PaletteSection>(reader, this);
            MotionData   = ReadSection <MotionDataSection>(reader, this);
            CenvData     = ReadSection <CenvDataSection>(reader, this);
            SkeletonData = ReadSection <SkeletonDataSection>(reader, this);

            //Unused sections
            //-----------
            PartData         = ReadSection <PartDataSection>(reader, this);
            ClusterData      = ReadSection <ClusterDataSection>(reader, this);
            ShapeData        = ReadSection <ShapeDataSection>(reader, this);
            MapAttributeData = ReadSection <MapAttributeDataSection>(reader, this);
            //-----------

            MatrixData = ReadSection <MatrixDataSection>(reader, this);
            SymbolData = ReadSection <SymbolDataSection>(reader, this);
            reader.ReadUInt32(); //StringTableOffset
            reader.ReadUInt32(); //StringTableSize

            /*       List<ObjectDataNode> objects = new List<ObjectDataNode>();
             *     foreach (var obj in ObjectData.Objects)
             *         objects.Add(new ObjectDataNode(obj));
             *
             *     foreach (var obj in objects)
             *     {
             *         var data = obj.ObjectData;
             *         var symbol = data.SymbolIndex;
             *         for (int i = 0; i < data.ChildrenCount; i++)
             *             obj.Children.Add(objects[SymbolData.SymbolIndices[symbol++]]);
             *
             *         if (data.ParentIndex != -1) {
             *             obj.Parent = objects[(int)data.ParentIndex];
             *         }
             *     }
             *
             *     foreach (var obj in objects) {
             *         if (obj.Parent == null)
             *             ObjectRoots.Add(obj);
             *     }
             *
             *     objects.Clear();*/

            foreach (var material in Materials)
            {
                var matData = material.MaterialData;
                if (matData.TextureCount > 0)
                {
                    var symbol = matData.FirstSymbol;
                    for (int i = 0; i < matData.TextureCount; i++)
                    {
                        var index = SymbolData.SymbolIndices[symbol++];
                        var name  = AttributeData.AttributeNames[index];
                        material.Textures.Add(Tuple.Create(name, AttributeData.Attributes[index]));
                    }
                }
            }

            ObjectData.ReadEffectMeshes(reader, this);
        }