Merge branch 'master' into replace-variables-with-literals
commit
3bd2f788f6
|
@ -1,6 +1,6 @@
|
||||||
# Open Asset Import Library (assimp)
|
# Open Asset Import Library (assimp)
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# Copyright (c) 2006-2022, assimp team
|
# Copyright (c) 2006-2023, assimp team
|
||||||
#
|
#
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
|
@ -277,13 +277,15 @@ ELSEIF(MSVC)
|
||||||
ELSE() # msvc
|
ELSE() # msvc
|
||||||
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
|
ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
||||||
IF(MSVC12)
|
IF(MSVC12)
|
||||||
ADD_COMPILE_OPTIONS(/wd4351)
|
ADD_COMPILE_OPTIONS(/wd4351)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ADD_COMPILE_OPTIONS(/wd4244) #supress warning for double to float conversion if Double precission is activated
|
# supress warning for double to float conversion if Double precission is activated
|
||||||
|
ADD_COMPILE_OPTIONS(/wd4244)
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
||||||
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
|
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
|
||||||
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
|
||||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||||
|
|
|
@ -762,6 +762,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
|
||||||
if (text == nullptr) {
|
if (text == nullptr) {
|
||||||
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
throw DeadlyImportError("Out of data while reading <vertex_weights>");
|
||||||
}
|
}
|
||||||
|
SkipSpacesAndLineEnd(&text);
|
||||||
it->first = strtoul10(text, &text);
|
it->first = strtoul10(text, &text);
|
||||||
SkipSpacesAndLineEnd(&text);
|
SkipSpacesAndLineEnd(&text);
|
||||||
if (*text == 0) {
|
if (*text == 0) {
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -53,22 +52,26 @@ namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOM base class for all kinds of FBX geometry
|
* @brief DOM base class for all kinds of FBX geometry
|
||||||
*/
|
*/
|
||||||
class Geometry : public Object {
|
class Geometry : public Object {
|
||||||
public:
|
public:
|
||||||
/// @brief The class constructor with all parameters.
|
/// @brief The class constructor with all parameters.
|
||||||
/// @param id The id.
|
/// @param id The id.
|
||||||
/// @param element
|
/// @param element The element instance
|
||||||
/// @param name
|
/// @param name The name instance
|
||||||
/// @param doc
|
/// @param doc The document instance
|
||||||
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||||
|
|
||||||
|
/// @brief The class destructor, default.
|
||||||
virtual ~Geometry() = default;
|
virtual ~Geometry() = default;
|
||||||
|
|
||||||
/// Get the Skin attached to this geometry or nullptr
|
/// @brief Get the Skin attached to this geometry or nullptr.
|
||||||
|
/// @return The deformer skip instance as a pointer, nullptr if none.
|
||||||
const Skin* DeformerSkin() const;
|
const Skin* DeformerSkin() const;
|
||||||
|
|
||||||
/// Get the BlendShape attached to this geometry or nullptr
|
/// @brief Get the BlendShape attached to this geometry or nullptr
|
||||||
|
/// @return The blendshape arrays.
|
||||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -78,59 +81,71 @@ private:
|
||||||
|
|
||||||
typedef std::vector<int> MatIndexArray;
|
typedef std::vector<int> MatIndexArray;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DOM class for FBX geometry of type "Mesh"
|
* @brief DOM class for FBX geometry of type "Mesh"
|
||||||
*/
|
*/
|
||||||
class MeshGeometry : public Geometry {
|
class MeshGeometry : public Geometry {
|
||||||
public:
|
public:
|
||||||
/** The class constructor */
|
/// @brief The class constructor
|
||||||
|
/// @param id The id.
|
||||||
|
/// @param element The element instance
|
||||||
|
/// @param name The name instance
|
||||||
|
/// @param doc The document instance
|
||||||
MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||||
|
|
||||||
/** The class destructor */
|
/// @brief The class destructor, default.
|
||||||
virtual ~MeshGeometry() = default;
|
virtual ~MeshGeometry() = default;
|
||||||
|
|
||||||
/** Get a list of all vertex points, non-unique*/
|
/// brief Get a vector of all vertex points, non-unique.
|
||||||
|
/// @return The vertices vector.
|
||||||
const std::vector<aiVector3D>& GetVertices() const;
|
const std::vector<aiVector3D>& GetVertices() const;
|
||||||
|
|
||||||
/** Get a list of all vertex normals or an empty array if
|
/// @brief Get a vector of all vertex normals or an empty array if no normals are specified.
|
||||||
* no normals are specified. */
|
/// @return The normal vector.
|
||||||
const std::vector<aiVector3D>& GetNormals() const;
|
const std::vector<aiVector3D>& GetNormals() const;
|
||||||
|
|
||||||
/** Get a list of all vertex tangents or an empty array
|
/// @brief Get a vector of all vertex tangents or an empty array if no tangents are specified.
|
||||||
* if no tangents are specified */
|
/// @return The vertex tangents vector.
|
||||||
const std::vector<aiVector3D>& GetTangents() const;
|
const std::vector<aiVector3D>& GetTangents() const;
|
||||||
|
|
||||||
/** Get a list of all vertex bi-normals or an empty array
|
/// @brief Get a vector of all vertex bi-normals or an empty array if no bi-normals are specified.
|
||||||
* if no bi-normals are specified */
|
/// @return The binomal vector.
|
||||||
const std::vector<aiVector3D>& GetBinormals() const;
|
const std::vector<aiVector3D>& GetBinormals() const;
|
||||||
|
|
||||||
/** Return list of faces - each entry denotes a face and specifies
|
/// @brief Return list of faces - each entry denotes a face and specifies how many vertices it has.
|
||||||
* how many vertices it has. Vertices are taken from the
|
/// Vertices are taken from the vertex data arrays in sequential order.
|
||||||
* vertex data arrays in sequential order. */
|
/// @return The face indices vector.
|
||||||
const std::vector<unsigned int>& GetFaceIndexCounts() const;
|
const std::vector<unsigned int>& GetFaceIndexCounts() const;
|
||||||
|
|
||||||
/** Get a UV coordinate slot, returns an empty array if
|
/// @brief Get a UV coordinate slot, returns an empty array if the requested slot does not exist.
|
||||||
* the requested slot does not exist. */
|
/// @param index The requested texture coordinate slot.
|
||||||
|
/// @return The texture coordinates.
|
||||||
const std::vector<aiVector2D>& GetTextureCoords( unsigned int index ) const;
|
const std::vector<aiVector2D>& GetTextureCoords( unsigned int index ) const;
|
||||||
|
|
||||||
/** Get a UV coordinate slot, returns an empty array if
|
/// @brief Get a UV coordinate slot, returns an empty array if the requested slot does not exist.
|
||||||
* the requested slot does not exist. */
|
/// @param index The requested texture coordinate slot.
|
||||||
|
/// @return The texture coordinate channel name.
|
||||||
std::string GetTextureCoordChannelName( unsigned int index ) const;
|
std::string GetTextureCoordChannelName( unsigned int index ) const;
|
||||||
|
|
||||||
/** Get a vertex color coordinate slot, returns an empty array if
|
/// @brief Get a vertex color coordinate slot, returns an empty array if the requested slot does not exist.
|
||||||
* the requested slot does not exist. */
|
/// @param index The requested texture coordinate slot.
|
||||||
|
/// @return The vertex color vector.
|
||||||
const std::vector<aiColor4D>& GetVertexColors( unsigned int index ) const;
|
const std::vector<aiColor4D>& GetVertexColors( unsigned int index ) const;
|
||||||
|
|
||||||
/** Get per-face-vertex material assignments */
|
/// @brief Get per-face-vertex material assignments.
|
||||||
|
/// @return The Material indices Array.
|
||||||
const MatIndexArray& GetMaterialIndices() const;
|
const MatIndexArray& GetMaterialIndices() const;
|
||||||
|
|
||||||
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr
|
/// @brief Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr if the vertex index is not valid.
|
||||||
* if the vertex index is not valid. */
|
/// @param in_index The requested input index.
|
||||||
|
/// @param count The number of indices.
|
||||||
|
/// @return The indices.
|
||||||
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;
|
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;
|
||||||
|
|
||||||
/** Determine the face to which a particular output vertex index belongs.
|
/// @brief Determine the face to which a particular output vertex index belongs.
|
||||||
* This mapping is always unique. */
|
/// This mapping is always unique.
|
||||||
|
/// @param in_index The requested input index.
|
||||||
|
/// @return The face-to-vertex index.
|
||||||
unsigned int FaceForVertexIndex( unsigned int in_index ) const;
|
unsigned int FaceForVertexIndex( unsigned int in_index ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -39,8 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
#if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER)
|
||||||
#if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER)
|
|
||||||
|
|
||||||
#include "M3DWrapper.h"
|
#include "M3DWrapper.h"
|
||||||
|
|
||||||
|
@ -149,4 +148,3 @@ void M3DWrapper::ClearSave() {
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
|
@ -47,8 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_M3DWRAPPER_H_INC
|
#ifndef AI_M3DWRAPPER_H_INC
|
||||||
#define AI_M3DWRAPPER_H_INC
|
#define AI_M3DWRAPPER_H_INC
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
#if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER)
|
||||||
#if !(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER)
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -126,7 +125,6 @@ inline m3d_t *M3DWrapper::M3D() const {
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif // ASSIMP_BUILD_NO_M3D_IMPORTER
|
#endif // ASSIMP_BUILD_NO_M3D_IMPORTER
|
||||||
|
|
||||||
#endif // AI_M3DWRAPPER_H_INC
|
#endif // AI_M3DWRAPPER_H_INC
|
||||||
|
|
|
@ -60,17 +60,17 @@ namespace Ogre {
|
||||||
class OgreImporter : public BaseImporter {
|
class OgreImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
||||||
|
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual const aiImporterDesc *GetInfo() const override;
|
const aiImporterDesc *GetInfo() const override;
|
||||||
|
|
||||||
/// BaseImporter override.
|
/// BaseImporter override.
|
||||||
virtual void SetupProperties(const Importer *pImp) override;
|
void SetupProperties(const Importer *pImp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Read materials referenced by the @c mesh to @c pScene.
|
/// Read materials referenced by the @c mesh to @c pScene.
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
const aiImporterDesc *GetInfo() const override;
|
const aiImporterDesc *GetInfo() const override;
|
||||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
|
||||||
virtual void SetupProperties(const Importer *pImp) override;
|
void SetupProperties(const Importer *pImp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ImportEmbeddedTextures(glTF2::Asset &a);
|
void ImportEmbeddedTextures(glTF2::Asset &a);
|
||||||
|
|
|
@ -105,7 +105,11 @@ void JoinVerticesProcess::Execute( aiScene* pScene) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
|
bool areVerticesEqual(
|
||||||
|
const Vertex &lhs,
|
||||||
|
const Vertex &rhs,
|
||||||
|
unsigned numUVChannels,
|
||||||
|
unsigned numColorChannels) {
|
||||||
// A little helper to find locally close vertices faster.
|
// A little helper to find locally close vertices faster.
|
||||||
// Try to reuse the lookup table from the last step.
|
// Try to reuse the lookup table from the last step.
|
||||||
const static float epsilon = 1e-5f;
|
const static float epsilon = 1e-5f;
|
||||||
|
@ -124,10 +128,6 @@ bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lhs.texcoords[0] - rhs.texcoords[0]).SquareLength() > squareEpsilon) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) {
|
if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -136,19 +136,18 @@ bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Usually we won't have vertex colors or multiple UVs, so we can skip from here
|
for (unsigned i = 0; i < numUVChannels; i++) {
|
||||||
// Actually this increases runtime performance slightly, at least if branch
|
if ((lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
|
||||||
// prediction is on our side.
|
|
||||||
if (complex) {
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
if (i > 0 && (lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < numColorChannels; i++) {
|
||||||
if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
|
if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,9 +240,16 @@ struct std::hash<Vertex> {
|
||||||
//template specialization for std::equal_to for Vertex
|
//template specialization for std::equal_to for Vertex
|
||||||
template<>
|
template<>
|
||||||
struct std::equal_to<Vertex> {
|
struct std::equal_to<Vertex> {
|
||||||
|
equal_to(unsigned numUVChannels, unsigned numColorChannels) :
|
||||||
|
mNumUVChannels(numUVChannels),
|
||||||
|
mNumColorChannels(numColorChannels) {}
|
||||||
bool operator()(const Vertex &lhs, const Vertex &rhs) const {
|
bool operator()(const Vertex &lhs, const Vertex &rhs) const {
|
||||||
return areVerticesEqual(lhs, rhs, false);
|
return areVerticesEqual(lhs, rhs, mNumUVChannels, mNumColorChannels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned mNumUVChannels;
|
||||||
|
unsigned mNumColorChannels;
|
||||||
};
|
};
|
||||||
// now start the JoinVerticesProcess
|
// now start the JoinVerticesProcess
|
||||||
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
|
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
|
||||||
|
@ -316,8 +322,13 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex) {
|
||||||
uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
|
uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// a map that maps a vertix to its new index
|
// a map that maps a vertex to its new index
|
||||||
std::unordered_map<Vertex,int> vertex2Index;
|
const auto numBuckets = pMesh->mNumVertices;
|
||||||
|
const auto hasher = std::hash<Vertex>();
|
||||||
|
const auto comparator = std::equal_to<Vertex>(
|
||||||
|
pMesh->GetNumUVChannels(),
|
||||||
|
pMesh->GetNumColorChannels());
|
||||||
|
std::unordered_map<Vertex, int> vertex2Index(numBuckets, hasher, comparator);
|
||||||
// we can not end up with more vertices than we started with
|
// we can not end up with more vertices than we started with
|
||||||
vertex2Index.reserve(pMesh->mNumVertices);
|
vertex2Index.reserve(pMesh->mNumVertices);
|
||||||
// Now check each vertex if it brings something new to the table
|
// Now check each vertex if it brings something new to the table
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -36,13 +35,7 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------- */
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Implementation of the LimitBoneWeightsProcess post processing step */
|
|
||||||
|
|
||||||
|
|
||||||
#include "LimitBoneWeightsProcess.h"
|
#include "LimitBoneWeightsProcess.h"
|
||||||
#include <assimp/SmallVector.h>
|
#include <assimp/SmallVector.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
|
@ -51,14 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
|
// Make sure this value is set.
|
||||||
|
#ifndef AI_LMW_MAX_WEIGHTS
|
||||||
|
# define AI_LMW_MAX_WEIGHTS 16
|
||||||
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
LimitBoneWeightsProcess::LimitBoneWeightsProcess()
|
LimitBoneWeightsProcess::LimitBoneWeightsProcess() : mMaxWeights(AI_LMW_MAX_WEIGHTS) {}
|
||||||
{
|
|
||||||
mMaxWeights = AI_LMW_MAX_WEIGHTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
|
@ -66,15 +61,15 @@ LimitBoneWeightsProcess::~LimitBoneWeightsProcess() = default;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const
|
bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return (pFlags & aiProcess_LimitBoneWeights) != 0;
|
return (pFlags & aiProcess_LimitBoneWeights) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void LimitBoneWeightsProcess::Execute( aiScene* pScene)
|
void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
|
||||||
{
|
ai_assert(pScene != nullptr);
|
||||||
|
|
||||||
ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
|
ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
|
||||||
|
|
||||||
for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
|
for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
|
||||||
|
@ -86,16 +81,30 @@ void LimitBoneWeightsProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp)
|
void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
// get the current value of the property
|
|
||||||
this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
|
this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static unsigned int removeEmptyBones(aiMesh *pMesh) {
|
||||||
|
ai_assert(pMesh != nullptr);
|
||||||
|
|
||||||
|
unsigned int writeBone = 0;
|
||||||
|
for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone) {
|
||||||
|
aiBone* bone = pMesh->mBones[readBone];
|
||||||
|
if (bone->mNumWeights > 0) {
|
||||||
|
pMesh->mBones[writeBone++] = bone;
|
||||||
|
} else {
|
||||||
|
delete bone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeBone;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Unites identical vertices in the given mesh
|
// Unites identical vertices in the given mesh
|
||||||
void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
|
void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh) {
|
||||||
{
|
|
||||||
if (!pMesh->HasBones())
|
if (!pMesh->HasBones())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -105,11 +114,9 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
|
||||||
WeightsPerVertex vertexWeights(pMesh->mNumVertices);
|
WeightsPerVertex vertexWeights(pMesh->mNumVertices);
|
||||||
size_t maxVertexWeights = 0;
|
size_t maxVertexWeights = 0;
|
||||||
|
|
||||||
for (unsigned int b = 0; b < pMesh->mNumBones; ++b)
|
for (unsigned int b = 0; b < pMesh->mNumBones; ++b) {
|
||||||
{
|
|
||||||
const aiBone* bone = pMesh->mBones[b];
|
const aiBone* bone = pMesh->mBones[b];
|
||||||
for (unsigned int w = 0; w < bone->mNumWeights; ++w)
|
for (unsigned int w = 0; w < bone->mNumWeights; ++w) {
|
||||||
{
|
|
||||||
const aiVertexWeight& vw = bone->mWeights[w];
|
const aiVertexWeight& vw = bone->mWeights[w];
|
||||||
|
|
||||||
if (vertexWeights.size() <= vw.mVertexId)
|
if (vertexWeights.size() <= vw.mVertexId)
|
||||||
|
@ -126,8 +133,7 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
|
||||||
unsigned int removed = 0, old_bones = pMesh->mNumBones;
|
unsigned int removed = 0, old_bones = pMesh->mNumBones;
|
||||||
|
|
||||||
// now cut the weight count if it exceeds the maximum
|
// now cut the weight count if it exceeds the maximum
|
||||||
for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
|
for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit) {
|
||||||
{
|
|
||||||
if (vit->size() <= mMaxWeights)
|
if (vit->size() <= mMaxWeights)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -154,40 +160,27 @@ void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear weight count for all bone
|
// clear weight count for all bone
|
||||||
for (unsigned int a = 0; a < pMesh->mNumBones; ++a)
|
for (unsigned int a = 0; a < pMesh->mNumBones; ++a) {
|
||||||
{
|
|
||||||
pMesh->mBones[a]->mNumWeights = 0;
|
pMesh->mBones[a]->mNumWeights = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rebuild the vertex weight array for all bones
|
// rebuild the vertex weight array for all bones
|
||||||
for (unsigned int a = 0; a < vertexWeights.size(); ++a)
|
for (unsigned int a = 0; a < vertexWeights.size(); ++a) {
|
||||||
{
|
|
||||||
const VertexWeightArray& vw = vertexWeights[a];
|
const VertexWeightArray& vw = vertexWeights[a];
|
||||||
for (const Weight* it = vw.begin(); it != vw.end(); ++it)
|
for (const Weight* it = vw.begin(); it != vw.end(); ++it) {
|
||||||
{
|
|
||||||
aiBone* bone = pMesh->mBones[it->mBone];
|
aiBone* bone = pMesh->mBones[it->mBone];
|
||||||
bone->mWeights[bone->mNumWeights++] = aiVertexWeight(a, it->mWeight);
|
bone->mWeights[bone->mNumWeights++] = aiVertexWeight(a, it->mWeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove empty bones
|
// remove empty bones
|
||||||
unsigned int writeBone = 0;
|
#ifdef AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES
|
||||||
|
pMesh->mNumBones = removeEmptyBones(pMesh);
|
||||||
for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone)
|
#endif // AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES
|
||||||
{
|
|
||||||
aiBone* bone = pMesh->mBones[readBone];
|
|
||||||
if (bone->mNumWeights > 0)
|
|
||||||
{
|
|
||||||
pMesh->mBones[writeBone++] = bone;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete bone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pMesh->mNumBones = writeBone;
|
|
||||||
|
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
|
ASSIMP_LOG_INFO("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
Loading…
Reference in New Issue