// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef NL_MRM_BUILDER_H #define NL_MRM_BUILDER_H #include "nel/misc/types_nl.h" #include "nel/misc/uv.h" #include "nel/3d/mrm_mesh.h" #include "nel/3d/mrm_internal.h" #include "nel/3d/mrm_parameters.h" #include "nel/3d/mesh.h" #include "nel/3d/mesh_mrm.h" #include "nel/3d/mesh_mrm_skinned.h" #include namespace NL3D { // *************************************************************************** /** * The class for building MRMs. * \author Lionel Berenguier * \author Nevrax France * \date 2000 */ class CMRMBuilder { public: /// Constructor CMRMBuilder(); /** Compile a MRM mesh info. * \param mbuild the input mesh * \param params the parameters of MRM process. * \param mrmMesh the result MRM mesh. */ void compileMRM( const CMesh::CMeshBuild &mbuild, std::vector &bsList, const CMRMParameters ¶ms, CMeshMRMGeom::CMeshBuildMRM &mrmMesh, uint numMaxMaterial); /** Compile a MRM skinned mesh info. * \param mbuild the input mesh * \param params the parameters of MRM process. * \param mrmMesh the result MRM mesh. */ void compileMRM( const CMesh::CMeshBuild &mbuild, std::vector &bsList, const CMRMParameters ¶ms, CMeshMRMSkinnedGeom::CMeshBuildMRM &mrmMesh, uint numMaxMaterial); // **************************** private: // Mesh Level Part. /// \name Mesh Level Tmp Values. // @{ // The vertices of the MRMMesh. std::vector TmpVertices; // The attributes of the MRMMesh. std::vector TmpAttributes[NL3D_MRM_MAX_ATTRIB]; // The number of used attributes of the MRMMesh. sint NumAttributes; // The faces of the MRMMesh. std::vector TmpFaces; // Ordered list of Edge collapse. TEdgeMap EdgeCollapses; // Say if the current build must compute skinning information. bool _Skinned; /// If the current build is skinned, control the quality of the skinning redcution. CMRMParameters::TSkinReduction _SkinReduction; // @} /// \name Edge Cost methods. // @{ bool vertexHasOneWedge(sint numvertex); bool vertexHasOneMaterial(sint numvertex); bool vertexContinue(sint numvertex); bool vertexClosed(sint numvertex); float getDeltaFaceNormals(sint numvertex); // return a positive value of Sum(|DeltaNormals|) / NNormals. bool edgeContinue(const CMRMEdge &edge); bool edgeNearUniqueMatFace(const CMRMEdge &edge); float computeEdgeCost(const CMRMEdge &edge); // @} /// \name Collapse methods. // @{ bool faceShareWedges(CMRMFaceBuild *face, sint attribId, sint numVertex1, sint numVertex2); void insertFaceIntoEdgeList(CMRMFaceBuild &tmpf); void removeFaceFromEdgeList(CMRMFaceBuild &f); sint collapseEdge(const CMRMEdge &edge); // return num of deleted faces. sint followVertex(sint i); sint followWedge(sint attribId, sint i); CMesh::CSkinWeight collapseSkinWeight(const CMesh::CSkinWeight &sw1, const CMesh::CSkinWeight &sw2, float InterValue) const; // @} /// \name Mesh Level methods. // @{ void init(const CMRMMesh &baseMesh); void collapseEdges(sint nWantedFaces); void makeLODMesh(CMRMMeshGeom &lodMesh); void saveCoarserMesh(CMRMMesh &coarserMesh); /// this is the root call to compute a single lodMesh and the coarserMesh from a baseMesh. void makeFromMesh(const CMRMMesh &baseMesh, CMRMMeshGeom &lodMesh, CMRMMesh &coarserMesh, sint nWantedFaces); // @} void computeBsVerticesAttributes(std::vector &srcBsMeshs, std::vector &srcBsMeshsMod); void makeCoarserBS (std::vector &csBsMeshs); /// \name Mesh Interfaces computing // @{ bool _HasMeshInterfaces; // the sewing meshes std::vector _SewingMeshes; // The current Lod uint _CurrentLodComputed; // true if the build has some Mesh sewing interface setup. bool buildMRMSewingMeshes(const CMesh::CMeshBuild &mbuild, uint nWantedLods, uint divisor); // @} private: // MRM Level Part. /// \name MRM Level Variables. // @{ // Our comparator of CMRMWedgeGeom. struct CGeomPred { bool operator()(const CMRMWedgeGeom &a, const CMRMWedgeGeom &b) const { if(a.Start!=b.Start) return a.Start TGeomMap; TGeomMap _GeomMap; // @} /// \name MRM Level Methods. // @{ /** build the blend shapes in the same way we constructed the base mesh mrm */ void buildBlendShapes (CMRMMesh &baseMesh, std::vector &bsList, uint32 VertexFlags); /** build all LODs from a baseMesh. NB: the coarsestMesh is stored in lodMeshs[0], and has no geomorph info since it is * the coarsest mesh. nWantedLods are created (including the coarsestMesh). * \param lodMeshs array created by the function (size of nWantedlods). * \param nWantedLods number of LODs wanted. * \param divisor the coarsestMesh will have baseMesh.Faces.size()/divisor faces. */ void buildAllLods( const CMRMMesh &baseMesh, std::vector &lodMeshs, uint nWantedLods= 10, uint divisor= 50 ); /** given a list of LODs, compress/reorganize data, and store in finalMRM mesh. * */ void buildFinalMRM(std::vector &lodMeshs, CMRMMeshFinal &finalMRM); // @} private: // Interface to MeshBuild Part. /// \name Top Level methods. // @{ /// Temp map Attribute/AttributeId . struct CAttributeKey { sint VertexId; CVectorH Attribute; bool operator<(const CAttributeKey &o) const { if(VertexId!=o.VertexId) return VertexId TAttributeMap; TAttributeMap _AttributeMap[NL3D_MRM_MAX_ATTRIB]; sint findInsertAttributeInBaseMesh(CMRMMesh &baseMesh, sint attId, sint vertexId, const CVectorH &att); sint findInsertNormalInBaseMesh(CMRMMesh &baseMesh, sint attId, sint vertexId, const CVector &normal); sint findInsertColorInBaseMesh(CMRMMesh &baseMesh, sint attId, sint vertexId, CRGBA col); sint findInsertUvwInBaseMesh(CMRMMesh &baseMesh, sint attId, sint vertexId, const NLMISC::CUVW &uvw); CRGBA attToColor(const CVectorH &att) const; NLMISC::CUVW attToUvw(const CVectorH &att) const; /** from a meshBuild, compute a CMRMMesh. This is the first stage of the algo. * \return the vertexFormat supported by CMRMBuilder. */ uint32 buildMrmBaseMesh(const CMesh::CMeshBuild &mbuild, CMRMMesh &baseMesh); /** from a final MRM Mesh representation, compute a CMeshBuildMRM. This is the last stage of the algo. * \param vbFlags the vertex format returned by earlier call too buildMrmBaseMesh(). * \param nbMats the number of materials of original MeshBuild. */ void buildMeshBuildMrm(const CMRMMeshFinal &finalMRM, CMeshMRMGeom::CMeshBuildMRM &mbuild, uint32 vbFlags, uint32 nbMats, const CMesh::CMeshBuild &mb); /** from a final MRM Mesh representation, compute a CMeshBuildMRM. This is the last stage of the algo. * \param vbFlags the vertex format returned by earlier call too buildMrmBaseMesh(). * \param nbMats the number of materials of original MeshBuild. */ void buildMeshBuildMrm(const CMRMMeshFinal &finalMRM, CMeshMRMSkinnedGeom::CMeshBuildMRM &mbuild, uint32 vbFlags, uint32 nbMats, const CMesh::CMeshBuild &mb); void normalizeBaseMeshSkin(CMRMMesh &baseMesh) const; CMesh::CSkinWeight normalizeSkinWeight(const CMesh::CSkinWeight &sw) const; // @} }; } // NL3D #endif // NL_MRM_BUILDER_H /* End of mrm_builder.h */