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); }
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); }