private int VertexIndexFromFaceElement(ObjParser.Types.Face face, int elementIndex) { int faceVertexIndex = face.VertexIndexList[elementIndex]; int faceTextureVertexIndex = face.TextureVertexIndexList[elementIndex]; int vertexIndex; ObjParser.Types.Vertex vertex = obj.VertexList[faceVertexIndex - 1]; if (faceIndex.ContainsKey(faceVertexIndex, faceTextureVertexIndex)) { vertexIndex = faceIndex.VertexIndex(faceVertexIndex, faceTextureVertexIndex); } else { vertices.Add(new Vector3((float)vertex.X, (float)vertex.Y, (float)vertex.Z) + loadObjectOffset); if (faceTextureVertexIndex != 0) { ObjParser.Types.TextureVertex textureVertex = obj.TextureList[faceTextureVertexIndex - 1]; uvs.Add(new Vector2((float)textureVertex.X, (float)textureVertex.Y)); } vertexIndex = vertices.Count - 1; faceIndex.Add(faceVertexIndex, faceTextureVertexIndex, vertexIndex); } return(vertexIndex); }
private List <ObjParser.Types.Vertex> ObjVerticesOfListVector3(Vector3[] vertices) { List <ObjParser.Types.Vertex> vertexList = new List <ObjParser.Types.Vertex>(); int i = 0; foreach (Vector3 vertex in vertices) { ObjParser.Types.Vertex newVertex = new ObjParser.Types.Vertex(); newVertex.X = vertex.x; newVertex.Y = vertex.y; newVertex.Z = vertex.z; newVertex.Index = i; vertexList.Add(newVertex); i++; } return(vertexList); }
public SyncMesh BuildMesh(Obj curObj) { SyncMesh syncmesh = new SyncMesh(new SyncId("MeshId_" + curObj.Name), "Mesh_" + curObj.Name); // Faceの定義に従う。無駄は多くなる syncmesh.SubMeshes = new List <SyncSubMesh>(); SyncSubMesh submesh = new SyncSubMesh(); for (int j = 0; j < curObj.FaceList.Count; j++) { ObjParser.Types.Face face = curObj.FaceList[j]; for (int i = 0; i < face.VertexIndexList.Length; i++) { //idx int vertexIdx = face.VertexIndexList[i] - 1; int uvIdx = face.TextureVertexIndexList[i] - 1; int normalIdx = face.NormalIndexList[i] - 1; //Console.WriteLine(string.Format("index[{0}] vert[{1}] uv[{2}] normal[{3}]",i, vertexIdx+1, uvIdx+1, normalIdx+1)); //ObjParser.Types.Vertex vertex = curObj.VertexList[vertexIdx]; //ObjParser.Types.TextureVertex uv = curObj.TextureList[uvIdx]; //ObjParser.Types.VertexNormal normal = curObj.VertexNormalList[normalIdx]; ObjParser.Types.Vertex vertex = obj.VertexList[vertexIdx]; ObjParser.Types.TextureVertex uv = obj.TextureList[uvIdx]; ObjParser.Types.VertexNormal normal = obj.VertexNormalList[normalIdx]; //頂点 // OpenGL->DirectX変換のため、Xは反転する syncmesh.Vertices.Add(new Vector3(vertex.X * -1.0f, vertex.Y, vertex.Z)); // 2021.5.26 X軸を反転 syncmesh.Uvs.Add(new Vector2(uv.X, uv.Y)); syncmesh.Normals.Add(new Vector3(normal.X * -1.0f, normal.Y, normal.Z)); // 2021.5.26 X軸を反転 //syncmesh.Normals.Add(new Vector3(0,0,1)); //Console.WriteLine(string.Format("vert={0}\t{1}\t{2}", (float)vertex.X, (float)vertex.Y, (float)vertex.Z)); //index //submesh.Triangles.Add(i + j * face.VertexIndexList.Length); // OpenGL->DirectX変換のため、逆順でセットする submesh.Triangles.Add((face.VertexIndexList.Length - 1 - i) + j * face.VertexIndexList.Length); } } syncmesh.SubMeshes.Add(submesh); return(syncmesh); }
public static Submesh[] ExtractModel(string fileName, EntryTreeNode node, Action completionAction) { Submesh[] submeshes; using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { if (stream.Length == 0) { return(null); } using (BinaryReader reader = new BinaryReader(stream)) { // header DatafileHeader header = new DatafileHeader { ResourceType = reader.ReadInt32(), FileSize = reader.ReadInt32(), FileNameSize = reader.ReadInt32() }; header.FileName = reader.ReadChars(header.FileNameSize); // ignore the 2 bytes, file ID, and resource type reader.BaseStream.Seek(0x1d, SeekOrigin.Current); // block A - 1 uint aCount = reader.ReadUInt32(); Block blockA = new Block(); blockA.Bytes = new byte[aCount][]; for (int i = 0; i < aCount; i++) { blockA.Bytes[i] = reader.ReadBytes(0x51); } // block B - 1-0 Block blockB = new Block(); blockB.Bytes = new byte[2][]; for (int i = 0; i < 2; i++) { blockB.Bytes[i] = reader.ReadBytes(0x10); } // block C - 1-1 reader.BaseStream.Seek(1, SeekOrigin.Current); Block blockC = new Block(); blockC.Bytes = new byte[2][]; for (int i = 0; i < 2; i++) { blockC.Bytes[i] = reader.ReadBytes(0x11); } // block D - 1-2 reader.BaseStream.Seek(0x29, SeekOrigin.Current); uint dCount = reader.ReadUInt32(); Block blockD = new Block(); blockD.Bytes = new byte[dCount][]; for (int i = 0; i < dCount; i++) { blockD.Bytes[i] = reader.ReadBytes(0x18); } // internal/external UVs (block E) - 20 uint eCount = reader.ReadUInt32(); reader.BaseStream.Seek(eCount, SeekOrigin.Current); // vertices (block F) - 30 uint fCount = reader.ReadUInt32() / 12; long verticesOffset = reader.BaseStream.Position; Block blockF = new Block(); blockF.Bytes = new byte[fCount][]; for (int i = 0; i < fCount; i++) { blockF.Bytes[i] = reader.ReadBytes(0x0c); } // block G - 40 uint gSize = reader.ReadUInt32(); Block blockG = new Block(); blockG.Bytes = new byte[gSize][]; reader.BaseStream.Seek(gSize, SeekOrigin.Current); // faces (block) H - 50 uint hCount = reader.ReadUInt32() / 6; long facesOffset = reader.BaseStream.Position; Block blockH = new Block(); blockH.Bytes = new byte[hCount][]; for (int i = 0; i < hCount; i++) { blockH.Bytes[i] = reader.ReadBytes(0x06); } // block I - 60 uint iSize = reader.ReadUInt32(); Block blockI = new Block(); blockI.Bytes = new byte[iSize][]; reader.BaseStream.Seek(iSize, SeekOrigin.Current); // block J - 70 uint jSize = reader.ReadUInt32(); Block blockJ = new Block(); blockJ.Bytes = new byte[jSize][]; reader.BaseStream.Seek(jSize, SeekOrigin.Current); // block K - 80 uint kSize = reader.ReadUInt32(); Block blockK = new Block(); blockK.Bytes = new byte[kSize][]; reader.BaseStream.Seek(kSize, SeekOrigin.Current); // block L Block blockL = new Block(); blockL.Bytes = new byte[1][]; for (int i = 0; i < 1; i++) { blockL.Bytes[i] = reader.ReadBytes(0x12); } // block M - 90 uint mSize = reader.ReadUInt32(); // number of submeshes // create submeshes submeshes = new Submesh[mSize]; for (int i = 0; i < mSize; i++) { submeshes[i] = new Submesh(); reader.BaseStream.Seek(0x14, SeekOrigin.Current); submeshes[i].VertexCount = reader.ReadUInt32(); reader.BaseStream.Seek(0x04, SeekOrigin.Current); submeshes[i].FaceCount = reader.ReadUInt32(); reader.BaseStream.Seek(0x04, SeekOrigin.Current); } /*reader.BaseStream.Seek(0x10, SeekOrigin.Current); * * // block N - 100 * uint nSize = reader.ReadUInt32(); * Block blockN = new Block(); * blockN.Bytes = new byte[nSize][]; * for (int i = 0; i < nSize; i++) * { * blockN.Bytes[i] = reader.ReadBytes(0x1e); * } * * // block O - 110 * reader.BaseStream.Seek(0x16, SeekOrigin.Current); * uint oSize = reader.ReadUInt32(); * Block blockO = new Block(); * blockO.Bytes = new byte[nSize][]; * for (int i = 0; i < oSize; i++) * { * blockO.Bytes[i] = reader.ReadBytes(0x0a); * }*/ // get faces reader.BaseStream.Seek(facesOffset, SeekOrigin.Begin); for (int i = 0; i < submeshes.Length; i++) { submeshes[i].Faces = new Face[submeshes[i].FaceCount]; for (int j = 0; j < submeshes[i].FaceCount; j++) { submeshes[i].Faces[j] = new Face { X = reader.ReadUInt16(), Y = reader.ReadUInt16(), Z = reader.ReadUInt16() }; /*ObjParser.Types.Face f = new ObjParser.Types.Face * { * X = submeshes[i].Vertices[j].X, * Y = submeshes[i].Vertices[j].Y, * Z = submeshes[i].Vertices[j].Z * }; * faces.Add(f);*/ } } // get vertices reader.BaseStream.Seek(verticesOffset, SeekOrigin.Begin); List <ObjParser.Types.Vertex> verts = new List <ObjParser.Types.Vertex>(); for (int i = 0; i < submeshes.Length; i++) { submeshes[i].Vertices = new Vertex[submeshes[i].VertexCount]; for (int j = 0; j < submeshes[i].VertexCount; j++) { submeshes[i].Vertices[j] = new Vertex { X = reader.ReadInt16(), Y = reader.ReadInt16(), Z = reader.ReadInt16(), U = reader.ReadInt16(), V = reader.ReadInt16(), Dummy = reader.ReadInt16() }; ObjParser.Types.Vertex v = new ObjParser.Types.Vertex { X = submeshes[i].Vertices[j].X, Y = submeshes[i].Vertices[j].Y, Z = submeshes[i].Vertices[j].Z }; verts.Add(v); } } Obj obj = new Obj(); obj.VertexList = verts; obj.WriteObjFile(@"C:\Users\pinea\bag-new.obj", new string[] { "" }); completionAction(); } } return(submeshes); }