public override void Read(FileReader reader, HsfFile header) { List <ComponentData> Components = reader.ReadMultipleStructs <ComponentData>(this.Count); long pos = reader.Position; var ExtOffset = pos; foreach (var att in Components) { ExtOffset += att.DataCount * 48; } foreach (var comp in Components) { List <PrimitiveObject> primatives = new List <PrimitiveObject>(); reader.SeekBegin(pos + comp.DataOffset); for (int i = 0; i < comp.DataCount; i++) { var prim = new PrimitiveObject(); primatives.Add(prim); prim.Type = (PrimitiveType)reader.ReadUInt16(); prim.Flags = reader.ReadUInt16(); prim.MaterialIndex = prim.Flags & 0xFFF; prim.FlagValue = prim.Flags >> 12; int primCount = 3; if (prim.Type == PrimitiveType.Triangle || prim.Type == PrimitiveType.Quad) { primCount = 4; } prim.Vertices = reader.ReadMultipleStructs <VertexGroup>(primCount).ToArray(); if (prim.Type == PrimitiveType.TriangleStrip) { primCount = reader.ReadInt32(); var offset = reader.ReadUInt32(); var temp = reader.Position; reader.Position = ExtOffset + offset * 8; var verts = reader.ReadMultipleStructs <VertexGroup>(primCount).ToArray(); reader.Position = temp; prim.TriCount = prim.Vertices.Length; var newVert = new VertexGroup[prim.Vertices.Length + primCount + 1]; //Copy the first 3 group to the full vertex group Array.Copy(prim.Vertices, 0, newVert, 0, prim.Vertices.Length); //Make the 4th group set as the second group newVert[3] = newVert[1]; //Copy the rest of the groups in the strip Array.Copy(verts, 0, newVert, prim.Vertices.Length + 1, verts.Length); prim.Vertices = newVert; } prim.NbtData = reader.ReadVec3(); } header.AddPrimitiveComponent(Components.IndexOf(comp), primatives); } }
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); }