260 lines
8.4 KiB
C++
260 lines
8.4 KiB
C++
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
#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 <map>
|
|
|
|
|
|
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<CMesh::CMeshBuild*> &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<CMesh::CMeshBuild*> &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<CMRMVertex> TmpVertices;
|
|
// The attributes of the MRMMesh.
|
|
std::vector<CMRMAttribute> TmpAttributes[NL3D_MRM_MAX_ATTRIB];
|
|
// The number of used attributes of the MRMMesh.
|
|
sint NumAttributes;
|
|
// The faces of the MRMMesh.
|
|
std::vector<CMRMFaceBuild> 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<CMRMMesh> &srcBsMeshs, std::vector<CMRMMesh> &srcBsMeshsMod);
|
|
void makeCoarserBS (std::vector<CMRMBlendShape> &csBsMeshs);
|
|
|
|
|
|
/// \name Mesh Interfaces computing
|
|
// @{
|
|
bool _HasMeshInterfaces;
|
|
// the sewing meshes
|
|
std::vector<CMRMSewingMesh> _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<b.Start;
|
|
return a.End<b.End;
|
|
}
|
|
};
|
|
|
|
// The map of geomorph. for one LOD only;
|
|
typedef std::map<CMRMWedgeGeom, sint, CGeomPred> 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<CMesh::CMeshBuild*> &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<CMRMMeshGeom> &lodMeshs,
|
|
uint nWantedLods= 10, uint divisor= 50 );
|
|
|
|
/** given a list of LODs, compress/reorganize data, and store in finalMRM mesh.
|
|
*
|
|
*/
|
|
void buildFinalMRM(std::vector<CMRMMeshGeom> &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<o.VertexId;
|
|
return Attribute<o.Attribute;
|
|
}
|
|
};
|
|
typedef std::map<CAttributeKey, sint> 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 */
|