unsafe IOReadResult BuildMeshes_Simple(ReadOptions options, IMeshBuilder builder) { if (vPositions.Length == 0) { return(new IOReadResult(IOCode.GarbageDataError, "No vertices in file")); } if (vTriangles.Length == 0) { return(new IOReadResult(IOCode.GarbageDataError, "No triangles in file")); } // [TODO] support non-per-vertex normals/colors bool bHaveNormals = (vNormals.Length == vPositions.Length); bool bHaveColors = (vColors.Length == vPositions.Length); bool bHaveUVs = (vUVs.Length / 2 == vPositions.Length / 3); int nVertices = vPositions.Length / 3; int[] mapV = new int[nVertices]; int meshID = builder.AppendNewMesh(bHaveNormals, bHaveColors, bHaveUVs, false); for (int k = 0; k < nVertices; ++k) { vtx_key vk = new vtx_key() { vi = k, ci = k, ni = k, ui = k }; mapV[k] = append_vertex(builder, vk, bHaveNormals, bHaveColors, bHaveUVs); } // [TODO] this doesn't handle missing vertices... for (int k = 0; k < vTriangles.Length; ++k) { append_triangle(builder, k, mapV); } if (UsedMaterials.Count == 1) // [RMS] should not be in here otherwise { int material_id = UsedMaterials.Keys.First(); string sMatName = UsedMaterials[material_id]; OBJMaterial useMat = Materials[sMatName]; int matID = builder.BuildMaterial(useMat); builder.AssignMaterial(matID, meshID); } return(new IOReadResult(IOCode.Ok, "")); }
int append_vertex(IMeshBuilder builder, vtx_key vk, bool bHaveNormals, bool bHaveColors, bool bHaveUVs) { int vi = 3 * vk.vi; if (vk.vi < 0 || vk.vi >= vPositions.Length / 3) { emit_warning("[OBJReader] append_vertex() referencing invalid vertex " + vk.vi.ToString()); return(-1); } if (bHaveNormals == false && bHaveColors == false && bHaveUVs == false) { return(builder.AppendVertex(vPositions[vi], vPositions[vi + 1], vPositions[vi + 2])); } NewVertexInfo vinfo = new NewVertexInfo(); vinfo.bHaveC = vinfo.bHaveN = vinfo.bHaveUV = false; vinfo.v = new Vector3d(vPositions[vi], vPositions[vi + 1], vPositions[vi + 2]); if (bHaveNormals) { vinfo.bHaveN = true; int ni = 3 * vk.ni; vinfo.n = new Vector3f(vNormals[ni], vNormals[ni + 1], vNormals[ni + 2]); } if (bHaveColors) { vinfo.bHaveC = true; int ci = 3 * vk.ci; vinfo.c = new Vector3f(vColors[ci], vColors[ci + 1], vColors[ci + 2]); } if (bHaveUVs) { vinfo.bHaveUV = true; int ui = 2 * vk.ui; vinfo.uv = new Vector2f(vUVs[ui], vUVs[ui + 1]); } return(builder.AppendVertex(vinfo)); }
unsafe IOReadResult BuildMeshes_ByMaterial(ReadOptions options, IMeshBuilder builder) { if (vPositions.Length == 0) { return(new IOReadResult(IOCode.GarbageDataError, "No vertices in file")); } if (vTriangles.Length == 0) { return(new IOReadResult(IOCode.GarbageDataError, "No triangles in file")); } bool bHaveNormals = (vNormals.Length > 0); bool bHaveColors = (vColors.Length > 0); bool bHaveUVs = (vUVs.Length > 0); List <int> usedMaterialIDs = new List <int>(UsedMaterials.Keys); usedMaterialIDs.Add(Triangle.InvalidMaterialID); foreach (int material_id in usedMaterialIDs) { int matID = Triangle.InvalidMaterialID; if (material_id != Triangle.InvalidMaterialID) { string sMatName = UsedMaterials[material_id]; OBJMaterial useMat = Materials[sMatName]; matID = builder.BuildMaterial(useMat); } bool bMatHaveUVs = (material_id == Triangle.InvalidMaterialID) ? false : bHaveUVs; int meshID = builder.AppendNewMesh(bHaveNormals, bHaveColors, bMatHaveUVs, false); Dictionary <vtx_key, int> mapV = new Dictionary <vtx_key, int>(); for (int k = 0; k < vTriangles.Length; ++k) { Triangle t = vTriangles[k]; if (t.nMaterialID == material_id) { Triangle t2 = new Triangle(); for (int j = 0; j < 3; ++j) { vtx_key vk = new vtx_key(); vk.vi = t.vIndices[j] - 1; vk.ni = t.vNormals[j] - 1; vk.ui = t.vUVs[j] - 1; vk.ci = vk.vi; int use_vtx = -1; if (mapV.ContainsKey(vk) == false) { use_vtx = append_vertex(builder, vk, bHaveNormals, bHaveColors, bMatHaveUVs); mapV[vk] = use_vtx; } else { use_vtx = mapV[vk]; } t2.vIndices[j] = use_vtx; } append_triangle(builder, t2); } } if (matID != Triangle.InvalidMaterialID) { builder.AssignMaterial(matID, meshID); } } return(new IOReadResult(IOCode.Ok, "")); }