Refactoring: Reuse code from GeometryUtils
parent
5d841ec9a5
commit
d58201a579
|
@ -89,4 +89,12 @@ bool GeometryUtils::PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void GeometryUtils::normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut,
|
||||||
|
size_t numVectors) {
|
||||||
|
for (size_t i=0; i<numVectors; ++i) {
|
||||||
|
vectorArrayOut[i] = vectorArrayIn[i].Normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Assimp {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/// @brief This helper class supports some basic geometry algorithms.
|
/// @brief This helper class supports some basic geometry algorithms.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
class GeometryUtils {
|
class ASSIMP_API GeometryUtils {
|
||||||
public:
|
public:
|
||||||
static ai_real heron( ai_real a, ai_real b, ai_real c );
|
static ai_real heron( ai_real a, ai_real b, ai_real c );
|
||||||
|
|
||||||
|
@ -63,7 +63,19 @@ public:
|
||||||
/// @return The area.
|
/// @return The area.
|
||||||
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh );
|
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh );
|
||||||
|
|
||||||
|
/// @brief
|
||||||
|
/// @param ray
|
||||||
|
/// @param planePos
|
||||||
|
/// @param planeNormal
|
||||||
|
/// @param pos
|
||||||
|
/// @return
|
||||||
static bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, const aiVector3D& planeNormal, aiVector3D& pos);
|
static bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, const aiVector3D& planeNormal, aiVector3D& pos);
|
||||||
|
|
||||||
|
/// @brief
|
||||||
|
/// @param vectorArrayIn
|
||||||
|
/// @param vectorArrayOut
|
||||||
|
/// @param numVectors
|
||||||
|
static void normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut, size_t numVectors);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
|
@ -42,30 +42,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file GenUVCoords step */
|
/** @file GenUVCoords step */
|
||||||
|
|
||||||
#include "ComputeUVMappingProcess.h"
|
#include "ComputeUVMappingProcess.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
#include "Geometry/GeometryUtils.h"
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const static aiVector3D base_axis_y(0.0,1.0,0.0);
|
const static aiVector3D base_axis_y(0.0, 1.0, 0.0);
|
||||||
const static aiVector3D base_axis_x(1.0,0.0,0.0);
|
const static aiVector3D base_axis_x(1.0, 0.0, 0.0);
|
||||||
const static aiVector3D base_axis_z(0.0,0.0,1.0);
|
const static aiVector3D base_axis_z(0.0, 0.0, 1.0);
|
||||||
const static ai_real angle_epsilon = ai_real( 0.95 );
|
const static ai_real angle_epsilon = ai_real(0.95);
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 ComputeUVMappingProcess::IsActive( unsigned int pFlags) const {
|
bool ComputeUVMappingProcess::IsActive(unsigned int pFlags) const {
|
||||||
return (pFlags & aiProcess_GenUVCoords) != 0;
|
return (pFlags & aiProcess_GenUVCoords) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Find the first empty UV channel in a mesh
|
// Find the first empty UV channel in a mesh
|
||||||
inline unsigned int FindEmptyUVChannel (aiMesh* mesh) {
|
inline unsigned int FindEmptyUVChannel(aiMesh *mesh) {
|
||||||
for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
|
for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++m)
|
||||||
if (!mesh->mTextureCoords[m]) {
|
if (!mesh->mTextureCoords[m]) {
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -76,19 +76,19 @@ inline unsigned int FindEmptyUVChannel (aiMesh* mesh) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Try to remove UV seams
|
// Try to remove UV seams
|
||||||
void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) {
|
void RemoveUVSeams(aiMesh *mesh, aiVector3D *out) {
|
||||||
// TODO: just a very rough algorithm. I think it could be done
|
// TODO: just a very rough algorithm. I think it could be done
|
||||||
// much easier, but I don't know how and am currently too tired to
|
// much easier, but I don't know how and am currently too tired to
|
||||||
// to think about a better solution.
|
// to think about a better solution.
|
||||||
|
|
||||||
const static ai_real LOWER_LIMIT = ai_real( 0.1 );
|
const static ai_real LOWER_LIMIT = ai_real(0.1);
|
||||||
const static ai_real UPPER_LIMIT = ai_real( 0.9 );
|
const static ai_real UPPER_LIMIT = ai_real(0.9);
|
||||||
|
|
||||||
const static ai_real LOWER_EPSILON = ai_real( 10e-3 );
|
const static ai_real LOWER_EPSILON = ai_real(10e-3);
|
||||||
const static ai_real UPPER_EPSILON = ai_real( 1.0-10e-3 );
|
const static ai_real UPPER_EPSILON = ai_real(1.0 - 10e-3);
|
||||||
|
|
||||||
for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx) {
|
for (unsigned int fidx = 0; fidx < mesh->mNumFaces; ++fidx) {
|
||||||
const aiFace& face = mesh->mFaces[fidx];
|
const aiFace &face = mesh->mFaces[fidx];
|
||||||
if (face.mNumIndices < 3) {
|
if (face.mNumIndices < 3) {
|
||||||
continue; // triangles and polygons only, please
|
continue; // triangles and polygons only, please
|
||||||
}
|
}
|
||||||
|
@ -100,20 +100,18 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) {
|
||||||
// but the assumption that a face with at least one very small
|
// but the assumption that a face with at least one very small
|
||||||
// on the one side and one very large U coord on the other side
|
// on the one side and one very large U coord on the other side
|
||||||
// lies on a UV seam should work for most cases.
|
// lies on a UV seam should work for most cases.
|
||||||
for (unsigned int n = 0; n < face.mNumIndices;++n)
|
for (unsigned int n = 0; n < face.mNumIndices; ++n) {
|
||||||
{
|
if (out[face.mIndices[n]].x < LOWER_LIMIT) {
|
||||||
if (out[face.mIndices[n]].x < LOWER_LIMIT)
|
|
||||||
{
|
|
||||||
smallV = n;
|
smallV = n;
|
||||||
|
|
||||||
// If we have a U value very close to 0 we can't
|
// If we have a U value very close to 0 we can't
|
||||||
// round the others to 0, too.
|
// round the others to 0, too.
|
||||||
if (out[face.mIndices[n]].x <= LOWER_EPSILON)
|
if (out[face.mIndices[n]].x <= LOWER_EPSILON)
|
||||||
zero = true;
|
zero = true;
|
||||||
else round_to_zero = true;
|
else
|
||||||
|
round_to_zero = true;
|
||||||
}
|
}
|
||||||
if (out[face.mIndices[n]].x > UPPER_LIMIT)
|
if (out[face.mIndices[n]].x > UPPER_LIMIT) {
|
||||||
{
|
|
||||||
large = n;
|
large = n;
|
||||||
|
|
||||||
// If we have a U value very close to 1 we can't
|
// If we have a U value very close to 1 we can't
|
||||||
|
@ -122,10 +120,8 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) {
|
||||||
one = true;
|
one = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (smallV != face.mNumIndices && large != face.mNumIndices)
|
if (smallV != face.mNumIndices && large != face.mNumIndices) {
|
||||||
{
|
for (unsigned int n = 0; n < face.mNumIndices; ++n) {
|
||||||
for (unsigned int n = 0; n < face.mNumIndices;++n)
|
|
||||||
{
|
|
||||||
// If the u value is over the upper limit and no other u
|
// If the u value is over the upper limit and no other u
|
||||||
// value of that face is 0, round it to 0
|
// value of that face is 0, round it to 0
|
||||||
if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
|
if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
|
||||||
|
@ -141,8 +137,7 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) {
|
||||||
// Due to numerical inaccuracies one U coord becomes 0, the
|
// Due to numerical inaccuracies one U coord becomes 0, the
|
||||||
// other 1. But we do still have a third UV coord to determine
|
// other 1. But we do still have a third UV coord to determine
|
||||||
// to which side we must round to.
|
// to which side we must round to.
|
||||||
else if (one && zero)
|
else if (one && zero) {
|
||||||
{
|
|
||||||
if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
|
if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
|
||||||
out[face.mIndices[n]].x = 0.0;
|
out[face.mIndices[n]].x = 0.0;
|
||||||
else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
|
else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
|
||||||
|
@ -154,8 +149,7 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
|
||||||
{
|
|
||||||
aiVector3D center, min, max;
|
aiVector3D center, min, max;
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
|
|
||||||
|
@ -177,51 +171,47 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
||||||
// Thus we can derive:
|
// Thus we can derive:
|
||||||
// lat = arcsin (z)
|
// lat = arcsin (z)
|
||||||
// lon = arctan (y/x)
|
// lon = arctan (y/x)
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
|
||||||
out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
(std::asin(diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||||
}
|
}
|
||||||
}
|
} else if (axis * base_axis_y >= angle_epsilon) {
|
||||||
else if (axis * base_axis_y >= angle_epsilon) {
|
|
||||||
// ... just the same again
|
// ... just the same again
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
|
||||||
out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
(std::asin(diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||||
}
|
}
|
||||||
}
|
} else if (axis * base_axis_z >= angle_epsilon) {
|
||||||
else if (axis * base_axis_z >= angle_epsilon) {
|
|
||||||
// ... just the same again
|
// ... just the same again
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
|
||||||
out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
(std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||||
else {
|
else {
|
||||||
aiMatrix4x4 mTrafo;
|
aiMatrix4x4 mTrafo;
|
||||||
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
aiMatrix4x4::FromToMatrix(axis, base_axis_y, mTrafo);
|
||||||
|
|
||||||
// again the same, except we're applying a transformation now
|
// again the same, except we're applying a transformation now
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
|
const aiVector3D diff = ((mTrafo * mesh->mVertices[pnt]) - center).Normalize();
|
||||||
out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
(std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
||||||
// close to zero on the one side, and a tcoord close to one on the
|
// close to zero on the one side, and a tcoord close to one on the
|
||||||
// other side.
|
// other side.
|
||||||
RemoveUVSeams(mesh,out);
|
RemoveUVSeams(mesh, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
|
||||||
{
|
|
||||||
aiVector3D center, min, max;
|
aiVector3D center, min, max;
|
||||||
|
|
||||||
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
||||||
|
@ -236,67 +226,64 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
|
||||||
// directly to the texture V axis. The other axis is derived from
|
// directly to the texture V axis. The other axis is derived from
|
||||||
// the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
|
// the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
|
||||||
// 'c' is the center point of the mesh.
|
// 'c' is the center point of the mesh.
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D &pos = mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D &uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.x - min.x) / diff;
|
uv.y = (pos.x - min.x) / diff;
|
||||||
uv.x = (std::atan2( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
uv.x = (std::atan2(pos.z - center.z, pos.y - center.y) + (ai_real)AI_MATH_PI) / (ai_real)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
} else if (axis * base_axis_y >= angle_epsilon) {
|
||||||
else if (axis * base_axis_y >= angle_epsilon) {
|
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
const ai_real diff = max.y - min.y;
|
const ai_real diff = max.y - min.y;
|
||||||
|
|
||||||
// just the same ...
|
// just the same ...
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D &pos = mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D &uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.y - min.y) / diff;
|
uv.y = (pos.y - min.y) / diff;
|
||||||
uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
uv.x = (std::atan2(pos.x - center.x, pos.z - center.z) + (ai_real)AI_MATH_PI) / (ai_real)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
} else if (axis * base_axis_z >= angle_epsilon) {
|
||||||
else if (axis * base_axis_z >= angle_epsilon) {
|
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
const ai_real diff = max.z - min.z;
|
const ai_real diff = max.z - min.z;
|
||||||
|
|
||||||
// just the same ...
|
// just the same ...
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D &pos = mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D &uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.z - min.z) / diff;
|
uv.y = (pos.z - min.z) / diff;
|
||||||
uv.x = (std::atan2( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
uv.x = (std::atan2(pos.y - center.y, pos.x - center.x) + (ai_real)AI_MATH_PI) / (ai_real)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||||
else {
|
else {
|
||||||
aiMatrix4x4 mTrafo;
|
aiMatrix4x4 mTrafo;
|
||||||
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
aiMatrix4x4::FromToMatrix(axis, base_axis_y, mTrafo);
|
||||||
FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
|
FindMeshCenterTransformed(mesh, center, min, max, mTrafo);
|
||||||
const ai_real diff = max.y - min.y;
|
const ai_real diff = max.y - min.y;
|
||||||
|
|
||||||
// again the same, except we're applying a transformation now
|
// again the same, except we're applying a transformation now
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D pos = mTrafo* mesh->mVertices[pnt];
|
const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D &uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.y - min.y) / diff;
|
uv.y = (pos.y - min.y) / diff;
|
||||||
uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
uv.x = (std::atan2(pos.x - center.x, pos.z - center.z) + (ai_real)AI_MATH_PI) / (ai_real)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
||||||
// close to zero on the one side, and a tcoord close to one on the
|
// close to zero on the one side, and a tcoord close to one on the
|
||||||
// other side.
|
// other side.
|
||||||
RemoveUVSeams(mesh,out);
|
RemoveUVSeams(mesh, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
|
||||||
{
|
ai_real diffu, diffv;
|
||||||
ai_real diffu,diffv;
|
|
||||||
aiVector3D center, min, max;
|
aiVector3D center, min, max;
|
||||||
|
|
||||||
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
||||||
|
@ -308,44 +295,41 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
|
||||||
diffu = max.z - min.z;
|
diffu = max.z - min.z;
|
||||||
diffv = max.y - min.y;
|
diffv = max.y - min.y;
|
||||||
|
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D &pos = mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.0);
|
out[pnt].Set((pos.z - min.z) / diffu, (pos.y - min.y) / diffv, 0.0);
|
||||||
}
|
}
|
||||||
}
|
} else if (axis * base_axis_y >= angle_epsilon) {
|
||||||
else if (axis * base_axis_y >= angle_epsilon) {
|
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
diffu = max.x - min.x;
|
diffu = max.x - min.x;
|
||||||
diffv = max.z - min.z;
|
diffv = max.z - min.z;
|
||||||
|
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D &pos = mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.0);
|
out[pnt].Set((pos.x - min.x) / diffu, (pos.z - min.z) / diffv, 0.0);
|
||||||
}
|
}
|
||||||
}
|
} else if (axis * base_axis_z >= angle_epsilon) {
|
||||||
else if (axis * base_axis_z >= angle_epsilon) {
|
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
diffu = max.x - min.x;
|
diffu = max.x - min.x;
|
||||||
diffv = max.y - min.y;
|
diffv = max.y - min.y;
|
||||||
|
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D &pos = mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
|
out[pnt].Set((pos.x - min.x) / diffu, (pos.y - min.y) / diffv, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
aiMatrix4x4 mTrafo;
|
aiMatrix4x4 mTrafo;
|
||||||
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
aiMatrix4x4::FromToMatrix(axis, base_axis_y, mTrafo);
|
||||||
FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
|
FindMeshCenterTransformed(mesh, center, min, max, mTrafo);
|
||||||
diffu = max.x - min.x;
|
diffu = max.x - min.x;
|
||||||
diffv = max.z - min.z;
|
diffv = max.z - min.z;
|
||||||
|
|
||||||
// again the same, except we're applying a transformation now
|
// again the same, except we're applying a transformation now
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
|
||||||
const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
|
const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.0);
|
out[pnt].Set((pos.x - min.x) / diffu, (pos.z - min.z) / diffv, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,14 +337,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
|
void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh *, aiVector3D *) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_ERROR("Mapping type currently not implemented");
|
ASSIMP_LOG_ERROR("Mapping type currently not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
void ComputeUVMappingProcess::Execute(aiScene *pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
|
ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
|
@ -371,22 +353,17 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
/* Iterate through all materials and search for non-UV mapped textures
|
/* Iterate through all materials and search for non-UV mapped textures
|
||||||
*/
|
*/
|
||||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
|
||||||
{
|
|
||||||
mappingStack.clear();
|
mappingStack.clear();
|
||||||
aiMaterial* mat = pScene->mMaterials[i];
|
aiMaterial *mat = pScene->mMaterials[i];
|
||||||
for (unsigned int a = 0; a < mat->mNumProperties;++a)
|
for (unsigned int a = 0; a < mat->mNumProperties; ++a) {
|
||||||
{
|
aiMaterialProperty *prop = mat->mProperties[a];
|
||||||
aiMaterialProperty* prop = mat->mProperties[a];
|
if (!::strcmp(prop->mKey.data, "$tex.mapping")) {
|
||||||
if (!::strcmp( prop->mKey.data, "$tex.mapping"))
|
aiTextureMapping &mapping = *((aiTextureMapping *)prop->mData);
|
||||||
{
|
if (aiTextureMapping_UV != mapping) {
|
||||||
aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData);
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
if (aiTextureMapping_UV != mapping)
|
|
||||||
{
|
|
||||||
if (!DefaultLogger::isNullLogger())
|
|
||||||
{
|
|
||||||
ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
|
ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
|
||||||
aiTextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
|
aiTextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex,
|
||||||
MappingTypeToString(mapping));
|
MappingTypeToString(mapping));
|
||||||
|
|
||||||
ASSIMP_LOG_INFO(buffer);
|
ASSIMP_LOG_INFO(buffer);
|
||||||
|
@ -395,67 +372,59 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
||||||
if (aiTextureMapping_OTHER == mapping)
|
if (aiTextureMapping_OTHER == mapping)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MappingInfo info (mapping);
|
MappingInfo info(mapping);
|
||||||
|
|
||||||
// Get further properties - currently only the major axis
|
// Get further properties - currently only the major axis
|
||||||
for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
|
for (unsigned int a2 = 0; a2 < mat->mNumProperties; ++a2) {
|
||||||
{
|
aiMaterialProperty *prop2 = mat->mProperties[a2];
|
||||||
aiMaterialProperty* prop2 = mat->mProperties[a2];
|
|
||||||
if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
|
if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) {
|
if (!::strcmp(prop2->mKey.data, "$tex.mapaxis")) {
|
||||||
info.axis = *((aiVector3D*)prop2->mData);
|
info.axis = *((aiVector3D *)prop2->mData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int idx( 99999999 );
|
unsigned int idx(99999999);
|
||||||
|
|
||||||
// Check whether we have this mapping mode already
|
// Check whether we have this mapping mode already
|
||||||
std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info);
|
std::list<MappingInfo>::iterator it = std::find(mappingStack.begin(), mappingStack.end(), info);
|
||||||
if (mappingStack.end() != it)
|
if (mappingStack.end() != it) {
|
||||||
{
|
|
||||||
idx = (*it).uv;
|
idx = (*it).uv;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We have found a non-UV mapped texture. Now
|
/* We have found a non-UV mapped texture. Now
|
||||||
* we need to find all meshes using this material
|
* we need to find all meshes using this material
|
||||||
* that we can compute UV channels for them.
|
* that we can compute UV channels for them.
|
||||||
*/
|
*/
|
||||||
for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
|
for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
|
||||||
{
|
aiMesh *mesh = pScene->mMeshes[m];
|
||||||
aiMesh* mesh = pScene->mMeshes[m];
|
|
||||||
unsigned int outIdx = 0;
|
unsigned int outIdx = 0;
|
||||||
if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX ||
|
if (mesh->mMaterialIndex != i || (outIdx = FindEmptyUVChannel(mesh)) == UINT_MAX ||
|
||||||
!mesh->mNumVertices)
|
!mesh->mNumVertices) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate output storage
|
// Allocate output storage
|
||||||
aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
|
aiVector3D *p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
|
||||||
|
|
||||||
switch (mapping)
|
switch (mapping) {
|
||||||
{
|
|
||||||
case aiTextureMapping_SPHERE:
|
case aiTextureMapping_SPHERE:
|
||||||
ComputeSphereMapping(mesh,info.axis,p);
|
ComputeSphereMapping(mesh, info.axis, p);
|
||||||
break;
|
break;
|
||||||
case aiTextureMapping_CYLINDER:
|
case aiTextureMapping_CYLINDER:
|
||||||
ComputeCylinderMapping(mesh,info.axis,p);
|
ComputeCylinderMapping(mesh, info.axis, p);
|
||||||
break;
|
break;
|
||||||
case aiTextureMapping_PLANE:
|
case aiTextureMapping_PLANE:
|
||||||
ComputePlaneMapping(mesh,info.axis,p);
|
ComputePlaneMapping(mesh, info.axis, p);
|
||||||
break;
|
break;
|
||||||
case aiTextureMapping_BOX:
|
case aiTextureMapping_BOX:
|
||||||
ComputeBoxMapping(mesh,p);
|
ComputeBoxMapping(mesh, p);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
if (m && idx != outIdx)
|
if (m && idx != outIdx) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to "
|
ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to "
|
||||||
"this material have equal numbers of UV channels. The UV index stored in "
|
"this material have equal numbers of UV channels. The UV index stored in "
|
||||||
"the material structure does therefore not apply for all meshes. ");
|
"the material structure does therefore not apply for all meshes. ");
|
||||||
|
@ -468,7 +437,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// Update the material property list
|
// Update the material property list
|
||||||
mapping = aiTextureMapping_UV;
|
mapping = aiTextureMapping_UV;
|
||||||
((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex));
|
((aiMaterial *)mat)->AddProperty(&idx, 1, AI_MATKEY_UVWSRC(prop->mSemantic, prop->mIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,27 +42,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Implementation of the post processing step to drop face
|
/** @file Implementation of the post processing step to drop face
|
||||||
* normals for all imported faces.
|
* normals for all imported faces.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "DropFaceNormalsProcess.h"
|
#include "DropFaceNormalsProcess.h"
|
||||||
|
#include <assimp/Exceptional.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/Exceptional.h>
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 DropFaceNormalsProcess::IsActive( unsigned int pFlags) const {
|
bool DropFaceNormalsProcess::IsActive(unsigned int pFlags) const {
|
||||||
return (pFlags & aiProcess_DropNormals) != 0;
|
return (pFlags & aiProcess_DropNormals) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void DropFaceNormalsProcess::Execute( aiScene* pScene) {
|
void DropFaceNormalsProcess::Execute(aiScene *pScene) {
|
||||||
ASSIMP_LOG_DEBUG("DropFaceNormalsProcess begin");
|
ASSIMP_LOG_DEBUG("DropFaceNormalsProcess begin");
|
||||||
|
|
||||||
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
||||||
|
@ -70,8 +69,8 @@ void DropFaceNormalsProcess::Execute( aiScene* pScene) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bHas = false;
|
bool bHas = false;
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
||||||
bHas |= this->DropMeshFaceNormals( pScene->mMeshes[a]);
|
bHas |= this->DropMeshFaceNormals(pScene->mMeshes[a]);
|
||||||
}
|
}
|
||||||
if (bHas) {
|
if (bHas) {
|
||||||
ASSIMP_LOG_INFO("DropFaceNormalsProcess finished. "
|
ASSIMP_LOG_INFO("DropFaceNormalsProcess finished. "
|
||||||
|
@ -84,7 +83,7 @@ void DropFaceNormalsProcess::Execute( aiScene* pScene) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
bool DropFaceNormalsProcess::DropMeshFaceNormals (aiMesh* mesh) {
|
bool DropFaceNormalsProcess::DropMeshFaceNormals(aiMesh *mesh) {
|
||||||
ai_assert(nullptr != mesh);
|
ai_assert(nullptr != mesh);
|
||||||
|
|
||||||
if (nullptr == mesh->mNormals) {
|
if (nullptr == mesh->mNormals) {
|
||||||
|
|
|
@ -41,11 +41,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file FindDegenerates.cpp
|
/** @file FindDegenerates.cpp
|
||||||
* @brief Implementation of the FindDegenerates post-process step.
|
* @brief Implementation of the FindDegenerates post-process step.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ProcessHelper.h"
|
|
||||||
#include "FindDegenerates.h"
|
#include "FindDegenerates.h"
|
||||||
#include "Geometry/GeometryUtils.h"
|
#include "Geometry/GeometryUtils.h"
|
||||||
|
#include "ProcessHelper.h"
|
||||||
|
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
|
||||||
|
@ -54,35 +54,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// Correct node indices to meshes and remove references to deleted mesh
|
// Correct node indices to meshes and remove references to deleted mesh
|
||||||
static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned int, unsigned int>& meshMap);
|
static void updateSceneGraph(aiNode *pNode, const std::unordered_map<unsigned int, unsigned int> &meshMap);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
FindDegeneratesProcess::FindDegeneratesProcess() :
|
FindDegeneratesProcess::FindDegeneratesProcess() :
|
||||||
mConfigRemoveDegenerates( false ),
|
mConfigRemoveDegenerates(false),
|
||||||
mConfigCheckAreaOfTriangle( false ){
|
mConfigCheckAreaOfTriangle(false) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
|
bool FindDegeneratesProcess::IsActive(unsigned int pFlags) const {
|
||||||
return 0 != (pFlags & aiProcess_FindDegenerates);
|
return 0 != (pFlags & aiProcess_FindDegenerates);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup import configuration
|
// Setup import configuration
|
||||||
void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
|
void FindDegeneratesProcess::SetupProperties(const Importer *pImp) {
|
||||||
// Get the current value of AI_CONFIG_PP_FD_REMOVE
|
// Get the current value of AI_CONFIG_PP_FD_REMOVE
|
||||||
mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
|
mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE, 0));
|
||||||
mConfigCheckAreaOfTriangle = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA) );
|
mConfigCheckAreaOfTriangle = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
void FindDegeneratesProcess::Execute(aiScene *pScene) {
|
||||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
||||||
if ( nullptr == pScene) {
|
if (nullptr == pScene) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
||||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned int, unsigned int>& meshMap) {
|
static void updateSceneGraph(aiNode *pNode, const std::unordered_map<unsigned int, unsigned int> &meshMap) {
|
||||||
unsigned int targetIndex = 0;
|
unsigned int targetIndex = 0;
|
||||||
for (unsigned i = 0; i < pNode->mNumMeshes; ++i) {
|
for (unsigned i = 0; i < pNode->mNumMeshes; ++i) {
|
||||||
const unsigned int sourceMeshIndex = pNode->mMeshes[i];
|
const unsigned int sourceMeshIndex = pNode->mMeshes[i];
|
||||||
|
@ -123,7 +123,7 @@ static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pNode->mNumMeshes = targetIndex;
|
pNode->mNumMeshes = targetIndex;
|
||||||
//recurse to all children
|
// recurse to all children
|
||||||
for (unsigned i = 0; i < pNode->mNumChildren; ++i) {
|
for (unsigned i = 0; i < pNode->mNumChildren; ++i) {
|
||||||
updateSceneGraph(pNode->mChildren[i], meshMap);
|
updateSceneGraph(pNode->mChildren[i], meshMap);
|
||||||
}
|
}
|
||||||
|
@ -131,17 +131,17 @@ static void updateSceneGraph(aiNode* pNode, const std::unordered_map<unsigned in
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported mesh
|
// Executes the post processing step on the given imported mesh
|
||||||
bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
bool FindDegeneratesProcess::ExecuteOnMesh(aiMesh *mesh) {
|
||||||
mesh->mPrimitiveTypes = 0;
|
mesh->mPrimitiveTypes = 0;
|
||||||
|
|
||||||
std::vector<bool> remove_me;
|
std::vector<bool> remove_me;
|
||||||
if (mConfigRemoveDegenerates) {
|
if (mConfigRemoveDegenerates) {
|
||||||
remove_me.resize( mesh->mNumFaces, false );
|
remove_me.resize(mesh->mNumFaces, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int deg = 0, limit;
|
unsigned int deg = 0, limit;
|
||||||
for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) {
|
for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
|
||||||
aiFace& face = mesh->mFaces[a];
|
aiFace &face = mesh->mFaces[a];
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
// check whether the face contains degenerated entries
|
// check whether the face contains degenerated entries
|
||||||
|
@ -151,43 +151,43 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
// double points may not come directly after another.
|
// double points may not come directly after another.
|
||||||
limit = face.mNumIndices;
|
limit = face.mNumIndices;
|
||||||
if (face.mNumIndices > 4) {
|
if (face.mNumIndices > 4) {
|
||||||
limit = std::min( limit, i+2 );
|
limit = std::min(limit, i + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int t = i+1; t < limit; ++t) {
|
for (unsigned int t = i + 1; t < limit; ++t) {
|
||||||
if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) {
|
if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]]) {
|
||||||
// we have found a matching vertex position
|
// we have found a matching vertex position
|
||||||
// remove the corresponding index from the array
|
// remove the corresponding index from the array
|
||||||
--face.mNumIndices;
|
--face.mNumIndices;
|
||||||
--limit;
|
--limit;
|
||||||
for (unsigned int m = t; m < face.mNumIndices; ++m) {
|
for (unsigned int m = t; m < face.mNumIndices; ++m) {
|
||||||
face.mIndices[ m ] = face.mIndices[ m+1 ];
|
face.mIndices[m] = face.mIndices[m + 1];
|
||||||
}
|
}
|
||||||
--t;
|
--t;
|
||||||
|
|
||||||
// NOTE: we set the removed vertex index to an unique value
|
// NOTE: we set the removed vertex index to an unique value
|
||||||
// to make sure the developer gets notified when his
|
// to make sure the developer gets notified when his
|
||||||
// application attempts to access this data.
|
// application attempts to access this data.
|
||||||
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
|
face.mIndices[face.mNumIndices] = 0xdeadbeef;
|
||||||
|
|
||||||
if(first) {
|
if (first) {
|
||||||
++deg;
|
++deg;
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mConfigRemoveDegenerates ) {
|
if (mConfigRemoveDegenerates) {
|
||||||
remove_me[ a ] = true;
|
remove_me[a] = true;
|
||||||
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
|
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mConfigCheckAreaOfTriangle ) {
|
if (mConfigCheckAreaOfTriangle) {
|
||||||
if ( face.mNumIndices == 3 ) {
|
if (face.mNumIndices == 3) {
|
||||||
ai_real area = GeometryUtils::calculateAreaOfTriangle( face, mesh );
|
ai_real area = GeometryUtils::calculateAreaOfTriangle(face, mesh);
|
||||||
if (area < ai_epsilon) {
|
if (area < ai_epsilon) {
|
||||||
if ( mConfigRemoveDegenerates ) {
|
if (mConfigRemoveDegenerates) {
|
||||||
remove_me[ a ] = true;
|
remove_me[a] = true;
|
||||||
++deg;
|
++deg;
|
||||||
goto evil_jump_outside;
|
goto evil_jump_outside;
|
||||||
}
|
}
|
||||||
|
@ -199,8 +199,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to update the primitive flags array of the mesh.
|
// We need to update the primitive flags array of the mesh.
|
||||||
switch (face.mNumIndices)
|
switch (face.mNumIndices) {
|
||||||
{
|
|
||||||
case 1u:
|
case 1u:
|
||||||
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
break;
|
break;
|
||||||
|
@ -214,18 +213,17 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||||
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
evil_jump_outside:
|
evil_jump_outside:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
|
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
|
||||||
if (mConfigRemoveDegenerates && deg) {
|
if (mConfigRemoveDegenerates && deg) {
|
||||||
unsigned int n = 0;
|
unsigned int n = 0;
|
||||||
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
|
for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
|
||||||
{
|
aiFace &face_src = mesh->mFaces[a];
|
||||||
aiFace& face_src = mesh->mFaces[a];
|
|
||||||
if (!remove_me[a]) {
|
if (!remove_me[a]) {
|
||||||
aiFace& face_dest = mesh->mFaces[n++];
|
aiFace &face_dest = mesh->mFaces[n++];
|
||||||
|
|
||||||
// Do a manual copy, keep the index array
|
// Do a manual copy, keep the index array
|
||||||
face_dest.mNumIndices = face_src.mNumIndices;
|
face_dest.mNumIndices = face_src.mNumIndices;
|
||||||
|
@ -246,15 +244,15 @@ evil_jump_outside:
|
||||||
// Just leave the rest of the array unreferenced, we don't care for now
|
// Just leave the rest of the array unreferenced, we don't care for now
|
||||||
mesh->mNumFaces = n;
|
mesh->mNumFaces = n;
|
||||||
if (!mesh->mNumFaces) {
|
if (!mesh->mNumFaces) {
|
||||||
//The whole mesh consists of degenerated faces
|
// The whole mesh consists of degenerated faces
|
||||||
//signal upward, that this mesh should be deleted.
|
// signal upward, that this mesh should be deleted.
|
||||||
ASSIMP_LOG_VERBOSE_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
|
ASSIMP_LOG_VERBOSE_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deg && !DefaultLogger::isNullLogger()) {
|
if (deg && !DefaultLogger::isNullLogger()) {
|
||||||
ASSIMP_LOG_WARN( "Found ", deg, " degenerated primitives");
|
ASSIMP_LOG_WARN("Found ", deg, " degenerated primitives");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -41,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file PretransformVertices.cpp
|
/// @file PretransformVertices.cpp
|
||||||
* @brief Implementation of the "PretransformVertices" post processing step
|
/// @brief Implementation of the "PretransformVertices" post processing step
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PretransformVertices.h"
|
#include "PretransformVertices.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
|
@ -57,16 +54,44 @@ using namespace Assimp;
|
||||||
#define AI_PTVS_VERTEX 0x0
|
#define AI_PTVS_VERTEX 0x0
|
||||||
#define AI_PTVS_FACE 0x1
|
#define AI_PTVS_FACE 0x1
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Get a bitwise combination identifying the vertex format of a mesh
|
||||||
|
static unsigned int GetMeshVFormat(aiMesh *pcMesh) {
|
||||||
|
// the vertex format is stored in aiMesh::mBones for later retrieval.
|
||||||
|
// there isn't a good reason to compute it a few hundred times
|
||||||
|
// from scratch. The pointer is unused as animations are lost
|
||||||
|
// during PretransformVertices.
|
||||||
|
if (pcMesh->mBones)
|
||||||
|
return (unsigned int)(uint64_t)pcMesh->mBones;
|
||||||
|
|
||||||
|
const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
|
||||||
|
|
||||||
|
// store the value for later use
|
||||||
|
pcMesh->mBones = (aiBone **)(uint64_t)iRet;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a list of all vertex formats that occur for a given material index
|
||||||
|
// The output list contains duplicate elements
|
||||||
|
static void GetVFormatList(const aiScene *pcScene, unsigned int iMat, std::list<unsigned int> &aiOut) {
|
||||||
|
for (unsigned int i = 0; i < pcScene->mNumMeshes; ++i) {
|
||||||
|
aiMesh *pcMesh = pcScene->mMeshes[i];
|
||||||
|
if (iMat == pcMesh->mMaterialIndex) {
|
||||||
|
aiOut.push_back(GetMeshVFormat(pcMesh));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
PretransformVertices::PretransformVertices() :
|
PretransformVertices::PretransformVertices() :
|
||||||
configKeepHierarchy(false),
|
mConfigKeepHierarchy(false),
|
||||||
configNormalize(false),
|
mConfigNormalize(false),
|
||||||
configTransform(false),
|
mConfigTransform(false),
|
||||||
configTransformation(),
|
mConfigTransformation(),
|
||||||
mConfigPointCloud(false) {
|
mConfigPointCloud(false) {}
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
|
@ -79,11 +104,11 @@ bool PretransformVertices::IsActive(unsigned int pFlags) const {
|
||||||
void PretransformVertices::SetupProperties(const Importer *pImp) {
|
void PretransformVertices::SetupProperties(const Importer *pImp) {
|
||||||
// Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE,
|
// Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE,
|
||||||
// AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION
|
// AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION
|
||||||
configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY, 0));
|
mConfigKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY, 0));
|
||||||
configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, 0));
|
mConfigNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, 0));
|
||||||
configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION, 0));
|
mConfigTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION, 0));
|
||||||
|
|
||||||
configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
|
mConfigTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
|
||||||
|
|
||||||
mConfigPointCloud = pImp->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
|
mConfigPointCloud = pImp->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
|
||||||
}
|
}
|
||||||
|
@ -99,25 +124,7 @@ unsigned int PretransformVertices::CountNodes(const aiNode *pcNode) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a bitwise combination identifying the vertex format of a mesh
|
// Count the number of vertices in the whole scene and a given material index
|
||||||
unsigned int PretransformVertices::GetMeshVFormat(aiMesh *pcMesh) const {
|
|
||||||
// the vertex format is stored in aiMesh::mBones for later retrieval.
|
|
||||||
// there isn't a good reason to compute it a few hundred times
|
|
||||||
// from scratch. The pointer is unused as animations are lost
|
|
||||||
// during PretransformVertices.
|
|
||||||
if (pcMesh->mBones)
|
|
||||||
return (unsigned int)(uint64_t)pcMesh->mBones;
|
|
||||||
|
|
||||||
const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
|
|
||||||
|
|
||||||
// store the value for later use
|
|
||||||
pcMesh->mBones = (aiBone **)(uint64_t)iRet;
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Count the number of vertices in the whole scene and a given
|
|
||||||
// material index
|
|
||||||
void PretransformVertices::CountVerticesAndFaces(const aiScene *pcScene, const aiNode *pcNode, unsigned int iMat,
|
void PretransformVertices::CountVerticesAndFaces(const aiScene *pcScene, const aiNode *pcNode, unsigned int iMat,
|
||||||
unsigned int iVFormat, unsigned int *piFaces, unsigned int *piVertices) const {
|
unsigned int iVFormat, unsigned int *piFaces, unsigned int *piVertices) const {
|
||||||
for (unsigned int i = 0; i < pcNode->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < pcNode->mNumMeshes; ++i) {
|
||||||
|
@ -128,8 +135,7 @@ void PretransformVertices::CountVerticesAndFaces(const aiScene *pcScene, const a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) {
|
||||||
CountVerticesAndFaces(pcScene, pcNode->mChildren[i], iMat,
|
CountVerticesAndFaces(pcScene, pcNode->mChildren[i], iMat, iVFormat, piFaces, piVertices);
|
||||||
iVFormat, piFaces, piVertices);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,19 +278,6 @@ void PretransformVertices::CollectData(const aiScene *pcScene, const aiNode *pcN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Get a list of all vertex formats that occur for a given material index
|
|
||||||
// The output list contains duplicate elements
|
|
||||||
void PretransformVertices::GetVFormatList(const aiScene *pcScene, unsigned int iMat,
|
|
||||||
std::list<unsigned int> &aiOut) const {
|
|
||||||
for (unsigned int i = 0; i < pcScene->mNumMeshes; ++i) {
|
|
||||||
aiMesh *pcMesh = pcScene->mMeshes[i];
|
|
||||||
if (iMat == pcMesh->mMaterialIndex) {
|
|
||||||
aiOut.push_back(GetMeshVFormat(pcMesh));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Compute the absolute transformation matrices of each node
|
// Compute the absolute transformation matrices of each node
|
||||||
void PretransformVertices::ComputeAbsoluteTransform(aiNode *pcNode) {
|
void PretransformVertices::ComputeAbsoluteTransform(aiNode *pcNode) {
|
||||||
|
@ -297,11 +290,19 @@ void PretransformVertices::ComputeAbsoluteTransform(aiNode *pcNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut, size_t numVectors) {
|
||||||
|
for (size_t i=0; i<numVectors; ++i) {
|
||||||
|
vectorArrayOut[i] = vectorArrayIn[i].Normalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Apply the node transformation to a mesh
|
// Apply the node transformation to a mesh
|
||||||
void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat) const {
|
void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat) const {
|
||||||
// Check whether we need to transform the coordinates at all
|
// Check whether we need to transform the coordinates at all
|
||||||
if (!mat.IsIdentity()) {
|
if (mat.IsIdentity()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for odd negative scale (mirror)
|
// Check for odd negative scale (mirror)
|
||||||
if (mesh->HasFaces() && mat.Determinant() < 0) {
|
if (mesh->HasFaces() && mat.Determinant() < 0) {
|
||||||
|
@ -321,9 +322,7 @@ void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat)
|
||||||
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
|
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
|
||||||
|
|
||||||
if (mesh->HasNormals()) {
|
if (mesh->HasNormals()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
|
||||||
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (mesh->HasTangentsAndBitangents()) {
|
if (mesh->HasTangentsAndBitangents()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
|
@ -332,7 +331,6 @@ void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -352,7 +350,8 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **i
|
||||||
// yes, we can.
|
// yes, we can.
|
||||||
mesh->mBones = reinterpret_cast<aiBone **>(&node->mTransformation);
|
mesh->mBones = reinterpret_cast<aiBone **>(&node->mTransformation);
|
||||||
mesh->mNumBones = UINT_MAX;
|
mesh->mNumBones = UINT_MAX;
|
||||||
} else {
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// try to find us in the list of newly created meshes
|
// try to find us in the list of newly created meshes
|
||||||
for (unsigned int n = 0; n < out.size(); ++n) {
|
for (unsigned int n = 0; n < out.size(); ++n) {
|
||||||
|
@ -368,10 +367,10 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **i
|
||||||
ASSIMP_LOG_INFO("PretransformVertices: Copying mesh due to mismatching transforms");
|
ASSIMP_LOG_INFO("PretransformVertices: Copying mesh due to mismatching transforms");
|
||||||
aiMesh *ntz;
|
aiMesh *ntz;
|
||||||
|
|
||||||
const unsigned int tmp = mesh->mNumBones; //
|
const unsigned int cacheNumBones = mesh->mNumBones; //
|
||||||
mesh->mNumBones = 0;
|
mesh->mNumBones = 0;
|
||||||
SceneCombiner::Copy(&ntz, mesh);
|
SceneCombiner::Copy(&ntz, mesh);
|
||||||
mesh->mNumBones = tmp;
|
mesh->mNumBones = cacheNumBones;
|
||||||
|
|
||||||
ntz->mNumBones = node->mMeshes[i];
|
ntz->mNumBones = node->mMeshes[i];
|
||||||
ntz->mBones = reinterpret_cast<aiBone **>(&node->mTransformation);
|
ntz->mBones = reinterpret_cast<aiBone **>(&node->mTransformation);
|
||||||
|
@ -381,11 +380,11 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **i
|
||||||
node->mMeshes[i] = static_cast<unsigned int>(numIn + out.size() - 1);
|
node->mMeshes[i] = static_cast<unsigned int>(numIn + out.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// call children
|
// call children
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; ++i)
|
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
|
||||||
BuildWCSMeshes(out, in, numIn, node->mChildren[i]);
|
BuildWCSMeshes(out, in, numIn, node->mChildren[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -394,8 +393,9 @@ void PretransformVertices::MakeIdentityTransform(aiNode *nd) const {
|
||||||
nd->mTransformation = aiMatrix4x4();
|
nd->mTransformation = aiMatrix4x4();
|
||||||
|
|
||||||
// call children
|
// call children
|
||||||
for (unsigned int i = 0; i < nd->mNumChildren; ++i)
|
for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
|
||||||
MakeIdentityTransform(nd->mChildren[i]);
|
MakeIdentityTransform(nd->mChildren[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -405,8 +405,27 @@ void PretransformVertices::BuildMeshRefCountArray(const aiNode *nd, unsigned int
|
||||||
refs[nd->mMeshes[i]]++;
|
refs[nd->mMeshes[i]]++;
|
||||||
|
|
||||||
// call children
|
// call children
|
||||||
for (unsigned int i = 0; i < nd->mNumChildren; ++i)
|
for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
|
||||||
BuildMeshRefCountArray(nd->mChildren[i], refs);
|
BuildMeshRefCountArray(nd->mChildren[i], refs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static void appendNewMeshesToScene(aiScene *pScene, std::vector<aiMesh*> &apcOutMeshes) {
|
||||||
|
ai_assert(pScene != nullptr);
|
||||||
|
|
||||||
|
if (apcOutMeshes.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMesh **npp = new aiMesh *[pScene->mNumMeshes + apcOutMeshes.size()];
|
||||||
|
|
||||||
|
::memcpy(npp, pScene->mMeshes, sizeof(aiMesh *) * pScene->mNumMeshes);
|
||||||
|
::memcpy(npp + pScene->mNumMeshes, &apcOutMeshes[0], sizeof(aiMesh *) * apcOutMeshes.size());
|
||||||
|
|
||||||
|
pScene->mNumMeshes += static_cast<unsigned int>(apcOutMeshes.size());
|
||||||
|
delete[] pScene->mMeshes;
|
||||||
|
pScene->mMeshes = npp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -418,12 +437,12 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
if (!pScene->mNumMeshes)
|
if (!pScene->mNumMeshes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const unsigned int iOldMeshes = pScene->mNumMeshes;
|
const unsigned int oldMeshes = pScene->mNumMeshes;
|
||||||
const unsigned int iOldAnimationChannels = pScene->mNumAnimations;
|
const unsigned int oldAnimationChannels = pScene->mNumAnimations;
|
||||||
const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
|
const unsigned int oldNodes = CountNodes(pScene->mRootNode);
|
||||||
|
|
||||||
if (configTransform) {
|
if (mConfigTransform) {
|
||||||
pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation;
|
pScene->mRootNode->mTransformation = mConfigTransformation * pScene->mRootNode->mTransformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first compute absolute transformation matrices for all nodes
|
// first compute absolute transformation matrices for all nodes
|
||||||
|
@ -449,22 +468,13 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
// we go on and transform all meshes, if one is referenced by nodes
|
// we go on and transform all meshes, if one is referenced by nodes
|
||||||
// with different absolute transformations a depth copy of the mesh
|
// with different absolute transformations a depth copy of the mesh
|
||||||
// is required.
|
// is required.
|
||||||
if (configKeepHierarchy) {
|
if (mConfigKeepHierarchy) {
|
||||||
|
|
||||||
// Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
|
// Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
|
||||||
BuildWCSMeshes(apcOutMeshes, pScene->mMeshes, pScene->mNumMeshes, pScene->mRootNode);
|
BuildWCSMeshes(apcOutMeshes, pScene->mMeshes, pScene->mNumMeshes, pScene->mRootNode);
|
||||||
|
|
||||||
// ... if new meshes have been generated, append them to the end of the scene
|
// ... if new meshes have been generated, append them to the end of the scene
|
||||||
if (apcOutMeshes.size() > 0) {
|
appendNewMeshesToScene(pScene, apcOutMeshes);
|
||||||
aiMesh **npp = new aiMesh *[pScene->mNumMeshes + apcOutMeshes.size()];
|
|
||||||
|
|
||||||
memcpy(npp, pScene->mMeshes, sizeof(aiMesh *) * pScene->mNumMeshes);
|
|
||||||
memcpy(npp + pScene->mNumMeshes, &apcOutMeshes[0], sizeof(aiMesh *) * apcOutMeshes.size());
|
|
||||||
|
|
||||||
pScene->mNumMeshes += static_cast<unsigned int>(apcOutMeshes.size());
|
|
||||||
delete[] pScene->mMeshes;
|
|
||||||
pScene->mMeshes = npp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now iterate through all meshes and transform them to world-space
|
// now iterate through all meshes and transform them to world-space
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
|
@ -488,34 +498,35 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
aiVFormats.sort();
|
aiVFormats.sort();
|
||||||
aiVFormats.unique();
|
aiVFormats.unique();
|
||||||
for (std::list<unsigned int>::const_iterator j = aiVFormats.begin(); j != aiVFormats.end(); ++j) {
|
for (std::list<unsigned int>::const_iterator j = aiVFormats.begin(); j != aiVFormats.end(); ++j) {
|
||||||
unsigned int iVertices = 0;
|
unsigned int numVertices = 0u;
|
||||||
unsigned int iFaces = 0;
|
unsigned int numFaces = 0u;
|
||||||
CountVerticesAndFaces(pScene, pScene->mRootNode, i, *j, &iFaces, &iVertices);
|
CountVerticesAndFaces(pScene, pScene->mRootNode, i, *j, &numFaces, &numVertices);
|
||||||
if (0 != iFaces && 0 != iVertices) {
|
if (0 != numFaces && 0 != numVertices) {
|
||||||
apcOutMeshes.push_back(new aiMesh());
|
apcOutMeshes.push_back(new aiMesh());
|
||||||
aiMesh *pcMesh = apcOutMeshes.back();
|
aiMesh *pcMesh = apcOutMeshes.back();
|
||||||
pcMesh->mNumFaces = iFaces;
|
pcMesh->mNumFaces = numFaces;
|
||||||
pcMesh->mNumVertices = iVertices;
|
pcMesh->mNumVertices = numVertices;
|
||||||
pcMesh->mFaces = new aiFace[iFaces];
|
pcMesh->mFaces = new aiFace[numFaces];
|
||||||
pcMesh->mVertices = new aiVector3D[iVertices];
|
pcMesh->mVertices = new aiVector3D[numVertices];
|
||||||
pcMesh->mMaterialIndex = i;
|
pcMesh->mMaterialIndex = i;
|
||||||
if ((*j) & 0x2) pcMesh->mNormals = new aiVector3D[iVertices];
|
if ((*j) & 0x2) pcMesh->mNormals = new aiVector3D[numVertices];
|
||||||
if ((*j) & 0x4) {
|
if ((*j) & 0x4) {
|
||||||
pcMesh->mTangents = new aiVector3D[iVertices];
|
pcMesh->mTangents = new aiVector3D[numVertices];
|
||||||
pcMesh->mBitangents = new aiVector3D[iVertices];
|
pcMesh->mBitangents = new aiVector3D[numVertices];
|
||||||
}
|
}
|
||||||
iFaces = 0;
|
numFaces = 0;
|
||||||
while ((*j) & (0x100 << iFaces)) {
|
while ((*j) & (0x100 << numFaces)) {
|
||||||
pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
|
pcMesh->mTextureCoords[numFaces] = new aiVector3D[numVertices];
|
||||||
if ((*j) & (0x10000 << iFaces))
|
if ((*j) & (0x10000 << numFaces)) {
|
||||||
pcMesh->mNumUVComponents[iFaces] = 3;
|
pcMesh->mNumUVComponents[numFaces] = 3;
|
||||||
else
|
} else {
|
||||||
pcMesh->mNumUVComponents[iFaces] = 2;
|
pcMesh->mNumUVComponents[numFaces] = 2;
|
||||||
iFaces++;
|
|
||||||
}
|
}
|
||||||
iFaces = 0;
|
++numFaces;
|
||||||
while ((*j) & (0x1000000 << iFaces))
|
}
|
||||||
pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];
|
numFaces = 0;
|
||||||
|
while ((*j) & (0x1000000 << numFaces))
|
||||||
|
pcMesh->mColors[numFaces++] = new aiColor4D[numVertices];
|
||||||
|
|
||||||
// fill the mesh ...
|
// fill the mesh ...
|
||||||
unsigned int aiTemp[2] = { 0, 0 };
|
unsigned int aiTemp[2] = { 0, 0 };
|
||||||
|
@ -593,7 +604,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
l->mUp = aiMatrix3x3(nd->mTransformation) * l->mUp;
|
l->mUp = aiMatrix3x3(nd->mTransformation) * l->mUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!configKeepHierarchy) {
|
if (!mConfigKeepHierarchy) {
|
||||||
|
|
||||||
// now delete all nodes in the scene and build a new
|
// now delete all nodes in the scene and build a new
|
||||||
// flat node graph with a root node and some level 1 children
|
// flat node graph with a root node and some level 1 children
|
||||||
|
@ -644,7 +655,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
MakeIdentityTransform(pScene->mRootNode);
|
MakeIdentityTransform(pScene->mRootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configNormalize) {
|
if (mConfigNormalize) {
|
||||||
// compute the boundary of all meshes
|
// compute the boundary of all meshes
|
||||||
aiVector3D min, max;
|
aiVector3D min, max;
|
||||||
MinMaxChooser<aiVector3D>()(min, max);
|
MinMaxChooser<aiVector3D>()(min, max);
|
||||||
|
@ -674,9 +685,9 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
ASSIMP_LOG_DEBUG("PretransformVerticesProcess finished");
|
ASSIMP_LOG_DEBUG("PretransformVerticesProcess finished");
|
||||||
|
|
||||||
ASSIMP_LOG_INFO("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (",
|
ASSIMP_LOG_INFO("Removed ", oldNodes, " nodes and ", oldAnimationChannels, " animation channels (",
|
||||||
CountNodes(pScene->mRootNode), " output nodes)");
|
CountNodes(pScene->mRootNode), " output nodes)");
|
||||||
ASSIMP_LOG_INFO("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras.");
|
ASSIMP_LOG_INFO("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras.");
|
||||||
ASSIMP_LOG_INFO("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")");
|
ASSIMP_LOG_INFO("Moved ", oldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public:
|
||||||
* @param keep true for keep configuration.
|
* @param keep true for keep configuration.
|
||||||
*/
|
*/
|
||||||
void KeepHierarchy(bool keep) {
|
void KeepHierarchy(bool keep) {
|
||||||
configKeepHierarchy = keep;
|
mConfigKeepHierarchy = keep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -98,7 +98,7 @@ public:
|
||||||
* @return ...
|
* @return ...
|
||||||
*/
|
*/
|
||||||
bool IsHierarchyKept() const {
|
bool IsHierarchyKept() const {
|
||||||
return configKeepHierarchy;
|
return mConfigKeepHierarchy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -108,7 +108,7 @@ private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get a bitwise combination identifying the vertex format of a mesh
|
// Get a bitwise combination identifying the vertex format of a mesh
|
||||||
unsigned int GetMeshVFormat(aiMesh *pcMesh) const;
|
//unsigned int GetMeshVFormat(aiMesh *pcMesh) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Count the number of vertices in the whole scene and a given
|
// Count the number of vertices in the whole scene and a given
|
||||||
|
@ -131,8 +131,8 @@ private:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get a list of all vertex formats that occur for a given material
|
// Get a list of all vertex formats that occur for a given material
|
||||||
// The output list contains duplicate elements
|
// The output list contains duplicate elements
|
||||||
void GetVFormatList(const aiScene *pcScene, unsigned int iMat,
|
/*void GetVFormatList(const aiScene *pcScene, unsigned int iMat,
|
||||||
std::list<unsigned int> &aiOut) const;
|
std::list<unsigned int> &aiOut) const;*/
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Compute the absolute transformation matrices of each node
|
// Compute the absolute transformation matrices of each node
|
||||||
|
@ -156,10 +156,10 @@ private:
|
||||||
void BuildMeshRefCountArray(const aiNode *nd, unsigned int *refs) const;
|
void BuildMeshRefCountArray(const aiNode *nd, unsigned int *refs) const;
|
||||||
|
|
||||||
//! Configuration option: keep scene hierarchy as long as possible
|
//! Configuration option: keep scene hierarchy as long as possible
|
||||||
bool configKeepHierarchy;
|
bool mConfigKeepHierarchy;
|
||||||
bool configNormalize;
|
bool mConfigNormalize;
|
||||||
bool configTransform;
|
bool mConfigTransform;
|
||||||
aiMatrix4x4 configTransformation;
|
aiMatrix4x4 mConfigTransformation;
|
||||||
bool mConfigPointCloud;
|
bool mConfigPointCloud;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -175,10 +175,9 @@ unsigned int GetMeshVFormatUnique(const aiMesh *pcMesh) {
|
||||||
// tangents and bitangents
|
// tangents and bitangents
|
||||||
if (pcMesh->HasTangentsAndBitangents()) iRet |= 0x4;
|
if (pcMesh->HasTangentsAndBitangents()) iRet |= 0x4;
|
||||||
|
|
||||||
#ifdef BOOST_STATIC_ASSERT
|
|
||||||
BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
|
static_assert(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
|
||||||
BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
static_assert(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
||||||
#endif
|
|
||||||
|
|
||||||
// texture coordinates
|
// texture coordinates
|
||||||
unsigned int p = 0;
|
unsigned int p = 0;
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -45,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
|
||||||
#include "RemoveRedundantMaterials.h"
|
#include "RemoveRedundantMaterials.h"
|
||||||
#include <assimp/ParsingUtils.h>
|
#include <assimp/ParsingUtils.h>
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
|
@ -57,35 +54,28 @@ using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
|
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess() : mConfigFixedMaterials() {}
|
||||||
: mConfigFixedMaterials() {
|
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
|
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
|
return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup import properties
|
// Setup import properties
|
||||||
void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
|
void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp) {
|
||||||
{
|
|
||||||
// Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
|
// Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
|
||||||
mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
|
mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
|
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
|
||||||
|
|
||||||
unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
|
unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
|
||||||
if (pScene->mNumMaterials)
|
if (pScene->mNumMaterials) {
|
||||||
{
|
|
||||||
// Find out which materials are referenced by meshes
|
// Find out which materials are referenced by meshes
|
||||||
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
|
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
|
||||||
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
|
||||||
|
@ -134,8 +124,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
// we do already have a specific hash. This allows us to
|
// we do already have a specific hash. This allows us to
|
||||||
// determine which materials are identical.
|
// determine which materials are identical.
|
||||||
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
|
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
|
||||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
|
||||||
{
|
|
||||||
// No mesh is referencing this material, remove it.
|
// No mesh is referencing this material, remove it.
|
||||||
if (!abReferenced[i]) {
|
if (!abReferenced[i]) {
|
||||||
++unreferencedRemoved;
|
++unreferencedRemoved;
|
||||||
|
@ -147,8 +136,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
// Check all previously mapped materials for a matching hash.
|
// Check all previously mapped materials for a matching hash.
|
||||||
// On a match we can delete this material and just make it ref to the same index.
|
// On a match we can delete this material and just make it ref to the same index.
|
||||||
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
|
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
|
||||||
for (unsigned int a = 0; a < i;++a)
|
for (unsigned int a = 0; a < i;++a) {
|
||||||
{
|
|
||||||
if (abReferenced[a] && me == aiHashes[a]) {
|
if (abReferenced[a] && me == aiHashes[a]) {
|
||||||
++redundantRemoved;
|
++redundantRemoved;
|
||||||
me = 0;
|
me = 0;
|
||||||
|
@ -205,12 +193,9 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
delete[] aiHashes;
|
delete[] aiHashes;
|
||||||
delete[] aiMappingTable;
|
delete[] aiMappingTable;
|
||||||
}
|
}
|
||||||
if (redundantRemoved == 0 && unreferencedRemoved == 0)
|
if (redundantRemoved == 0 && unreferencedRemoved == 0) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
|
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ",
|
ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ",
|
||||||
unreferencedRemoved, " unused materials.");
|
unreferencedRemoved, " unused materials.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
|
@ -99,8 +99,9 @@ void UpdateNodes(const std::vector<unsigned int> &replaceMeshIndex, aiNode *node
|
||||||
}
|
}
|
||||||
|
|
||||||
// call all subnodes recursively
|
// call all subnodes recursively
|
||||||
for (unsigned int m = 0; m < node->mNumChildren; ++m)
|
for (unsigned int m = 0; m < node->mNumChildren; ++m) {
|
||||||
UpdateNodes(replaceMeshIndex, node->mChildren[m]);
|
UpdateNodes(replaceMeshIndex, node->mChildren[m]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -57,9 +57,7 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor
|
// Constructor
|
||||||
SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {
|
SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {}
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag.
|
// Returns whether the processing step is present in the given flag.
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -40,9 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/// @file Implementation of the SplitLargeMeshes postprocessing step
|
||||||
* @file Implementation of the SplitLargeMeshes postprocessing step
|
|
||||||
*/
|
|
||||||
|
|
||||||
// internal headers of the post-processing framework
|
// internal headers of the post-processing framework
|
||||||
#include "SplitLargeMeshes.h"
|
#include "SplitLargeMeshes.h"
|
||||||
|
@ -75,7 +72,10 @@ void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
|
||||||
this->SplitMesh(a, pScene->mMeshes[a],avList);
|
this->SplitMesh(a, pScene->mMeshes[a],avList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avList.size() != pScene->mNumMeshes) {
|
if (avList.size() == pScene->mNumMeshes) {
|
||||||
|
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
|
||||||
|
}
|
||||||
|
|
||||||
// it seems something has been split. rebuild the mesh list
|
// it seems something has been split. rebuild the mesh list
|
||||||
delete[] pScene->mMeshes;
|
delete[] pScene->mMeshes;
|
||||||
pScene->mNumMeshes = (unsigned int)avList.size();
|
pScene->mNumMeshes = (unsigned int)avList.size();
|
||||||
|
@ -88,9 +88,6 @@ void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
|
||||||
// now we need to update all nodes
|
// now we need to update all nodes
|
||||||
this->UpdateNode(pScene->mRootNode,avList);
|
this->UpdateNode(pScene->mRootNode,avList);
|
||||||
ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
|
ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
|
||||||
} else {
|
|
||||||
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -102,8 +99,7 @@ void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Update a node after some meshes have been split
|
// Update a node after some meshes have been split
|
||||||
void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
|
void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
|
||||||
const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
|
|
||||||
// for every index in out list build a new entry
|
// for every index in out list build a new entry
|
||||||
std::vector<unsigned int> aiEntries;
|
std::vector<unsigned int> aiEntries;
|
||||||
aiEntries.reserve(pcNode->mNumMeshes + 1);
|
aiEntries.reserve(pcNode->mNumMeshes + 1);
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -42,8 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file A helper class that processes texture transformations */
|
/** @file A helper class that processes texture transformations */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
@ -494,8 +491,9 @@ void TextureTransformStep::Execute( aiScene* pScene) {
|
||||||
ai_assert(nullptr != src);
|
ai_assert(nullptr != src);
|
||||||
|
|
||||||
// Copy the data to the destination array
|
// Copy the data to the destination array
|
||||||
if (dest != src)
|
if (dest != src) {
|
||||||
::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);
|
::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);
|
||||||
|
}
|
||||||
|
|
||||||
end = dest + mesh->mNumVertices;
|
end = dest + mesh->mNumVertices;
|
||||||
|
|
||||||
|
|
|
@ -158,15 +158,13 @@ namespace {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 TriangulateProcess::IsActive( unsigned int pFlags) const
|
bool TriangulateProcess::IsActive( unsigned int pFlags) const {
|
||||||
{
|
|
||||||
return (pFlags & aiProcess_Triangulate) != 0;
|
return (pFlags & aiProcess_Triangulate) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void TriangulateProcess::Execute( aiScene* pScene)
|
void TriangulateProcess::Execute( aiScene* pScene) {
|
||||||
{
|
|
||||||
ASSIMP_LOG_DEBUG("TriangulateProcess begin");
|
ASSIMP_LOG_DEBUG("TriangulateProcess begin");
|
||||||
|
|
||||||
bool bHas = false;
|
bool bHas = false;
|
||||||
|
@ -187,8 +185,7 @@ void TriangulateProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Triangulates the given mesh.
|
// Triangulates the given mesh.
|
||||||
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) {
|
||||||
{
|
|
||||||
// Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
|
// Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
|
||||||
if (!pMesh->mPrimitiveTypes) {
|
if (!pMesh->mPrimitiveTypes) {
|
||||||
bool bNeed = false;
|
bool bNeed = false;
|
||||||
|
@ -218,8 +215,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
if( face.mNumIndices <= 3) {
|
if( face.mNumIndices <= 3) {
|
||||||
numOut++;
|
numOut++;
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
numOut += face.mNumIndices-2;
|
numOut += face.mNumIndices-2;
|
||||||
max_out = std::max(max_out,face.mNumIndices);
|
max_out = std::max(max_out,face.mNumIndices);
|
||||||
}
|
}
|
||||||
|
@ -511,22 +507,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
#endif
|
#endif
|
||||||
num = 0;
|
num = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*curOut -= (max-num); // undo all previous work
|
|
||||||
for (tmp = 0; tmp < max-2; ++tmp) {
|
|
||||||
aiFace& nface = *curOut++;
|
|
||||||
|
|
||||||
nface.mNumIndices = 3;
|
|
||||||
if (!nface.mIndices)
|
|
||||||
nface.mIndices = new unsigned int[3];
|
|
||||||
|
|
||||||
nface.mIndices[0] = 0;
|
|
||||||
nface.mIndices[1] = tmp+1;
|
|
||||||
nface.mIndices[2] = tmp+2;
|
|
||||||
|
|
||||||
}
|
|
||||||
num = 0;
|
|
||||||
break;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aiFace& nface = *curOut++;
|
aiFace& nface = *curOut++;
|
||||||
|
@ -580,23 +560,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||||
for(aiFace* f = last_face; f != curOut; ) {
|
for(aiFace* f = last_face; f != curOut; ) {
|
||||||
unsigned int* i = f->mIndices;
|
unsigned int* i = f->mIndices;
|
||||||
|
|
||||||
// drop dumb 0-area triangles - deactivated for now:
|
|
||||||
//FindDegenerates post processing step can do the same thing
|
|
||||||
//if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
|
|
||||||
// ASSIMP_LOG_VERBOSE_DEBUG("Dropping triangle with area 0");
|
|
||||||
// --curOut;
|
|
||||||
|
|
||||||
// delete[] f->mIndices;
|
|
||||||
// f->mIndices = nullptr;
|
|
||||||
|
|
||||||
// for(aiFace* ff = f; ff != curOut; ++ff) {
|
|
||||||
// ff->mNumIndices = (ff+1)->mNumIndices;
|
|
||||||
// ff->mIndices = (ff+1)->mIndices;
|
|
||||||
// (ff+1)->mIndices = nullptr;
|
|
||||||
// }
|
|
||||||
// continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
i[0] = idx[i[0]];
|
i[0] = idx[i[0]];
|
||||||
i[1] = idx[i[1]];
|
i[1] = idx[i[1]];
|
||||||
i[2] = idx[i[2]];
|
i[2] = idx[i[2]];
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -110,11 +108,15 @@ inline int HasNameMatch(const aiString &in, aiNode *node) {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
|
inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
|
||||||
// validate all entries
|
// validate all entries
|
||||||
if (size) {
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!parray) {
|
if (!parray) {
|
||||||
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
||||||
firstName, secondName, size);
|
firstName, secondName, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < size; ++i) {
|
for (unsigned int i = 0; i < size; ++i) {
|
||||||
if (!parray[i]) {
|
if (!parray[i]) {
|
||||||
ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
|
ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
|
||||||
|
@ -122,7 +124,6 @@ inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const
|
||||||
}
|
}
|
||||||
Validate(parray[i]);
|
Validate(parray[i]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -130,7 +131,10 @@ template <typename T>
|
||||||
inline void ValidateDSProcess::DoValidationEx(T **parray, unsigned int size,
|
inline void ValidateDSProcess::DoValidationEx(T **parray, unsigned int size,
|
||||||
const char *firstName, const char *secondName) {
|
const char *firstName, const char *secondName) {
|
||||||
// validate all entries
|
// validate all entries
|
||||||
if (size) {
|
if (size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!parray) {
|
if (!parray) {
|
||||||
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
||||||
firstName, secondName, size);
|
firstName, secondName, size);
|
||||||
|
@ -151,7 +155,6 @@ inline void ValidateDSProcess::DoValidationEx(T **parray, unsigned int size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -229,12 +232,6 @@ void ValidateDSProcess::Execute(aiScene *pScene) {
|
||||||
if (pScene->mNumMaterials) {
|
if (pScene->mNumMaterials) {
|
||||||
DoValidation(pScene->mMaterials, pScene->mNumMaterials, "mMaterials", "mNumMaterials");
|
DoValidation(pScene->mMaterials, pScene->mNumMaterials, "mMaterials", "mNumMaterials");
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// NOTE: ScenePreprocessor generates a default material if none is there
|
|
||||||
else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
|
|
||||||
ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else if (pScene->mMaterials) {
|
else if (pScene->mMaterials) {
|
||||||
ReportError("aiScene::mMaterials is non-null although there are no materials");
|
ReportError("aiScene::mMaterials is non-null although there are no materials");
|
||||||
}
|
}
|
||||||
|
@ -267,8 +264,7 @@ void ValidateDSProcess::Validate(const aiCamera *pCamera) {
|
||||||
if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
|
if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
|
||||||
ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
|
ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
|
||||||
|
|
||||||
// FIX: there are many 3ds files with invalid FOVs. No reason to
|
// There are many 3ds files with invalid FOVs. No reason to reject them at all ... a warning is appropriate.
|
||||||
// reject them at all ... a warning is appropriate.
|
|
||||||
if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
|
if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
|
||||||
ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV", pCamera->mHorizontalFOV);
|
ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV", pCamera->mHorizontalFOV);
|
||||||
}
|
}
|
||||||
|
@ -362,15 +358,6 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh) {
|
||||||
if (face.mIndices[a] >= pMesh->mNumVertices) {
|
if (face.mIndices[a] >= pMesh->mNumVertices) {
|
||||||
ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range", i, a);
|
ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range", i, a);
|
||||||
}
|
}
|
||||||
// the MSB flag is temporarily used by the extra verbose
|
|
||||||
// mode to tell us that the JoinVerticesProcess might have
|
|
||||||
// been executed already.
|
|
||||||
/*if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) &&
|
|
||||||
abRefList[face.mIndices[a]])
|
|
||||||
{
|
|
||||||
ReportError("aiMesh::mVertices[%i] is referenced twice - second "
|
|
||||||
"time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
|
|
||||||
}*/
|
|
||||||
abRefList[face.mIndices[a]] = true;
|
abRefList[face.mIndices[a]] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,7 +453,7 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh, const aiBone *pBone, float
|
||||||
this->Validate(&pBone->mName);
|
this->Validate(&pBone->mName);
|
||||||
|
|
||||||
if (!pBone->mNumWeights) {
|
if (!pBone->mNumWeights) {
|
||||||
//ReportError("aiBone::mNumWeights is zero");
|
ReportWarning("aiBone::mNumWeights is zero");
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether all vertices affected by this bone are valid
|
// check whether all vertices affected by this bone are valid
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2022, assimp team
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -68,8 +66,7 @@ namespace Assimp {
|
||||||
*/
|
*/
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
|
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
|
||||||
class StreamWriter
|
class StreamWriter {
|
||||||
{
|
|
||||||
enum {
|
enum {
|
||||||
INITIAL_CAPACITY = 1024
|
INITIAL_CAPACITY = 1024
|
||||||
};
|
};
|
||||||
|
|
|
@ -97,14 +97,20 @@ namespace Assimp {
|
||||||
* to *all* vertex components equally. This is useful for stuff like interpolation
|
* to *all* vertex components equally. This is useful for stuff like interpolation
|
||||||
* or subdivision, but won't work if special handling is required for some vertex components. */
|
* or subdivision, but won't work if special handling is required for some vertex components. */
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
class Vertex {
|
struct Vertex {
|
||||||
friend Vertex operator + (const Vertex&,const Vertex&);
|
friend Vertex operator + (const Vertex&,const Vertex&);
|
||||||
friend Vertex operator - (const Vertex&,const Vertex&);
|
friend Vertex operator - (const Vertex&,const Vertex&);
|
||||||
friend Vertex operator * (const Vertex&,ai_real);
|
friend Vertex operator * (const Vertex&,ai_real);
|
||||||
friend Vertex operator / (const Vertex&,ai_real);
|
friend Vertex operator / (const Vertex&,ai_real);
|
||||||
friend Vertex operator * (ai_real, const Vertex&);
|
friend Vertex operator * (ai_real, const Vertex&);
|
||||||
|
|
||||||
public:
|
aiVector3D position;
|
||||||
|
aiVector3D normal;
|
||||||
|
aiVector3D tangent, bitangent;
|
||||||
|
|
||||||
|
aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
|
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||||
|
|
||||||
Vertex() = default;
|
Vertex() = default;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -178,7 +184,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Convert back to non-interleaved storage */
|
/// Convert back to non-interleaved storage
|
||||||
void SortBack(aiMesh* out, unsigned int idx) const {
|
void SortBack(aiMesh* out, unsigned int idx) const {
|
||||||
ai_assert(idx<out->mNumVertices);
|
ai_assert(idx<out->mNumVertices);
|
||||||
out->mVertices[idx] = position;
|
out->mVertices[idx] = position;
|
||||||
|
@ -204,7 +210,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Construct from two operands and a binary operation to combine them */
|
/// Construct from two operands and a binary operation to combine them
|
||||||
template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
|
template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
|
||||||
// this is a heavy task for the compiler to optimize ... *pray*
|
// this is a heavy task for the compiler to optimize ... *pray*
|
||||||
|
|
||||||
|
@ -224,7 +230,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** This time binary arithmetic of v0 with a floating-point number */
|
/// This time binary arithmetic of v0 with a floating-point number
|
||||||
template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) {
|
template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) {
|
||||||
// this is a heavy task for the compiler to optimize ... *pray*
|
// this is a heavy task for the compiler to optimize ... *pray*
|
||||||
|
|
||||||
|
@ -262,15 +268,6 @@ private:
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
aiVector3D position;
|
|
||||||
aiVector3D normal;
|
|
||||||
aiVector3D tangent, bitangent;
|
|
||||||
|
|
||||||
aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
|
||||||
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -102,6 +102,10 @@ SET( COMMON
|
||||||
unit/Common/utBaseProcess.cpp
|
unit/Common/utBaseProcess.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SET(Geometry
|
||||||
|
unit/Geometry/utGeometryUtils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
SET( IMPORTERS
|
SET( IMPORTERS
|
||||||
unit/ImportExport/Assxml/utAssxmlImportExport.cpp
|
unit/ImportExport/Assxml/utAssxmlImportExport.cpp
|
||||||
unit/utLWSImportExport.cpp
|
unit/utLWSImportExport.cpp
|
||||||
|
@ -202,6 +206,7 @@ SET( POST_PROCESSES
|
||||||
|
|
||||||
SOURCE_GROUP( UnitTests\\Compiler FILES unit/CCompilerTest.c )
|
SOURCE_GROUP( UnitTests\\Compiler FILES unit/CCompilerTest.c )
|
||||||
SOURCE_GROUP( UnitTests\\Common FILES ${COMMON} )
|
SOURCE_GROUP( UnitTests\\Common FILES ${COMMON} )
|
||||||
|
SOURCE_GROUP( UnitTests\\GeometryTools FILES ${Geometry} )
|
||||||
SOURCE_GROUP( UnitTests\\ImportExport FILES ${IMPORTERS} )
|
SOURCE_GROUP( UnitTests\\ImportExport FILES ${IMPORTERS} )
|
||||||
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
|
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
|
||||||
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
|
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
|
||||||
|
@ -213,6 +218,7 @@ add_executable( unit
|
||||||
../code/Common/Version.cpp
|
../code/Common/Version.cpp
|
||||||
../code/Common/Base64.cpp
|
../code/Common/Base64.cpp
|
||||||
${COMMON}
|
${COMMON}
|
||||||
|
${Geometry}
|
||||||
${IMPORTERS}
|
${IMPORTERS}
|
||||||
${MATERIAL}
|
${MATERIAL}
|
||||||
${MATH}
|
${MATH}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2022, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utGeometryUtils : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void SetUp() override {
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static constexpr size_t NumVectors = 100;
|
||||||
|
TEST_F(utGeometryUtils, normalizeVectorArrayTest) {
|
||||||
|
aiVector3D *inNormals = new aiVector3D[NumVectors];
|
||||||
|
for (uint32_t i=0; i<NumVectors; ++i){
|
||||||
|
inNormals[i].x = static_cast<ai_real>(i);
|
||||||
|
inNormals[i].y = static_cast<ai_real>(i);
|
||||||
|
inNormals[i].z = static_cast<ai_real>(i);
|
||||||
|
}
|
||||||
|
aiVector3D *outNormals = new aiVector3D[NumVectors];
|
||||||
|
GeometryUtils::normalizeVectorArray(inNormals, outNormals, NumVectors);
|
||||||
|
delete[] outNormals;
|
||||||
|
delete[] inNormals;
|
||||||
|
}
|
Loading…
Reference in New Issue