public override IOModel GetIOModel() { var iomodel = new IOModel(); iomodel.Skeleton = (SBSkeleton)Skeleton; List <SBHsdBone> bones = new List <SBHsdBone>(); foreach (SBHsdBone bone in Skeleton.Bones) { bones.Add(bone); } Dictionary <HSDStruct, string> tobjToName = new Dictionary <HSDStruct, string>(); foreach (var tex in tobjToSurface) { tex.Value.Name = $"TOBJ_{iomodel.Textures.Count}"; tobjToName.Add(tex.Key, tex.Value.Name); iomodel.Textures.Add(tex.Value); } foreach (SBHsdMesh me in GetMeshObjects()) { var dobj = me.DOBJ; var parent = Skeleton.Bones[0]; foreach (var b in Skeleton.Bones) { if (b is SBHsdBone bone) { if (bone.GetJOBJ().Dobj != null) { if (bone.GetJOBJ().Dobj.List.Contains(dobj)) { parent = b; break; } } } } var iomesh = new IOMesh(); iomesh.Name = me.Name; iomodel.Meshes.Add(iomesh); iomesh.HasPositions = true; iomesh.HasColor = true; iomesh.HasNormals = true; iomesh.HasBoneWeights = true; iomesh.HasUV0 = true; if (dobj.Pobj != null) { foreach (var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); var vertices = GX_VertexAccessor.GetDecodedVertices(dl, pobj); HSD_Envelope[] bindGroups = null;; if (pobj.EnvelopeWeights != null) { bindGroups = pobj.EnvelopeWeights; } var offset = 0; foreach (var v in dl.Primitives) { List <GX_Vertex> strip = new List <GX_Vertex>(); for (int i = 0; i < v.Count; i++) { strip.Add(vertices[offset + i]); } offset += v.Count; iomesh.Vertices.AddRange(ConvertGXDLtoTriangleList(v.PrimitiveType, SBHsdMesh.GXVertexToHsdVertex(strip, bones, bindGroups), (SBHsdBone)parent)); } } } iomesh.Optimize(); // flip faces var temp = iomesh.Indices.ToArray(); iomesh.Indices.Clear(); for (int i = 0; i < temp.Length; i += 3) { if (i + 2 < temp.Length) { iomesh.Indices.Add(temp[i + 2]); iomesh.Indices.Add(temp[i + 1]); iomesh.Indices.Add(temp[i]); } else { break; } } iomesh.MaterialIndex = iomodel.Materials.Count; IOMaterialPhong mat = new IOMaterialPhong(); mat.Name = iomesh.Name + "_material"; if (dobj.Mobj.Material != null) { mat.DiffuseColor = dobj.Mobj.Material.DiffuseColor; mat.SpecularColor = dobj.Mobj.Material.SpecularColor; mat.AmbientColor = dobj.Mobj.Material.AmbientColor; } if (dobj.Mobj.Textures != null) { mat.DiffuseTexture = tobjToName[dobj.Mobj.Textures._s]; } iomodel.Materials.Add(mat); } return(iomodel); }
public override IOScene GetIOModel() { IOScene scene = new IOScene(); IOModel iomodel = new IOModel(); scene.Models.Add(iomodel); iomodel.Skeleton = ((SBSkeleton)Skeleton).ToIOSkeleton(); // bone indices List <SBHsdBone> bones = new List <SBHsdBone>(); foreach (SBHsdBone bone in Skeleton.Bones) { bones.Add(bone); } // gather textures Dictionary <HSDStruct, string> tobjToName = new Dictionary <HSDStruct, string>(); List <SBSurface> textures = new List <SBSurface>(); foreach (var tex in tobjToSurface) { tex.Value.Name = $"TOBJ_{textures.Count}"; tobjToName.Add(tex.Key, tex.Value.Name); textures.Add(tex.Value); } // process mesh foreach (SBHsdMesh me in GetMeshObjects()) { var dobj = me.DOBJ; var parent = Skeleton.Bones[0]; foreach (var b in Skeleton.Bones) { if (b is SBHsdBone bone) { if (bone.GetJOBJ().Dobj != null) { if (bone.GetJOBJ().Dobj.List.Contains(dobj)) { parent = b; break; } } } } var iomesh = new IOMesh(); iomesh.Name = me.Name; iomodel.Meshes.Add(iomesh); IOPolygon poly = new IOPolygon(); iomesh.Polygons.Add(poly); if (dobj.Pobj != null) { foreach (var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); var vertices = GX_VertexAccessor.GetDecodedVertices(dl, pobj); HSD_Envelope[] bindGroups = null;; if (pobj.EnvelopeWeights != null) { bindGroups = pobj.EnvelopeWeights; } var offset = 0; foreach (var v in dl.Primitives) { List <GX_Vertex> strip = new List <GX_Vertex>(); for (int i = 0; i < v.Count; i++) { strip.Add(vertices[offset + i]); } offset += v.Count; iomesh.Vertices.AddRange(ConvertGXDLtoTriangleList(v.PrimitiveType, SBHsdMesh.GXVertexToHsdVertex(strip, bones, bindGroups), (SBHsdBone)parent)); } } } // flip faces for (int i = 0; i < iomesh.Vertices.Count; i += 3) { if (i + 2 < iomesh.Vertices.Count) { poly.Indicies.Add(i + 2); poly.Indicies.Add(i + 1); poly.Indicies.Add(i); } else { break; } } poly.MaterialName = iomesh.Name + "_material"; // create material IOMaterial mat = new IOMaterial(); mat.Name = iomesh.Name + "_material"; if (dobj.Mobj.Material != null) { mat.DiffuseColor = new System.Numerics.Vector4( dobj.Mobj.Material.DiffuseColor.R / 255f, dobj.Mobj.Material.DiffuseColor.G / 255f, dobj.Mobj.Material.DiffuseColor.B / 255f, dobj.Mobj.Material.DiffuseColor.A / 255f); mat.SpecularColor = new System.Numerics.Vector4( dobj.Mobj.Material.SpecularColor.R / 255f, dobj.Mobj.Material.SpecularColor.G / 255f, dobj.Mobj.Material.SpecularColor.B / 255f, dobj.Mobj.Material.SpecularColor.A / 255f); mat.AmbientColor = new System.Numerics.Vector4( dobj.Mobj.Material.AmbientColor.R / 255f, dobj.Mobj.Material.AmbientColor.G / 255f, dobj.Mobj.Material.AmbientColor.B / 255f, dobj.Mobj.Material.AmbientColor.A / 255f); mat.Alpha = dobj.Mobj.Material.Alpha; mat.Shininess = dobj.Mobj.Material.Shininess; } if (dobj.Mobj.Textures != null) { mat.DiffuseMap = new IOTexture() { Name = tobjToName[dobj.Mobj.Textures._s], FilePath = tobjToName[dobj.Mobj.Textures._s] } } ; scene.Materials.Add(mat); } return(scene); }