private static ThreeDSMesh LoadMeshOBJ_MESH(FileStream file, Chunk thischunk) { uint bytesRead = 6; ThreeDSMesh mesh = new ThreeDSMesh(); while (bytesRead < thischunk.length) { Chunk chunk = ReadChunk(file); switch ((ChunkCodes)chunk.ID) { case ChunkCodes.BLANK: break; case ChunkCodes.MESH_VERTICES: mesh.verticies = ReadVerticesMESH_VERTICES(file); break; case ChunkCodes.MESH_FACES: mesh.groups.Add(ReadVerticesMESH_FACES(file, chunk)); break; case ChunkCodes.MESH_TEX_VERT: mesh.uvMap = ReadTEXVERTS(file, chunk); break; /*case ChunkCodes.MESH_MATER: * mesh.mappings.Add(ReadMESHMATERIAL(file, chunk)); * break;*/ case ChunkCodes.VERTEX_FLAGS: goto END; default: END: file.Seek(chunk.length - 6, SeekOrigin.Current); break; } bytesRead += chunk.length; } return(mesh); }
private static ThreeDSMesh ParsePolygonalData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); // working data subsegment ThreeDSMesh mesh = new ThreeDSMesh(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MESH_VERTICES: // Subsegment contains vertex information mesh.verticies = new ThreeDSMesh.Vertex[subSegment.GetUShort()]; for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) { mesh.verticies[vertex].x = subSegment.GetFloat(); mesh.verticies[vertex].y = subSegment.GetFloat(); mesh.verticies[vertex].z = subSegment.GetFloat(); } break; case ChunkCodes.MESH_XFMATRIX: // Subsegment contains translation matrix info (ignore for now) break; case ChunkCodes.MESH_FACES: // Subsegment contains face information mesh.groups.Add(ParseFaceData(subSegment)); break; case ChunkCodes.MESH_TEX_VERT: // Subsegment contains texture mapping information mesh.uvMap = ParseTexVerts(subSegment); break; } subSegment = dataSegment.GetNextSubSegment(); } // Also use face data to calculate vertex normals CalculateVertexNormals(mesh); return(mesh); }
private static void CalculateVertexNormals(ThreeDSMesh mesh) { // TODO: Use opt one from SM c++ imp Vector3 faceV1 = new Vector3(); Vector3 faceV2 = new Vector3(); Vector3 faceV3 = new Vector3(); Vector3 faceEdge1; Vector3 faceEdge2; //Vector3[][] faceNormals = new Vector3[mesh.groups.Count][]; int gIndex = 0; int[] vertexMults = new int[mesh.verticies.Length]; Vector3[] normals = new Vector3[mesh.verticies.Length]; foreach (ThreeDSMesh.FaceGroup group in mesh.groups) { //Vector3[] normals = faceNormals[gIndex] = new Vector3[group.faces.Length]; //int fIndex = 0; foreach (ThreeDSMesh.Face face in group.faces) { faceV1.X = mesh.verticies[face.p1].x; faceV1.Y = mesh.verticies[face.p1].y; faceV1.Z = mesh.verticies[face.p1].z; vertexMults[face.p1]++; faceV2.X = mesh.verticies[face.p2].x; faceV2.Y = mesh.verticies[face.p2].y; faceV2.Z = mesh.verticies[face.p2].z; vertexMults[face.p2]++; faceV3.X = mesh.verticies[face.p3].x; faceV3.Y = mesh.verticies[face.p3].y; faceV3.Z = mesh.verticies[face.p3].z; vertexMults[face.p3]++; Vector3 e1 = faceV2 - faceV1, e2 = faceV3 - faceV1; Vector3 normal = Vector3.Normalize(Vector3.Cross(e1, e2)); //faceEdge1 = Vector3.Subtract(faceV2, faceV1); //faceEdge2 = Vector3.Subtract(faceV3, faceV1); //normals[fIndex] = Vector3.Cross(faceEdge1, faceEdge2); //normals[fIndex++].Normalize(); //Vector3 normal = Vector3.Cross(faceEdge1, faceEdge2); normals[face.p1] += normal; normals[face.p2] += normal; normals[face.p3] += normal; /*mesh.verticies[face.p1].nx = mesh.verticies[face.p2].nx = mesh.verticies[face.p3].nx = nor.X; mesh.verticies[face.p1].ny = mesh.verticies[face.p2].ny = mesh.verticies[face.p3].ny = nor.Y; mesh.verticies[face.p1].nz = mesh.verticies[face.p2].nz = mesh.verticies[face.p3].nz = nor.Z;*/ } } for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) { normals[vertex] *= 1f / (float)vertexMults[vertex]; mesh.verticies[vertex].nx = normals[vertex].X; mesh.verticies[vertex].ny = normals[vertex].Y; mesh.verticies[vertex].nz = normals[vertex].Z; } //int faceCount; //Vector3 vertexVectorSum; //for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) //{ // faceCount = 0; // vertexVectorSum = Vector3.Empty; // gIndex = 0; // foreach (ThreeDSMesh.FaceGroup group in mesh.groups) // { // int fIndex = 0; // foreach (ThreeDSMesh.Face face in group.faces) // { // if ((vertex == face.p1) || (vertex == face.p2) || (vertex == face.p3)) // { // faceCount++; // vertexVectorSum = Vector3.Add(vertexVectorSum, faceNormals[gIndex][fIndex]); // } // } // } // if (faceCount > 0) // { // Vector3 normal = Vector3.Multiply(vertexVectorSum, 1f/(float)faceCount); // normal.Normalize(); // mesh.verticies[vertex].nx = normal.X; // mesh.verticies[vertex].ny = normal.Y; // mesh.verticies[vertex].nz = normal.Z; // } // else // mesh.verticies[vertex].nx = mesh.verticies[vertex].ny = mesh.verticies[vertex].nz = 0; //} }
private static ThreeDSMesh ParsePolygonalData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); // working data subsegment ThreeDSMesh mesh = new ThreeDSMesh(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MESH_VERTICES: // Subsegment contains vertex information mesh.verticies = new ThreeDSMesh.Vertex[subSegment.GetUShort()]; for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) { mesh.verticies[vertex].x = subSegment.GetFloat(); mesh.verticies[vertex].y = subSegment.GetFloat(); mesh.verticies[vertex].z = subSegment.GetFloat(); } break; case ChunkCodes.MESH_XFMATRIX: // Subsegment contains translation matrix info (ignore for now) break; case ChunkCodes.MESH_FACES: // Subsegment contains face information mesh.groups.Add(ParseFaceData(subSegment)); break; case ChunkCodes.MESH_TEX_VERT: // Subsegment contains texture mapping information mesh.uvMap = ParseTexVerts(subSegment); break; } subSegment = dataSegment.GetNextSubSegment(); } // Also use face data to calculate vertex normals CalculateVertexNormals(mesh); return mesh; }
private ABModel3D ConvertMesh(ThreeDSMesh mesh, ABMaterial[] materials) { // convert vertices ABModel3D model = new ABModel3D(); model.Geometry = new ABGeometry3D(); if (mesh.verticies != null && mesh.verticies.Length > 0) { int numVerts = mesh.verticies.Length; model.Geometry.Vertices = new Vector3[numVerts]; model.Geometry.Normals = new Vector3[numVerts]; for (int vert = 0; vert < numVerts; vert++) { model.Geometry.Vertices[vert] = new Vector3(mesh.verticies[vert].x, mesh.verticies[vert].y, mesh.verticies[vert].z); model.Geometry.Normals[vert] = new Vector3(mesh.verticies[vert].nx, mesh.verticies[vert].ny, mesh.verticies[vert].nz); } } // uv map if (mesh.uvMap != null) { int numCoords = mesh.uvMap.Length; model.Geometry.TexCoords = new Vector2[numCoords]; for (int coord = 0; coord < numCoords; coord++) { model.Geometry.TexCoords[coord] = new Vector2(mesh.uvMap[coord].u, -mesh.uvMap[coord].v); } } model.Geometry.PrimType = Microsoft.DirectX.Direct3D.PrimitiveType.TriangleList; // indices if (mesh.groups != null) { model.Geometry.PrimIndices = new int[mesh.GetNumFaces() * 3]; int idx = 0; foreach (ThreeDSMesh.FaceGroup group in mesh.groups) { foreach (ThreeDSMesh.Face face in group.faces) { model.Geometry.PrimIndices[idx++] = face.p1; model.Geometry.PrimIndices[idx++] = face.p2; model.Geometry.PrimIndices[idx++] = face.p3; } if (group.mappings != null && group.mappings.Count > 0) { int numMatIndices = 0; foreach (ThreeDSMesh.MaterialMapping mapping in group.mappings) { if (mapping.mappedFaces != null && mapping.mappedFaces.Length > 0) numMatIndices++; } model.MaterialIndices = new ABMaterialIndex[numMatIndices]; int miIdx = 0; foreach (ThreeDSMesh.MaterialMapping mapping in group.mappings) { if (mapping.mappedFaces != null && mapping.mappedFaces.Length > 0) { ABMaterialIndex matIndex = model.MaterialIndices[miIdx++] = new ABMaterialIndex(); matIndex.Indices = new int[mapping.mappedFaces.Length]; foreach (ABMaterial material in materials) { if (material.Name == mapping.name) matIndex.Material = material; } for (int face = 0; face < mapping.mappedFaces.Length; face++) { matIndex.Indices[face] = mapping.mappedFaces[face]; } } } } } } return model; }
private ABModel3D ConvertMesh(ThreeDSMesh mesh, ABMaterial[] materials) { // convert vertices ABModel3D model = new ABModel3D(); model.Geometry = new ABGeometry3D(); if (mesh.verticies != null && mesh.verticies.Length > 0) { int numVerts = mesh.verticies.Length; model.Geometry.Vertices = new Vector3[numVerts]; model.Geometry.Normals = new Vector3[numVerts]; for (int vert = 0; vert < numVerts; vert++) { model.Geometry.Vertices[vert] = new Vector3(mesh.verticies[vert].x, mesh.verticies[vert].y, mesh.verticies[vert].z); model.Geometry.Normals[vert] = new Vector3(mesh.verticies[vert].nx, mesh.verticies[vert].ny, mesh.verticies[vert].nz); } } // uv map if (mesh.uvMap != null) { int numCoords = mesh.uvMap.Length; model.Geometry.TexCoords = new Vector2[numCoords]; for (int coord = 0; coord < numCoords; coord++) { model.Geometry.TexCoords[coord] = new Vector2(mesh.uvMap[coord].u, -mesh.uvMap[coord].v); } } model.Geometry.PrimType = Microsoft.DirectX.Direct3D.PrimitiveType.TriangleList; // indices if (mesh.groups != null) { model.Geometry.PrimIndices = new int[mesh.GetNumFaces() * 3]; int idx = 0; foreach (ThreeDSMesh.FaceGroup group in mesh.groups) { foreach (ThreeDSMesh.Face face in group.faces) { model.Geometry.PrimIndices[idx++] = face.p1; model.Geometry.PrimIndices[idx++] = face.p2; model.Geometry.PrimIndices[idx++] = face.p3; } if (group.mappings != null && group.mappings.Count > 0) { int numMatIndices = 0; foreach (ThreeDSMesh.MaterialMapping mapping in group.mappings) { if (mapping.mappedFaces != null && mapping.mappedFaces.Length > 0) { numMatIndices++; } } model.MaterialIndices = new ABMaterialIndex[numMatIndices]; int miIdx = 0; foreach (ThreeDSMesh.MaterialMapping mapping in group.mappings) { if (mapping.mappedFaces != null && mapping.mappedFaces.Length > 0) { ABMaterialIndex matIndex = model.MaterialIndices[miIdx++] = new ABMaterialIndex(); matIndex.Indices = new int[mapping.mappedFaces.Length]; foreach (ABMaterial material in materials) { if (material.Name == mapping.name) { matIndex.Material = material; } } for (int face = 0; face < mapping.mappedFaces.Length; face++) { matIndex.Indices[face] = mapping.mappedFaces[face]; } } } } } } return(model); }
private static void CalculateVertexNormals(ThreeDSMesh mesh) { // TODO: Use opt one from SM c++ imp Vector3 faceV1 = new Vector3(); Vector3 faceV2 = new Vector3(); Vector3 faceV3 = new Vector3(); Vector3 faceEdge1; Vector3 faceEdge2; //Vector3[][] faceNormals = new Vector3[mesh.groups.Count][]; int gIndex = 0; int[] vertexMults = new int[mesh.verticies.Length]; Vector3[] normals = new Vector3[mesh.verticies.Length]; foreach (ThreeDSMesh.FaceGroup group in mesh.groups) { //Vector3[] normals = faceNormals[gIndex] = new Vector3[group.faces.Length]; //int fIndex = 0; foreach (ThreeDSMesh.Face face in group.faces) { faceV1.X = mesh.verticies[face.p1].x; faceV1.Y = mesh.verticies[face.p1].y; faceV1.Z = mesh.verticies[face.p1].z; vertexMults[face.p1]++; faceV2.X = mesh.verticies[face.p2].x; faceV2.Y = mesh.verticies[face.p2].y; faceV2.Z = mesh.verticies[face.p2].z; vertexMults[face.p2]++; faceV3.X = mesh.verticies[face.p3].x; faceV3.Y = mesh.verticies[face.p3].y; faceV3.Z = mesh.verticies[face.p3].z; vertexMults[face.p3]++; Vector3 e1 = faceV2 - faceV1, e2 = faceV3 - faceV1; Vector3 normal = Vector3.Normalize(Vector3.Cross(e1, e2)); //faceEdge1 = Vector3.Subtract(faceV2, faceV1); //faceEdge2 = Vector3.Subtract(faceV3, faceV1); //normals[fIndex] = Vector3.Cross(faceEdge1, faceEdge2); //normals[fIndex++].Normalize(); //Vector3 normal = Vector3.Cross(faceEdge1, faceEdge2); normals[face.p1] += normal; normals[face.p2] += normal; normals[face.p3] += normal; /*mesh.verticies[face.p1].nx = mesh.verticies[face.p2].nx = mesh.verticies[face.p3].nx = nor.X; * mesh.verticies[face.p1].ny = mesh.verticies[face.p2].ny = mesh.verticies[face.p3].ny = nor.Y; * mesh.verticies[face.p1].nz = mesh.verticies[face.p2].nz = mesh.verticies[face.p3].nz = nor.Z;*/ } } for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) { normals[vertex] *= 1f / (float)vertexMults[vertex]; mesh.verticies[vertex].nx = normals[vertex].X; mesh.verticies[vertex].ny = normals[vertex].Y; mesh.verticies[vertex].nz = normals[vertex].Z; } //int faceCount; //Vector3 vertexVectorSum; //for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) //{ // faceCount = 0; // vertexVectorSum = Vector3.Empty; // gIndex = 0; // foreach (ThreeDSMesh.FaceGroup group in mesh.groups) // { // int fIndex = 0; // foreach (ThreeDSMesh.Face face in group.faces) // { // if ((vertex == face.p1) || (vertex == face.p2) || (vertex == face.p3)) // { // faceCount++; // vertexVectorSum = Vector3.Add(vertexVectorSum, faceNormals[gIndex][fIndex]); // } // } // } // if (faceCount > 0) // { // Vector3 normal = Vector3.Multiply(vertexVectorSum, 1f/(float)faceCount); // normal.Normalize(); // mesh.verticies[vertex].nx = normal.X; // mesh.verticies[vertex].ny = normal.Y; // mesh.verticies[vertex].nz = normal.Z; // } // else // mesh.verticies[vertex].nx = mesh.verticies[vertex].ny = mesh.verticies[vertex].nz = 0; //} }