From cdc2cacfc05f1a9758ed113a62bc5710297cbd65 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 25 May 2021 16:33:30 +0800 Subject: [PATCH] Fixup shape2obj --- nel/tools/3d/shape2obj/main.cpp | 134 +++++++++++++++++--------------- 1 file changed, 73 insertions(+), 61 deletions(-) diff --git a/nel/tools/3d/shape2obj/main.cpp b/nel/tools/3d/shape2obj/main.cpp index 7d106a887..fbfc713d4 100644 --- a/nel/tools/3d/shape2obj/main.cpp +++ b/nel/tools/3d/shape2obj/main.cpp @@ -45,9 +45,24 @@ bool operator == (const CVertex &v1, const CVertex &v2) bool operator < (const CVertex &v1, const CVertex &v2) { + /* + if (v1.vertex == v2.vertex) + { + if (v1.normal == v2.normal) + { + return (v1.uv < v2.uv); + } + return (v1.normal < v1.normal); + } + */ return (v1.vertex < v2.vertex); } +const CIndexBuffer *getRdrPassPrimitiveBlock(const CMeshGeom *mesh, uint lodId, uint renderPass) +{ + return &(mesh->getRdrPassPrimitiveBlock(lodId, renderPass)); +} + const CIndexBuffer *getRdrPassPrimitiveBlock(const CMeshMRMGeom *mesh, uint lodId, uint renderPass) { return &(mesh->getRdrPassPrimitiveBlock(lodId, renderPass)); @@ -66,7 +81,7 @@ const CIndexBuffer *getRdrPassPrimitiveBlock(const CMeshMRMSkinnedGeom *mesh, ui bool ProcessMeshMRMSkinned(const std::string &filename, IShape *shapeMesh); bool ProcessMeshMRM(const std::string &filename, IShape *shapeMesh); -//bool ProcessMesh(const std::string &filename, IShape *shapeMesh); +bool ProcessMesh(const std::string &filename, IShape *shapeMesh); int main(int argc, char* argv[]) { @@ -110,9 +125,9 @@ int main(int argc, char* argv[]) if (ProcessMeshMRMSkinned(filename, shapeMesh)) return 0; if (ProcessMeshMRM(filename, shapeMesh)) return 0; -// if (ProcessMesh(filename, shapeMesh)) return 0; + if (ProcessMesh(filename, shapeMesh)) return 0; - return 0; + return 1; } bool ProcessMeshMRMSkinned(const std::string &filename, IShape *shapeMesh) @@ -256,7 +271,7 @@ bool ProcessMeshMRMSkinned(const std::string &filename, IShape *shapeMesh) ofs << "v " << v.x << " " << v.y << " " << v.z << endl; ofs << "vn " << vn.x << " " << vn.y << " " << vn.z << endl; - ofs << "vt " << vt.U << " " << vt.V << endl; + ofs << "vt " << vt.U << " " << (1.0f - vt.V) << endl; } // **** Get All Faces @@ -457,7 +472,7 @@ bool ProcessMeshMRM(const std::string &filename, IShape *shapeMesh) ofs << "v " << v.x << " " << v.y << " " << v.z << endl; ofs << "vn " << vn.x << " " << vn.y << " " << vn.z << endl; - ofs << "vt " << vt.U << " " << vt.V << endl; + ofs << "vt " << vt.U << " " << (1.0f - vt.V) << endl; } // **** Get All Faces @@ -519,9 +534,6 @@ bool ProcessMeshMRM(const std::string &filename, IShape *shapeMesh) return true; } -/* - -TODO: implement this bool ProcessMesh(const std::string &filename, IShape *shapeMesh) { @@ -531,71 +543,73 @@ bool ProcessMesh(const std::string &filename, IShape *shapeMesh) COFile ofile; - CMeshGeom* meshIn = (CMeshGeom*)&mesh->getMeshGeom(); + const CMeshGeom *meshIn = &mesh->getMeshGeom(); CVertexBuffer vertexBuffer = meshIn->getVertexBuffer(); -// CVertexBufferRead vba; -// vertexBuffer.lock (vba); - - uint i = vertexBuffer.getNumVertices(); - - std::vector vertices; - meshIn->retrieveVertices(vertices); + CVertexBufferRead vba; + vertexBuffer.lock (vba); + uint i, j; - std::vector indices; - meshIn->retrieveTriangles(indices); + // **** First, for the best lod indicate what vertex is used or not. Also index geomorphs to know what real vertex is used + vector vertexUsed; + // -1 means "not used" + vertexUsed.resize(vertexBuffer.capacity(), -1); + // Parse all triangles. + for(i=0;igetNbRdrPass(0); ++i) + { + const CIndexBuffer *pb = getRdrPassPrimitiveBlock(meshIn, 0, i); + CIndexBufferRead iba; + pb->lock (iba); + if (iba.getFormat() == CIndexBuffer::Indices32) + { + const uint32 *triPtr= (const uint32 *) iba.getPtr(); + for(j=0;jgetNumIndexes(); ++j) + { + uint idx= *triPtr; + // Flag the vertex with its own index => used. + vertexUsed[idx]= idx; + triPtr++; + } + } + else + { + const uint16 *triPtr= (const uint16 *) iba.getPtr(); + for(j=0;jgetNumIndexes(); ++j) + { + uint idx= *triPtr; + // Flag the vertex with its own index => used. + vertexUsed[idx]= idx; + triPtr++; + } + } + } // **** For all vertices used (not geomorphs), compute vertex Skins. vector shadowVertices; vector vertexToVSkin; - vertexToVSkin.resize(indices.size()); - shadowVertices.reserve(indices.size()); + vertexToVSkin.resize(vertexUsed.size()); + shadowVertices.reserve(vertexUsed.size()); // use a map to remove duplicates (because of UV/normal discontinuities before!!) - map shadowVertexMap; uint numMerged= 0; - // Skip Geomorphs. - for(i=0;imaxW) - { - matId= sw.MatrixId[j]; - maxW= sw.Weights[j]; - } - } + // Build the vertex + CVertex shadowVert; + CUV uv; + shadowVert.vertex = *(CVector*)vba.getVertexCoordPointer(i); + shadowVert.normal = *(CVector*)vba.getNormalCoordPointer(i); + shadowVert.uv = *(CUV*)vba.getTexCoordPointer(i); - // If dont find the shadowVertex in the map. - map::iterator it= shadowVertexMap.find(shadowVert); - if(it==shadowVertexMap.end()) - { // Append uint index= shadowVertices.size(); vertexToVSkin[i]= index; shadowVertices.push_back(shadowVert); - shadowVertexMap.insert(make_pair(shadowVert, index)); - } - else - { - // Ok, map. - vertexToVSkin[i]= it->second; - numMerged++; } } @@ -609,7 +623,7 @@ bool ProcessMesh(const std::string &filename, IShape *shapeMesh) ofs << "v " << v.x << " " << v.y << " " << v.z << endl; ofs << "vn " << vn.x << " " << vn.y << " " << vn.z << endl; - ofs << "vt " << vt.U << " " << vt.V << endl; + ofs << "vt " << vt.U << " " << (1.0f - vt.V) << endl; } // **** Get All Faces @@ -617,11 +631,11 @@ bool ProcessMesh(const std::string &filename, IShape *shapeMesh) vector shadowTriangles; shadowTriangles.reserve(1000); // Parse all input tri of the mesh. - for(i=0; igetNbRdrPass(lodId); ++i) + for(i=0; igetNbRdrPass(0); ++i) { - ofs << "g pass" << i << endl; + ofs << "g " << filename << endl; - const CIndexBuffer *pb = getRdrPassPrimitiveBlock(meshIn, lodId, i); + const CIndexBuffer *pb = getRdrPassPrimitiveBlock(meshIn, 0, i); CIndexBufferRead iba; pb->lock (iba); if (iba.getFormat() == CIndexBuffer::Indices32) @@ -670,5 +684,3 @@ bool ProcessMesh(const std::string &filename, IShape *shapeMesh) return true; } - -*/ \ No newline at end of file