private static List <UltimateVertex> CreateVertices(MESH mesh, ISBSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices) { // Read attribute values. var positions = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject); var normals = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject); var tangents = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject); var map1Values = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject); var uvSetValues = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject); var uvSet1Values = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject); var bake1Values = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject); var colorSet1Values = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject); var colorSet5Values = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject); var generatedBitangents = GenerateBitangents(vertexIndices, positions, map1Values); var riggingAccessor = new SSBHRiggingAccessor(mesh); var influences = riggingAccessor.ReadRiggingBuffer(meshObject.Name, (int)meshObject.SubMeshIndex); var indexByBoneName = new Dictionary <string, int>(); if (Skeleton != null) { var Bones = Skeleton.Bones; for (int i = 0; i < Bones.Length; i++) { indexByBoneName.Add(Bones[i].Name, i); } } GetRiggingData(positions, influences, indexByBoneName, out IVec4[] boneIndices, out Vector4[] boneWeights);
private static List <UltimateVertex> CreateVertices(MESH mesh, ISBSkeleton Skeleton, MeshObject meshObject, SSBHVertexAccessor vertexAccessor, uint[] vertexIndices) { // Read attribute values. var positions = vertexAccessor.ReadAttribute("Position0", 0, meshObject.VertexCount, meshObject); var normals = vertexAccessor.ReadAttribute("Normal0", 0, meshObject.VertexCount, meshObject); var tangents = vertexAccessor.ReadAttribute("Tangent0", 0, meshObject.VertexCount, meshObject); var map1Values = vertexAccessor.ReadAttribute("map1", 0, meshObject.VertexCount, meshObject); var uvSetValues = vertexAccessor.ReadAttribute("uvSet", 0, meshObject.VertexCount, meshObject); var uvSet1Values = vertexAccessor.ReadAttribute("uvSet1", 0, meshObject.VertexCount, meshObject); var uvSet2Values = vertexAccessor.ReadAttribute("uvSet2", 0, meshObject.VertexCount, meshObject); var bake1Values = vertexAccessor.ReadAttribute("bake1", 0, meshObject.VertexCount, meshObject); var colorSet1Values = vertexAccessor.ReadAttribute("colorSet1", 0, meshObject.VertexCount, meshObject); var colorSet2Values = vertexAccessor.ReadAttribute("colorSet2", 0, meshObject.VertexCount, meshObject); var colorSet21Values = vertexAccessor.ReadAttribute("colorSet21", 0, meshObject.VertexCount, meshObject); var colorSet22Values = vertexAccessor.ReadAttribute("colorSet22", 0, meshObject.VertexCount, meshObject); var colorSet23Values = vertexAccessor.ReadAttribute("colorSet23", 0, meshObject.VertexCount, meshObject); var colorSet3Values = vertexAccessor.ReadAttribute("colorSet3", 0, meshObject.VertexCount, meshObject); var colorSet4Values = vertexAccessor.ReadAttribute("colorSet4", 0, meshObject.VertexCount, meshObject); var colorSet5Values = vertexAccessor.ReadAttribute("colorSet5", 0, meshObject.VertexCount, meshObject); var colorSet6Values = vertexAccessor.ReadAttribute("colorSet6", 0, meshObject.VertexCount, meshObject); var colorSet7Values = vertexAccessor.ReadAttribute("colorSet7", 0, meshObject.VertexCount, meshObject); // Generate bitangents. // TODO: Use vec4 tangents instead. var positionVectors = GetVectors3d(positions); var normalVectors = GetVectors3d(normals); var map1Vectors = GetVectors2d(map1Values); SFGraphics.Utils.TriangleListUtils.CalculateTangentsBitangents(positionVectors, normalVectors, map1Vectors, (int[])(object)vertexIndices, out Vector3[] tangentVectors, out Vector3[] bitangentVectors);
static Mesh mesh(int N = 4) { Node[,] nodes_2D = new Node[2, N + 1]; Vector3 dir = Vector3.up, start = Vector3.right; float a_s = 360f / N; for (int x = 0; x <= 1; x += 1) { Vector3 o = dir * x; for (int y = 0; y <= N; y += 1) { Vector3 v = Z.Rotate(start, -dir, a_s * y); nodes_2D[x, y] = new Node() { pos = o + v, wrap = new Vector2(x, 0) }; } } return(MESH.mesh(nodes_2D)); }
public void Read(FileReader reader) { reader.ReadSignature(4, "GMX2"); reader.SetByteOrder(true); HeaderSize = reader.ReadUInt32(); while (reader.Position < reader.BaseStream.Length) { long pos = reader.Position; string Magic = reader.ReadString(4); uint SectionSize = reader.ReadUInt32(); reader.SeekBegin(pos); switch (Magic) { case "PADX": PADX padding = new PADX(); padding.Read(reader); break; case "INDX": INDX indexGrp = new INDX(); indexGrp.Read(reader, GetLastMesh()); GetLastMesh().IndexGroup = indexGrp; break; case "VMAP": VMAP vmap = new VMAP(); vmap.Read(reader); GetLastMesh().VMapGroup = vmap; break; case "MESH": MESH mesh = new MESH(); mesh.Read(reader); Meshes.Add(mesh); Console.WriteLine($"MESH {mesh.VertexCount} {mesh.FaceCount} {mesh.SkinningFlags} {mesh.VertexSize}"); break; case "VERT": VERT vert = new VERT(); vert.Read(reader, GetLastMesh()); GetLastMesh().VertexGroup = vert; break; case "ENDX": reader.ReadSignature(4, "ENDX"); uint EndSectionSize = reader.ReadUInt32(); break; default: throw new Exception("Unknown section! " + Magic); } reader.SeekBegin(pos + SectionSize); } Console.WriteLine("MESHES " + Meshes.Count); }
public void Write(FileWriter writer, MESH mesh) { writer.WriteSignature("VERT"); writer.Write(Vertices.Count * mesh.VertexSize + 8); for (int v = 0; v < mesh.VertexCount; v++) { if (mesh.VertexSize == 32) { writer.Write(Vertices[v].pos); writer.Write(Vertices[v].nrm); writer.Write(Vertices[v].uv0); } else if (mesh.VertexSize == 36) { writer.Write(Unknowns[v]); writer.Write(Vertices[v].pos); writer.Write(-Vertices[v].nrm); writer.Write(Vertices[v].uv0); } else { throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}"); } } }
// ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- // ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ //==================================================================================================== // ■ START //==================================================================================================== void Start() { var filter = GameObject.MeshFilter; var mesh = filter.sharedMesh; var indexArray = mesh.GetIndices(); var vertexArray = mesh.GetVertices(); var indexList = new List <int>(); for (int i = 0; i < indexArray.Length / 3; i++) { indexList.Add(indexArray[i * 3 + 0]); indexList.Add(indexArray[i * 3 + 1]); indexList.Add(indexArray[i * 3 + 1]); indexList.Add(indexArray[i * 3 + 2]); indexList.Add(indexArray[i * 3 + 2]); indexList.Add(indexArray[i * 3 + 0]); } var newMesh = new MESH(); newMesh.SetVertices(vertexArray); newMesh.SetLineIndices(indexList.ToArray()); filter.mesh = newMesh; }
/// <summary> /// Creates a new vertex accessor for given mesh file /// </summary> /// <param name="meshFile"></param> public SSBHVertexAccessor(MESH meshFile) { if (meshFile == null) { return; } this.meshFile = meshFile; }
public override void Open(string Path) { if (SSBH.TryParseSSBHFile(Path, out ISSBH_File ssbhFile)) { if (ssbhFile is MESH) { mesh = (MESH)ssbhFile; } } }
public void Read(FileReader reader, MESH mesh) { reader.ReadSignature(4, "INDX"); uint SectionSize = reader.ReadUInt32(); Indices = new ushort[mesh.FaceCount]; for (int i = 0; i < mesh.FaceCount; i++) { Indices[i] = reader.ReadUInt16(); } }
//==================================================================================================== // ■ CREATE MESH //==================================================================================================== void CreateMesh() { if (ExplosionMesh == null) { ExplosionMesh = new MESH(); } else { ExplosionMesh.Clear(); } var vertexArray = new float3[PointCount * 2]; var indexArray = new int[(PointCount + 1) * 6]; //Vertex for (int i = 0; i < PointCount; i++) { var p1 = ExplosionSize * PointArray[i]; p1.z = PlanetRadius; p1 = math.normalize(p1) * PlanetRadius; var p2 = ExplosionSize * (1 + ExplosionWidth) * PointArray[i]; p2.z = PlanetRadius; p2 = math.normalize(p2) * PlanetRadius; vertexArray[2 * i + 0] = p1; vertexArray[2 * i + 1] = p2; } //Index for (int i = 0; i < PointCount; i++) { var p0 = i * 2 + 0; var p1 = i * 2 + 1; var p2 = ((i + 1) % PointCount) * 2 + 0; var p3 = ((i + 1) % PointCount) * 2 + 1; indexArray[i * 6 + 0] = p0; indexArray[i * 6 + 1] = p1; indexArray[i * 6 + 2] = p3; indexArray[i * 6 + 3] = p3; indexArray[i * 6 + 4] = p2; indexArray[i * 6 + 5] = p0; } ExplosionMesh.vertices = vertexArray; ExplosionMesh.SetTriangleIndices(indexArray); GameObject.MeshFilter.sharedMesh = ExplosionMesh; }
public SSBHVertexAccessor(MESH meshFile) { if (meshFile == null) { return; } this.meshFile = meshFile; buffers = new BinaryReader[meshFile.VertexBuffers.Length]; for (int i = 0; i < meshFile.VertexBuffers.Length; i++) { buffers[i] = new BinaryReader(new MemoryStream(meshFile.VertexBuffers[i].Buffer)); } indexBuffer = new BinaryReader(new MemoryStream(meshFile.PolygonBuffer)); }
private void MESH() { FileInfo fi = new FileInfo(textBoxFile5.Text); if (!fi.Exists) { richTextBoxStatus.Text = "File [" + fi.FullName + "] does not exist.\r\n"; return; } using (MESH mesh = new MESH(fi)) { mesh.CSSPDHIChanged += CSSPDHIChanged; mesh.ReadFile(); mesh.CSSPDHIChanged -= CSSPDHIChanged; } }
public override void Open() { string ADJB = System.IO.Path.GetDirectoryName(AbsolutePath) + "/model.adjb"; System.Console.WriteLine(ADJB); if (File.Exists(ADJB)) { ExtendedMesh = new ADJB(); ExtendedMesh.Read(ADJB); } if (SSBH.TryParseSSBHFile(AbsolutePath, out ISSBH_File ssbhFile)) { if (ssbhFile is MESH) { mesh = (MESH)ssbhFile; } } }
/// <summary> /// Creates a vertex accessor from given MESH filepath /// </summary> /// <param name="FilePath"></param> public SSBHVertexAccessor(string meshFilePath) { if (SSBH.TryParseSSBHFile(meshFilePath, out ISSBH_File file)) { if (file == null) { throw new FileNotFoundException("File was null"); } if (file is MESH mesh) { meshFile = mesh; } else { throw new FormatException("Given file was not a MESH file"); } } }
static MESH CreateMesh(int boneCount) { var mesh = new MESH("skinned mesh"); mesh.VertexPreprocessor.SetValidationPreprocessors(); var prim = mesh.UsePrimitive(new SharpGLTF.Materials.MaterialBuilder("Default")); var a0 = default(VERTEX); var a1 = default(VERTEX); var a2 = default(VERTEX); var a3 = default(VERTEX); for (int i = 0; i < boneCount; ++i) { var b0 = new VERTEX(new Vector3(-5, i * 10, -5), Vector4.One, (i, 1)); var b1 = new VERTEX(new Vector3(+5, i * 10, -5), Vector4.One, (i, 1)); var b2 = new VERTEX(new Vector3(+5, i * 10, +5), Vector4.One, (i, 1)); var b3 = new VERTEX(new Vector3(-5, i * 10, +5), Vector4.One, (i, 1)); if (i == 0) { prim.AddQuadrangle(b0, b1, b2, b3); } else { prim.AddQuadrangle(b0, b1, a1, a0); prim.AddQuadrangle(b1, b2, a2, a1); prim.AddQuadrangle(b2, b3, a3, a2); prim.AddQuadrangle(b3, b0, a0, a3); } a0 = b0; a1 = b1; a2 = b2; a3 = b3; } prim.AddQuadrangle(a3, a2, a1, a0); return(mesh); }
public void Write(FileWriter writer, MESH mesh) { writer.WriteSignature("VERT"); writer.Write(Vertices.Count * mesh.VertexSize + 8); for (int v = 0; v < mesh.VertexCount; v++) { if (mesh.VertexSize == 32) { writer.Write(Vertices[v].Position); writer.Write(Vertices[v].Normal); writer.Write(Vertices[v].TexCoord0); } else if (mesh.VertexSize == 36 && mesh.SkinningFlags != 0) { writer.Write(Vertices[v].MatrixID); writer.Write(Vertices[v].Position); writer.Write(Vertices[v].Normal); writer.Write(Vertices[v].TexCoord0); } else if (mesh.SkinningFlags != 0 && mesh.SkinningFlags != 0) { writer.Write(Vertices[v].MatrixID); writer.Write(Vertices[v].Position); writer.Write(Vertices[v].Normal); writer.Write((byte)Vertices[v].Color.X); writer.Write((byte)Vertices[v].Color.Y); writer.Write((byte)Vertices[v].Color.Z); writer.Write((byte)Vertices[v].Color.W); writer.Write(Vertices[v].TexCoord0); } else { throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}"); } } }
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 = ((NUMSHB_Node)n).mesh; } if (n.Text.Equals(_model.SkeletonFileName)) { outModel.Skeleton = (RSkeleton)((SKEL_Node)n).GetRenderableNode(); } if (n.Text.Equals(_model.MaterialFileNames[0].MaterialFileName)) { materialFile = ((MATL_Node)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.MaterialLabel, materialIndex++); IOMaterial material = new IOMaterial(); material.Name = entry.MaterialLabel; outModel.Materials.Add(material); foreach (var attr in entry.Attributes) { if (attr.ParamID == MatlEnums.ParamId.Texture0) { IOTexture dif = new IOTexture(); dif.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.MaterialName]; 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); }
public void Read(FileReader reader, MESH mesh) { reader.ReadSignature(4, "VERT"); uint SectionSize = reader.ReadUInt32(); if (mesh.VertexSize == 32) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.Position = reader.ReadVec3(); vert.Normal = reader.ReadVec3(); vert.TexCoord0 = reader.ReadVec2(); Vertices.Add(vert); } } else if (mesh.VertexSize == 12) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.Position = reader.ReadVec3(); Vertices.Add(vert); } } else if (mesh.VertexSize == 20) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.Position = reader.ReadVec3(); vert.TexCoord0 = reader.ReadVec2(); Vertices.Add(vert); } } else if (mesh.VertexSize == 24) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.Position = reader.ReadVec3(); vert.Normal = reader.ReadVec3(); Vertices.Add(vert); } } else if (mesh.VertexSize == 36) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); if (mesh.SkinningFlags != 0) { vert.MatrixID = reader.ReadUInt32(); vert.Position = reader.ReadVec3(); vert.Normal = reader.ReadVec3(); vert.TexCoord0 = reader.ReadVec2(); } else { vert.Position = reader.ReadVec3(); vert.Normal = reader.ReadVec3(); vert.Color = ColorUtility.ToVector4(reader.ReadBytes(4)); vert.TexCoord0 = reader.ReadVec2(); } Vertices.Add(vert); } } else if (mesh.VertexSize == 40) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); if (mesh.SkinningFlags != 0) { vert.MatrixID = reader.ReadUInt32(); //Bone index? vert.Position = reader.ReadVec3(); vert.Normal = reader.ReadVec3(); vert.Color = ColorUtility.ToVector4(reader.ReadBytes(4)); vert.TexCoord0 = reader.ReadVec2(); } else { throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}"); } Vertices.Add(vert); } } else if (mesh.VertexSize == 44) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.Position = reader.ReadVec3(); vert.Normal = reader.ReadVec3(); vert.Color = ColorUtility.ToVector4(reader.ReadBytes(4)); vert.TexCoord0 = reader.ReadVec2(); vert.TexCoord1 = reader.ReadVec2(); Vertices.Add(vert); } } else { throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}"); } }
public bool ExportMeshWithMaterials(Stream meshStream, FileInfo outfile, List <Archive> archives, string matRepo, EUncookExtension eUncookExtension = EUncookExtension.dds, bool isGLBinary = true, bool LodFilter = true) { if (matRepo == null) { throw new Exception("Material Repository Path is not set, Please select a folder in the Material Repository Settings where your textures will output, Generating the complete dump is not required."); } var cr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(false); } DirectoryInfo outDir = new DirectoryInfo(Path.Combine(outfile.DirectoryName, Path.GetFileNameWithoutExtension(outfile.FullName))); MESH.MeshBones meshBones = new MESH.MeshBones(); meshBones.boneCount = cr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count; if (meshBones.boneCount != 0) // for rigid meshes { meshBones.Names = RIG.GetboneNames(cr2w); meshBones.WorldPosn = MESH.GetMeshBonesPosn(cr2w); } RawArmature Rig = MESH.GetNonParentedRig(meshBones); MemoryStream ms = MESH.GetMeshBufferStream(meshStream, cr2w); MeshesInfo meshinfo = MESH.GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = MESH.ContainRawMesh(ms, meshinfo, LodFilter); if (meshBones.boneCount == 0) // for rigid meshes { for (int i = 0; i < expMeshes.Count; i++) { expMeshes[i].weightcount = 0; } } MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones); ModelRoot model = MESH.RawMeshesToGLTF(expMeshes, Rig); if (!outDir.Exists) { Directory.CreateDirectory(outDir.FullName); } ParseMaterials(cr2w, meshStream, outDir, archives, matRepo, eUncookExtension); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } meshStream.Dispose(); meshStream.Close(); return(true); }
//==================================================================================================== // ■ CREATE MESH //==================================================================================================== void CreateMesh() { if (PointList.Count >= 2) { if (WallMesh == null) { WallMesh = new MESH(); } else { WallMesh.Clear(); } int count = PointList.Count; var vertexArray = new float3[count * 4]; var indexArray = new int[(count - 1) * 18 + 12]; //Vertex for (int i = 0; i < count; i++) { var p = PointList[i]; float3 tangent; if (i - 1 >= 0) { var t = PointList[i - 1].Position; tangent = math.normalize(p.Position - t); } else { var t = PointList[i + 1].Position; tangent = math.normalize(t - p.Position); } var center = math.normalize(p.Position); var normal = math.normalize(math.cross(tangent, center)); var gridPosition = p.Position - center * GridDistance; vertexArray[4 * i + 0] = gridPosition - normal * WallWidth; vertexArray[4 * i + 1] = gridPosition + center * WallHeight - normal * WallWidth; vertexArray[4 * i + 2] = gridPosition + center * WallHeight + normal * WallWidth; vertexArray[4 * i + 3] = gridPosition + normal * WallWidth; } //Index for (int i = 0; i < count - 1; i++) { var p0 = i * 4 + 0; var p1 = i * 4 + 1; var p2 = i * 4 + 2; var p3 = i * 4 + 3; var p4 = (i + 1) * 4 + 0; var p5 = (i + 1) * 4 + 1; var p6 = (i + 1) * 4 + 2; var p7 = (i + 1) * 4 + 3; indexArray[i * 18 + 0] = p4; indexArray[i * 18 + 1] = p5; indexArray[i * 18 + 2] = p1; indexArray[i * 18 + 3] = p1; indexArray[i * 18 + 4] = p0; indexArray[i * 18 + 5] = p4; indexArray[i * 18 + 6] = p1; indexArray[i * 18 + 7] = p5; indexArray[i * 18 + 8] = p6; indexArray[i * 18 + 9] = p6; indexArray[i * 18 + 10] = p2; indexArray[i * 18 + 11] = p1; indexArray[i * 18 + 12] = p3; indexArray[i * 18 + 13] = p2; indexArray[i * 18 + 14] = p6; indexArray[i * 18 + 15] = p6; indexArray[i * 18 + 16] = p7; indexArray[i * 18 + 17] = p3; } //begin, end close var v0 = 0 * 4 + 0; var v1 = 0 * 4 + 1; var v2 = 0 * 4 + 2; var v3 = 0 * 4 + 3; var v4 = (count - 1) * 4 + 0; var v5 = (count - 1) * 4 + 1; var v6 = (count - 1) * 4 + 2; var v7 = (count - 1) * 4 + 3; int j = count - 1; indexArray[j * 18 + 0] = v0; indexArray[j * 18 + 1] = v1; indexArray[j * 18 + 2] = v2; indexArray[j * 18 + 3] = v2; indexArray[j * 18 + 4] = v3; indexArray[j * 18 + 5] = v0; indexArray[j * 18 + 6] = v7; indexArray[j * 18 + 7] = v6; indexArray[j * 18 + 8] = v5; indexArray[j * 18 + 9] = v5; indexArray[j * 18 + 10] = v4; indexArray[j * 18 + 11] = v7; WallMesh.vertices = vertexArray; WallMesh.SetTriangleIndices(indexArray); GameObject.MeshFilter.sharedMesh = WallMesh; } }
private static void ContainedMeshToGLTF(List <RawMeshContainer> meshes, FileInfo outfile) { var scene = new SharpGLTF.Scenes.SceneBuilder(); int mIndex = -1; foreach (var mesh in meshes) { ++mIndex; long indCount = mesh.indices.Length; var expmesh = new MESH(string.Format(Path.GetFileNameWithoutExtension(outfile.FullName) + "_mesh_{0}", mIndex)); var prim = expmesh.UsePrimitive(new MaterialBuilder("Default")); for (long i = 0; i < indCount; i += 3) { uint idx0 = mesh.indices[i + 1]; uint idx1 = mesh.indices[i]; uint idx2 = mesh.indices[i + 2]; //VPNT Vec3 p_0 = new Vec3(mesh.vertices[idx0].X, mesh.vertices[idx0].Y, mesh.vertices[idx0].Z); Vec3 n_0 = new Vec3(mesh.normals[idx0].X, mesh.normals[idx0].Y, mesh.normals[idx0].Z); Vec4 t_0 = new Vec4(new Vec3(mesh.tangents[idx0].X, mesh.tangents[idx0].Y, mesh.tangents[idx0].Z), 1); Vec3 p_1 = new Vec3(mesh.vertices[idx1].X, mesh.vertices[idx1].Y, mesh.vertices[idx1].Z); Vec3 n_1 = new Vec3(mesh.normals[idx1].X, mesh.normals[idx1].Y, mesh.normals[idx1].Z); Vec4 t_1 = new Vec4(new Vec3(mesh.tangents[idx1].X, mesh.tangents[idx1].Y, mesh.tangents[idx1].Z), 1); Vec3 p_2 = new Vec3(mesh.vertices[idx2].X, mesh.vertices[idx2].Y, mesh.vertices[idx2].Z); Vec3 n_2 = new Vec3(mesh.normals[idx2].X, mesh.normals[idx2].Y, mesh.normals[idx2].Z); Vec4 t_2 = new Vec4(new Vec3(mesh.tangents[idx2].X, mesh.tangents[idx2].Y, mesh.tangents[idx2].Z), 1); //VCT Vec2 tx0_0 = new Vec2(mesh.tx0coords[idx0].X, mesh.tx0coords[idx0].Y); Vec2 tx1_0 = new Vec2(mesh.tx1coords[idx0].X, mesh.tx1coords[idx0].Y); Vec2 tx0_1 = new Vec2(mesh.tx0coords[idx1].X, mesh.tx0coords[idx1].Y); Vec2 tx1_1 = new Vec2(mesh.tx1coords[idx1].X, mesh.tx1coords[idx1].Y); Vec2 tx0_2 = new Vec2(mesh.tx0coords[idx2].X, mesh.tx0coords[idx2].Y); Vec2 tx1_2 = new Vec2(mesh.tx1coords[idx2].X, mesh.tx1coords[idx2].Y); Vec4 col_0 = new Vec4(mesh.colors[idx0].X, mesh.colors[idx0].Y, mesh.colors[idx0].Z, mesh.colors[idx0].W); Vec4 col_1 = new Vec4(mesh.colors[idx1].X, mesh.colors[idx1].Y, mesh.colors[idx1].Z, mesh.colors[idx1].W); Vec4 col_2 = new Vec4(mesh.colors[idx2].X, mesh.colors[idx2].Y, mesh.colors[idx2].Z, mesh.colors[idx2].W); // vertex build var v0 = new VERTEX(new VPNT(p_0, n_0, t_0), new VCT(col_0, tx0_0, tx1_0)); var v1 = new VERTEX(new VPNT(p_1, n_1, t_1), new VCT(col_1, tx0_1, tx1_1)); var v2 = new VERTEX(new VPNT(p_2, n_2, t_2), new VCT(col_2, tx0_2, tx1_2)); // triangle build prim.AddTriangle(v0, v1, v2); } scene.AddRigidMesh(expmesh, System.Numerics.Matrix4x4.Identity); } var model = scene.ToGltf2(); model.SaveGLB(Path.GetFullPath(outfile.FullName).Replace(".mesh", ".glb")); }
public static Mesh mesh(int N = 32) { #region Ball /* * Vector3 a = Vector3.right, * b = Vector3.up, * K = -Vector3.forward; * * Node[,] nodes_2D = new Node[N + 1, N + 1]; * float A_s = 180f / N, * a_s = 2f * A_s; * * for (int y = 0; y <= N; y += 1) * { * Vector3 V = Z.Rotate(-b, K, y * A_s); * float _x = Z.dot(V, a), * _y = Z.dot(V, b); * * for (int x = 0; x <= N; x += 1) * { * Vector3 pos = Z.Rotate(a, b, x * a_s); * * nodes_2D[x, y] = new Node() * { * pos = pos * _x + b * _y, * wrap = new Vector2(x, y) / N * }; * } * } */ #endregion float[] R = new float[3] { 0f, 0.7f, 1f }; int l = R.Length - 1; Node[,] nodes_2D = new Node[l + 1, N + 1]; Vector3 k = Vector3.forward, start = Vector3.up; float a_s = 360f / N; for (int x = 0; x <= l; x += 1) { for (int y = 0; y <= N; y += 1) { Vector3 pos = Z.Rotate(start, -k, a_s * y); nodes_2D[x, y] = new Node() { pos = pos * R[x], wrap = new Vector2(x, 0) / l }; } } return(MESH.mesh(nodes_2D)); }
/// <summary> /// Creates and returns a mesh file /// </summary> /// <returns></returns> public MESH GetMeshFile() { MESH mesh = new MESH { //TODO: bounding box stuff // Rigging Objects = new MeshObject[meshes.Count] }; // create mesh objects and buffers BinaryWriter vertexBuffer1 = new BinaryWriter(new MemoryStream()); BinaryWriter vertexBuffer2 = new BinaryWriter(new MemoryStream()); // there are actually 4 buffers, but only 2 seem to be used BinaryWriter indexBuffer = new BinaryWriter(new MemoryStream()); int finalBufferOffset = 0; int meshIndex = 0; Dictionary <string, int> MeshGroups = new Dictionary <string, int>(); List <MeshRiggingGroup> RiggingGroups = new List <MeshRiggingGroup>(); foreach (var tempmesh in meshes) { MeshObject mo = new MeshObject { Name = tempmesh.Name }; if (MeshGroups.ContainsKey(mo.Name)) { MeshGroups[mo.Name] += 1; } else { MeshGroups.Add(mo.Name, 0); } mo.SubMeshIndex = MeshGroups[mo.Name]; mo.BoundingSphereX = tempmesh.BoundingSphere.X; mo.BoundingSphereY = tempmesh.BoundingSphere.Y; mo.BoundingSphereZ = tempmesh.BoundingSphere.Z; mo.BoundingSphereRadius = tempmesh.BoundingSphere.W; mo.MaxBoundingBoxX = tempmesh.BBMax.X; mo.MaxBoundingBoxY = tempmesh.BBMax.Y; mo.MaxBoundingBoxZ = tempmesh.BBMax.Z; mo.MinBoundingBoxX = tempmesh.BBMin.X; mo.MinBoundingBoxY = tempmesh.BBMin.Y; mo.MinBoundingBoxZ = tempmesh.BBMin.Z; mo.OBBCenterX = tempmesh.OBBCenter.X; mo.OBBCenterY = tempmesh.OBBCenter.Y; mo.OBBCenterZ = tempmesh.OBBCenter.Z; mo.OBBSizeX = tempmesh.OBBSize.X; mo.OBBSizeY = tempmesh.OBBSize.Y; mo.OBBSizeZ = tempmesh.OBBSize.Z; mo.M11 = tempmesh.OBBMatrix3x3[0]; mo.M12 = tempmesh.OBBMatrix3x3[1]; mo.M13 = tempmesh.OBBMatrix3x3[2]; mo.M21 = tempmesh.OBBMatrix3x3[3]; mo.M22 = tempmesh.OBBMatrix3x3[4]; mo.M23 = tempmesh.OBBMatrix3x3[5]; mo.M31 = tempmesh.OBBMatrix3x3[6]; mo.M32 = tempmesh.OBBMatrix3x3[7]; mo.M33 = tempmesh.OBBMatrix3x3[8]; // Create Rigging RiggingGroups.Add(SSBHRiggingCompiler.CreateRiggingGroup(mo.Name, (int)mo.SubMeshIndex, tempmesh.Influences.ToArray())); // set object mesh.Objects[meshIndex++] = mo; mo.ParentBoneName = tempmesh.ParentBone; if (tempmesh.Influences.Count > 0 && (tempmesh.ParentBone == null || tempmesh.ParentBone.Equals(""))) { mo.HasRigging = 1; } int Stride1 = 0; int Stride2 = 0; mo.VertexOffset = (int)vertexBuffer1.BaseStream.Length; mo.VertexOffset2 = (int)vertexBuffer2.BaseStream.Length; mo.ElementOffset = (uint)indexBuffer.BaseStream.Length; // gather strides mo.Attributes = new MeshAttribute[tempmesh.VertexData.Count]; int attributeIndex = 0; foreach (var keypair in tempmesh.VertexData) { MeshAttribute attr = new MeshAttribute { Name = GetAttributeName(keypair.Key), Index = GetAttributeIndex(keypair.Key), BufferIndex = GetBufferIndex(keypair.Key), DataType = GetAttributeDataType(keypair.Key), BufferOffset = (GetBufferIndex(keypair.Key) == 0) ? Stride1 : Stride2, AttributeStrings = new MeshAttributeString[] { new MeshAttributeString() { Name = keypair.Key.ToString() } } }; mo.Attributes[attributeIndex++] = attr; if (GetBufferIndex(keypair.Key) == 0) { Stride1 += GetAttributeSize(keypair.Key) * GetAttributeDataSize(keypair.Key); } else { Stride2 += GetAttributeSize(keypair.Key) * GetAttributeDataSize(keypair.Key); } } // now that strides are known... long Buffer1Start = vertexBuffer1.BaseStream.Length; long Buffer2Start = vertexBuffer2.BaseStream.Length; vertexBuffer1.Write(new byte[Stride1 * tempmesh.VertexCount]); vertexBuffer2.Write(new byte[Stride2 * tempmesh.VertexCount]); attributeIndex = 0; foreach (var keypair in tempmesh.VertexData) { var attr = mo.Attributes[attributeIndex++]; float[] Data = keypair.Value; var buffer = attr.BufferIndex == 0 ? vertexBuffer1 : vertexBuffer2; int bufferOffset = (int)(attr.BufferIndex == 0 ? Buffer1Start : Buffer2Start); int stride = (attr.BufferIndex == 0 ? Stride1 : Stride2); int size = GetAttributeSize(keypair.Key); for (int vertexIndex = 0; vertexIndex < tempmesh.VertexCount; vertexIndex++) { buffer.Seek(bufferOffset + stride * vertexIndex + attr.BufferOffset, SeekOrigin.Begin); for (int j = 0; j < size; j++) { WriteType(buffer, attr.DataType, Data[vertexIndex * size + j]); } } // seek to end just to make sure buffer.Seek((int)buffer.BaseStream.Length, SeekOrigin.Begin); } mo.FinalBufferOffset = finalBufferOffset; finalBufferOffset += (4 + Stride1) * tempmesh.VertexCount; mo.VertexCount = tempmesh.VertexCount; mo.IndexCount = tempmesh.Indices.Count; mo.Stride = Stride1; mo.Stride2 = Stride2; // write index buffer if (tempmesh.VertexCount > ushort.MaxValue) { mo.DrawElementType = 1; foreach (var i in tempmesh.Indices) { indexBuffer.Write(i); } } else { foreach (var i in tempmesh.Indices) { indexBuffer.Write((ushort)i); } } } mesh.PolygonIndexSize = indexBuffer.BaseStream.Length; mesh.BufferSizes = new int[] { (int)vertexBuffer1.BaseStream.Length, (int)vertexBuffer2.BaseStream.Length, 0, 0 }; mesh.PolygonBuffer = ((MemoryStream)indexBuffer.BaseStream).ToArray(); Console.WriteLine(mesh.PolygonBuffer.Length + " " + indexBuffer.BaseStream.Length); mesh.VertexBuffers = new MeshBuffer[] { new MeshBuffer() { Buffer = ((MemoryStream)vertexBuffer1.BaseStream).ToArray() }, new MeshBuffer() { Buffer = ((MemoryStream)vertexBuffer2.BaseStream).ToArray() }, new MeshBuffer() { Buffer = new byte[0] }, new MeshBuffer() { Buffer = new byte[0] } }; mesh.RiggingBuffers = RiggingGroups.ToArray().OrderBy(o => o.Name, StringComparer.Ordinal).ToArray(); vertexBuffer1.Close(); vertexBuffer2.Close(); indexBuffer.Close(); return(mesh); }
public bool ExportMorphTargets(Stream targetStream, FileInfo outfile, List <Archive> archives, bool isGLBinary = true) { var cr2w = _wolvenkitFileService.TryReadRED4File(targetStream); if (cr2w == null || !cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().Any() || !cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { return(false); } RawArmature Rig = null; MemoryStream meshbuffer = MESH.GetMeshBufferStream(targetStream, cr2w); MeshesInfo meshinfo = MESH.GetMeshesinfo(cr2w); List <RawMeshContainer> expMeshes = MESH.ContainRawMesh(meshbuffer, meshinfo, true); int subMeshC = expMeshes.Count; var buffers = cr2w.Buffers; var blob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMorphTargetMeshBlob>().First(); string baseMeshPath = cr2w.Chunks.Select(_ => _.Data).OfType <MorphTargetMesh>().First().BaseMesh.DepotPath; ulong hash = FNV1A64HashAlgorithm.HashString(baseMeshPath); foreach (Archive ar in archives) { if (ar.Files.ContainsKey(hash)) { var meshStream = new MemoryStream(); ModTools.ExtractSingleToStream(ar, hash, meshStream); var meshCr2w = _wolvenkitFileService.TryReadRED4File(meshStream); if (meshCr2w == null || !meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().Any() || !meshCr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().Any()) { break; } MESH.MeshBones meshBones = new MESH.MeshBones(); meshBones.boneCount = meshCr2w.Chunks.Select(_ => _.Data).OfType <CMesh>().First().BoneNames.Count; if (meshBones.boneCount != 0) // for rigid meshes { meshBones.Names = RIG.GetboneNames(meshCr2w); meshBones.WorldPosn = MESH.GetMeshBonesPosn(meshCr2w); } Rig = MESH.GetNonParentedRig(meshBones); MemoryStream ms = MESH.GetMeshBufferStream(meshStream, meshCr2w); meshinfo = MESH.GetMeshesinfo(meshCr2w); expMeshes = MESH.ContainRawMesh(ms, meshinfo, true); subMeshC = expMeshes.Count; if (meshBones.boneCount == 0) // for rigid meshes { for (int i = 0; i < expMeshes.Count; i++) { expMeshes[i].weightcount = 0; } } MESH.UpdateMeshJoints(ref expMeshes, Rig, meshBones); break; } } MemoryStream diffsbuffer = new MemoryStream(); MemoryStream mappingbuffer = new MemoryStream(); MemoryStream texbuffer = new MemoryStream(); if (blob.DiffsBuffer.IsSerialized) { targetStream.Seek(cr2w.Buffers[blob.DiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin); targetStream.DecompressAndCopySegment(diffsbuffer, buffers[blob.DiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.DiffsBuffer.Buffer.Value - 1].MemSize); } if (blob.MappingBuffer.IsSerialized) { targetStream.Seek(cr2w.Buffers[blob.MappingBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin); targetStream.DecompressAndCopySegment(mappingbuffer, buffers[blob.MappingBuffer.Buffer.Value - 1].DiskSize, buffers[blob.MappingBuffer.Buffer.Value - 1].MemSize); } if (blob.TextureDiffsBuffer.IsSerialized) { targetStream.Seek(cr2w.Buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].Offset, SeekOrigin.Begin); targetStream.DecompressAndCopySegment(texbuffer, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].DiskSize, buffers[blob.TextureDiffsBuffer.Buffer.Value - 1].MemSize); } TargetsInfo targetsInfo = GetTargetInfos(cr2w, subMeshC); List <RawTargetContainer[]> expTargets = new List <RawTargetContainer[]>(); for (int i = 0; i < targetsInfo.NumTargets; i++) { UInt32[] temp_NumVertexDiffsInEachChunk = new UInt32[subMeshC]; UInt32[] temp_NumVertexDiffsMappingInEachChunk = new UInt32[subMeshC]; for (int e = 0; e < subMeshC; e++) { temp_NumVertexDiffsInEachChunk[e] = targetsInfo.NumVertexDiffsInEachChunk[i, e]; temp_NumVertexDiffsMappingInEachChunk[e] = targetsInfo.NumVertexDiffsMappingInEachChunk[i, e]; } expTargets.Add(ContainRawTargets(diffsbuffer, mappingbuffer, temp_NumVertexDiffsInEachChunk, temp_NumVertexDiffsMappingInEachChunk, targetsInfo.TargetStartsInVertexDiffs[i], targetsInfo.TargetStartsInVertexDiffsMapping[i], targetsInfo.TargetPositionDiffOffset[i], targetsInfo.TargetPositionDiffScale[i], subMeshC)); } string[] names = new string[targetsInfo.NumTargets]; for (int i = 0; i < targetsInfo.NumTargets; i++) { names[i] = targetsInfo.Names[i] + "_" + targetsInfo.RegionNames[i]; } List <MemoryStream> textureStreams = ContainTextureStreams(cr2w, texbuffer); ModelRoot model = RawTargetsToGLTF(expMeshes, expTargets, names, Rig); if (WolvenTesting.IsTesting) { return(true); } model.Extras = SharpGLTF.IO.JsonContent.Serialize(new { BaseMesh = targetsInfo.BaseMesh }); if (isGLBinary) { model.SaveGLB(outfile.FullName); } else { model.SaveGLTF(outfile.FullName); } var dir = new DirectoryInfo(outfile.FullName.Replace(Path.GetExtension(outfile.FullName), string.Empty) + "_Textures"); if (textureStreams.Count > 0) { Directory.CreateDirectory(dir.FullName); } for (int i = 0; i < textureStreams.Count; i++) { File.WriteAllBytes(dir.FullName + "\\" + Path.GetFileNameWithoutExtension(outfile.FullName) + i + ".dds", textureStreams[i].ToArray()); } targetStream.Dispose(); targetStream.Close(); return(true); }
/// <summary> /// Creates a rigging accessor from a mesh file /// </summary> /// <param name="meshFile"></param> public SSBHRiggingAccessor(MESH meshFile) { this.meshFile = meshFile; }
public SSBHRiggingAccessor(MESH MeshFile) { this.MeshFile = MeshFile; }
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); }
public void Read(FileReader reader, MESH mesh) { reader.ReadSignature(4, "VERT"); uint SectionSize = reader.ReadUInt32(); if (mesh.VertexSize == 32) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.pos = reader.ReadVec3(); vert.nrm = reader.ReadVec3(); vert.uv0 = reader.ReadVec2(); Vertices.Add(vert); } } else if (mesh.VertexSize == 12) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.pos = reader.ReadVec3(); Vertices.Add(vert); } } else if (mesh.VertexSize == 20) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.pos = reader.ReadVec3(); vert.uv0 = reader.ReadVec2(); Vertices.Add(vert); } } else if (mesh.VertexSize == 24) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.pos = reader.ReadVec3(); vert.nrm = reader.ReadVec3(); Vertices.Add(vert); } } else if (mesh.VertexSize == 36) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); if (mesh.Unknown1 != 0) { uint Unknown = reader.ReadUInt32(); //Bone index? vert.pos = reader.ReadVec3(); vert.nrm = reader.ReadVec3(); vert.uv0 = reader.ReadVec2(); Unknowns.Add(Unknown); } else { vert.pos = reader.ReadVec3(); vert.nrm = reader.ReadVec3(); vert.col = ColorUtility.ToVector4(reader.ReadBytes(4)); vert.uv0 = reader.ReadVec2(); } Vertices.Add(vert); } } else if (mesh.VertexSize == 40) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); if (mesh.Unknown1 != 0) { uint Unknown = reader.ReadUInt32(); //Bone index? vert.pos = reader.ReadVec3(); vert.nrm = reader.ReadVec3(); vert.col = ColorUtility.ToVector4(reader.ReadBytes(4)); vert.uv0 = reader.ReadVec2(); } else { throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}"); } Vertices.Add(vert); } } else if (mesh.VertexSize == 44) { for (int v = 0; v < mesh.VertexCount; v++) { Vertex vert = new Vertex(); vert.pos = reader.ReadVec3(); vert.nrm = reader.ReadVec3(); vert.col = ColorUtility.ToVector4(reader.ReadBytes(4)); vert.uv0 = reader.ReadVec2(); vert.uv1 = reader.ReadVec2(); Vertices.Add(vert); } } else { throw new Exception($"Unsupported Vertex Size {mesh.VertexSize}"); } }