Merge branch 'master' into refactor/KHR_material_specular
commit
e947471549
|
@ -138,7 +138,7 @@ IF (WIN32)
|
||||||
ELSE()
|
ELSE()
|
||||||
OPTION( ASSIMP_BUILD_ZLIB
|
OPTION( ASSIMP_BUILD_ZLIB
|
||||||
"Build your own zlib"
|
"Build your own zlib"
|
||||||
OFF
|
ON
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
|
@ -397,10 +397,6 @@ struct Material {
|
||||||
|
|
||||||
Material(const Material &other) = default;
|
Material(const Material &other) = default;
|
||||||
|
|
||||||
Material(Material &&other) AI_NO_EXCEPT = default;
|
|
||||||
|
|
||||||
Material &operator=(Material &&other) AI_NO_EXCEPT = default;
|
|
||||||
|
|
||||||
virtual ~Material() = default;
|
virtual ~Material() = default;
|
||||||
|
|
||||||
//! Name of the material
|
//! Name of the material
|
||||||
|
|
|
@ -266,8 +266,15 @@ void Discreet3DSImporter::ParseMainChunk() {
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSIMP_3DS_END_CHUNK();
|
ASSIMP_3DS_END_CHUNK();
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wunreachable-code-return"
|
||||||
|
#endif
|
||||||
// recursively continue processing this hierarchy level
|
// recursively continue processing this hierarchy level
|
||||||
return ParseMainChunk();
|
return ParseMainChunk();
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -68,7 +68,7 @@ using namespace D3DS;
|
||||||
class Discreet3DSImporter : public BaseImporter {
|
class Discreet3DSImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
Discreet3DSImporter();
|
Discreet3DSImporter();
|
||||||
~Discreet3DSImporter();
|
~Discreet3DSImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~EmbeddedTexture() = default;
|
~EmbeddedTexture() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_EmbeddedTexture2D;
|
return ResourceType::RT_EmbeddedTexture2D;
|
||||||
|
@ -110,7 +110,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~Texture2DGroup() = default;
|
~Texture2DGroup() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Texture2DGroup;
|
return ResourceType::RT_Texture2DGroup;
|
||||||
|
@ -127,7 +127,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~BaseMaterials() = default;
|
~BaseMaterials() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_BaseMaterials;
|
return ResourceType::RT_BaseMaterials;
|
||||||
|
@ -152,7 +152,7 @@ public:
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
~Object() = default;
|
~Object() override = default;
|
||||||
|
|
||||||
ResourceType getType() const override {
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Object;
|
return ResourceType::RT_Object;
|
||||||
|
|
|
@ -282,11 +282,11 @@ public:
|
||||||
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
||||||
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
|
||||||
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
|
||||||
void Throw_CloseNotFound(const std::string &nodeName);
|
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
|
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
|
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
|
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
||||||
void Throw_ID_NotFound(const std::string &pID) const;
|
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
|
||||||
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
|
||||||
bool XML_SearchNode(const std::string &nodeName);
|
bool XML_SearchNode(const std::string &nodeName);
|
||||||
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
|
||||||
|
|
|
@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
@ -322,21 +321,6 @@ void ASEImporter::BuildAnimations(const std::vector<BaseNode *> &nodes) {
|
||||||
aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
|
aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
|
||||||
nd->mNodeName.Set(me->mName + ".Target");
|
nd->mNodeName.Set(me->mName + ".Target");
|
||||||
|
|
||||||
// If there is no input position channel we will need
|
|
||||||
// to supply the default position from the node's
|
|
||||||
// local transformation matrix.
|
|
||||||
/*TargetAnimationHelper helper;
|
|
||||||
if (me->mAnim.akeyPositions.empty())
|
|
||||||
{
|
|
||||||
aiMatrix4x4& mat = (*i)->mTransform;
|
|
||||||
helper.SetFixedMainAnimationChannel(aiVector3D(
|
|
||||||
mat.a4, mat.b4, mat.c4));
|
|
||||||
}
|
|
||||||
else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
|
|
||||||
helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
|
|
||||||
|
|
||||||
helper.Process(&me->mTargetAnim.akeyPositions);*/
|
|
||||||
|
|
||||||
// Allocate the key array and fill it
|
// Allocate the key array and fill it
|
||||||
nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
|
nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
|
||||||
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
|
nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
|
||||||
|
|
|
@ -304,7 +304,6 @@ void Parser::Parse() {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -734,7 +733,6 @@ void Parser::ParseLV3MapBlock(Texture &map) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
|
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -859,7 +857,6 @@ void Parser::ParseLV1ObjectBlock(ASE::BaseNode &node) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -883,7 +880,6 @@ void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
|
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1189,7 +1185,6 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
|
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
||||||
|
@ -1310,7 +1305,6 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("2", "*MESH");
|
AI_ASE_HANDLE_SECTION("2", "*MESH");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
||||||
|
@ -1344,7 +1338,6 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
|
||||||
|
@ -1414,7 +1407,6 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
|
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshVertexListBlock(
|
void Parser::ParseLV3MeshVertexListBlock(
|
||||||
|
@ -1443,7 +1435,6 @@ void Parser::ParseLV3MeshVertexListBlock(
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
||||||
|
@ -1470,7 +1461,6 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
|
@ -1503,7 +1493,6 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
|
@ -1532,7 +1521,6 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
||||||
|
@ -1567,7 +1555,6 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
|
||||||
|
@ -1595,7 +1582,6 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
|
||||||
|
@ -1623,7 +1609,6 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
||||||
|
@ -1681,7 +1666,6 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
|
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ For details, see http://sourceforge.net/projects/libb64
|
||||||
|
|
||||||
#include "cencode.h" // changed from <B64/cencode.h>
|
#include "cencode.h" // changed from <B64/cencode.h>
|
||||||
|
|
||||||
const int CHARS_PER_LINE = 72;
|
static const int CHARS_PER_LINE = 72;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
|
|
@ -96,7 +96,8 @@ struct CustomDataTypeDescription {
|
||||||
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
|
||||||
* use a special readfunction for that cases
|
* use a special readfunction for that cases
|
||||||
*/
|
*/
|
||||||
std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
|
||||||
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
|
||||||
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
|
||||||
|
|
|
@ -1855,7 +1855,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||||
default:
|
default:
|
||||||
// LineStrip is not supported due to expected index unmangling
|
// LineStrip is not supported due to expected index unmangling
|
||||||
throw DeadlyImportError("Unsupported primitive type.");
|
throw DeadlyImportError("Unsupported primitive type.");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the face size to later reconstruct the face from
|
// store the face size to later reconstruct the face from
|
||||||
|
|
|
@ -139,6 +139,7 @@ size_t Offset(const char* begin, const char* cursor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AI_WONT_RETURN void TokenizeError(const std::string& message, const char* begin, const char* cursor) AI_WONT_RETURN_SUFFIX;
|
||||||
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
|
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
|
||||||
TokenizeError(message, Offset(begin, cursor));
|
TokenizeError(message, Offset(begin, cursor));
|
||||||
}
|
}
|
||||||
|
@ -341,8 +342,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, bool const is64bits)
|
bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const char *input, const char *&cursor, const char *end, bool const is64bits) {
|
||||||
{
|
|
||||||
// the first word contains the offset at which this block ends
|
// the first word contains the offset at which this block ends
|
||||||
const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
|
|
||||||
// XXX this is vulnerable to stack overflowing ..
|
// XXX this is vulnerable to stack overflowing ..
|
||||||
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
||||||
ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits);
|
ReadScope(output_tokens, token_allocator, input, cursor, input + end_offset - sentinel_block_length, is64bits);
|
||||||
}
|
}
|
||||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
||||||
|
|
||||||
|
@ -431,8 +431,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
|
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
|
||||||
void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, StackAllocator &token_allocator) {
|
||||||
{
|
|
||||||
ai_assert(input);
|
ai_assert(input);
|
||||||
ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
|
ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
|
||||||
|
|
||||||
|
@ -465,7 +464,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (cursor < end ) {
|
while (cursor < end ) {
|
||||||
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
if (!ReadScope(output_tokens, token_allocator, input, cursor, input + length, is64bits)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ void FBXConverter::ConvertRootNode() {
|
||||||
mSceneOut->mRootNode->mName.Set(unique_name);
|
mSceneOut->mRootNode->mName.Set(unique_name);
|
||||||
|
|
||||||
// root has ID 0
|
// root has ID 0
|
||||||
ConvertNodes(0L, mSceneOut->mRootNode, mSceneOut->mRootNode, aiMatrix4x4());
|
ConvertNodes(0L, mSceneOut->mRootNode, mSceneOut->mRootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getAncestorBaseName(const aiNode *node) {
|
static std::string getAncestorBaseName(const aiNode *node) {
|
||||||
|
@ -196,7 +196,7 @@ struct FBXConverter::PotentialNode {
|
||||||
/// todo: get bone from stack
|
/// todo: get bone from stack
|
||||||
/// todo: make map of aiBone* to aiNode*
|
/// todo: make map of aiBone* to aiNode*
|
||||||
/// then update convert clusters to the new format
|
/// then update convert clusters to the new format
|
||||||
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &globalTransform) {
|
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
|
||||||
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
|
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
|
||||||
|
|
||||||
std::vector<PotentialNode> nodes;
|
std::vector<PotentialNode> nodes;
|
||||||
|
@ -290,15 +290,14 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node,
|
||||||
}
|
}
|
||||||
|
|
||||||
// recursion call - child nodes
|
// recursion call - child nodes
|
||||||
aiMatrix4x4 newGlobalMatrix = globalTransform * nodes_chain.front().mNode->mTransformation;
|
ConvertNodes(model->ID(), last_parent, root_node);
|
||||||
ConvertNodes(model->ID(), last_parent, root_node, newGlobalMatrix);
|
|
||||||
|
|
||||||
if (doc.Settings().readLights) {
|
if (doc.Settings().readLights) {
|
||||||
ConvertLights(*model, node_name);
|
ConvertLights(*model, node_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc.Settings().readCameras) {
|
if (doc.Settings().readCameras) {
|
||||||
ConvertCameras(*model, node_name, newGlobalMatrix);
|
ConvertCameras(*model, node_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes.push_back(std::move(nodes_chain.front()));
|
nodes.push_back(std::move(nodes_chain.front()));
|
||||||
|
@ -328,14 +327,12 @@ void FBXConverter::ConvertLights(const Model &model, const std::string &orig_nam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXConverter::ConvertCameras(const Model &model,
|
void FBXConverter::ConvertCameras(const Model &model, const std::string &orig_name) {
|
||||||
const std::string &orig_name,
|
|
||||||
const aiMatrix4x4 &transform) {
|
|
||||||
const std::vector<const NodeAttribute *> &node_attrs = model.GetAttributes();
|
const std::vector<const NodeAttribute *> &node_attrs = model.GetAttributes();
|
||||||
for (const NodeAttribute *attr : node_attrs) {
|
for (const NodeAttribute *attr : node_attrs) {
|
||||||
const Camera *const cam = dynamic_cast<const Camera *>(attr);
|
const Camera *const cam = dynamic_cast<const Camera *>(attr);
|
||||||
if (cam) {
|
if (cam) {
|
||||||
ConvertCamera(*cam, orig_name, transform);
|
ConvertCamera(*cam, orig_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,9 +413,7 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXConverter::ConvertCamera(const Camera &cam,
|
void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name) {
|
||||||
const std::string &orig_name,
|
|
||||||
aiMatrix4x4 transform) {
|
|
||||||
cameras.push_back(new aiCamera());
|
cameras.push_back(new aiCamera());
|
||||||
aiCamera *const out_camera = cameras.back();
|
aiCamera *const out_camera = cameras.back();
|
||||||
|
|
||||||
|
@ -426,16 +421,11 @@ void FBXConverter::ConvertCamera(const Camera &cam,
|
||||||
|
|
||||||
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
||||||
|
|
||||||
aiVector3D pos = cam.Position();
|
// NOTE: Camera mPosition, mLookAt and mUp must be set to default here.
|
||||||
out_camera->mLookAt = cam.InterestPosition();
|
// All transformations to the camera will be handled by its node in the scenegraph.
|
||||||
out_camera->mUp = pos + cam.UpVector();
|
|
||||||
transform.Inverse();
|
|
||||||
pos *= transform;
|
|
||||||
out_camera->mLookAt *= transform;
|
|
||||||
out_camera->mUp *= transform;
|
|
||||||
out_camera->mLookAt -= pos;
|
|
||||||
out_camera->mUp -= pos;
|
|
||||||
out_camera->mPosition = aiVector3D(0.0f);
|
out_camera->mPosition = aiVector3D(0.0f);
|
||||||
|
out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
|
||||||
|
out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
|
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
|
||||||
|
|
||||||
|
|
|
@ -134,22 +134,19 @@ private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// collect and assign child nodes
|
// collect and assign child nodes
|
||||||
void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node,
|
void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
|
||||||
const aiMatrix4x4 &globalTransform);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertLights(const Model& model, const std::string &orig_name );
|
void ConvertLights(const Model& model, const std::string &orig_name );
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertCameras(const Model& model, const std::string &orig_name,
|
void ConvertCameras(const Model& model, const std::string &orig_name );
|
||||||
const aiMatrix4x4 &transform);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertLight( const Light& light, const std::string &orig_name );
|
void ConvertLight( const Light& light, const std::string &orig_name );
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ConvertCamera(const Camera& cam, const std::string &orig_name,
|
void ConvertCamera( const Camera& cam, const std::string &orig_name );
|
||||||
aiMatrix4x4 transform);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void GetUniqueName( const std::string &name, std::string& uniqueName );
|
void GetUniqueName( const std::string &name, std::string& uniqueName );
|
||||||
|
|
|
@ -243,7 +243,7 @@ FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Document::Document(const Parser& parser, const ImportSettings& settings) :
|
Document::Document(Parser& parser, const ImportSettings& settings) :
|
||||||
settings(settings), parser(parser) {
|
settings(settings), parser(parser) {
|
||||||
ASSIMP_LOG_DEBUG("Creating FBX Document");
|
ASSIMP_LOG_DEBUG("Creating FBX Document");
|
||||||
|
|
||||||
|
@ -265,13 +265,17 @@ Document::Document(const Parser& parser, const ImportSettings& settings) :
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Document::~Document() {
|
Document::~Document()
|
||||||
for(ObjectMap::value_type& v : objects) {
|
{
|
||||||
delete v.second;
|
// The document does not own the memory for the following objects, but we need to call their d'tor
|
||||||
|
// so they can properly free memory like string members:
|
||||||
|
|
||||||
|
for (ObjectMap::value_type &v : objects) {
|
||||||
|
delete_LazyObject(v.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ConnectionMap::value_type& v : src_connections) {
|
for (ConnectionMap::value_type &v : src_connections) {
|
||||||
delete v.second;
|
delete_Connection(v.second);
|
||||||
}
|
}
|
||||||
// |dest_connections| contain the same Connection objects as the |src_connections|
|
// |dest_connections| contain the same Connection objects as the |src_connections|
|
||||||
}
|
}
|
||||||
|
@ -356,9 +360,11 @@ void Document::ReadObjects() {
|
||||||
DOMError("no Objects dictionary found");
|
DOMError("no Objects dictionary found");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
|
|
||||||
// add a dummy entry to represent the Model::RootNode object (id 0),
|
// add a dummy entry to represent the Model::RootNode object (id 0),
|
||||||
// which is only indirectly defined in the input file
|
// which is only indirectly defined in the input file
|
||||||
objects[0] = new LazyObject(0L, *eobjects, *this);
|
objects[0] = new_LazyObject(0L, *eobjects, *this);
|
||||||
|
|
||||||
const Scope& sobjects = *eobjects->Compound();
|
const Scope& sobjects = *eobjects->Compound();
|
||||||
for(const ElementMap::value_type& el : sobjects.Elements()) {
|
for(const ElementMap::value_type& el : sobjects.Elements()) {
|
||||||
|
@ -387,7 +393,7 @@ void Document::ReadObjects() {
|
||||||
delete foundObject->second;
|
delete foundObject->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
objects[id] = new LazyObject(id, *el.second, *this);
|
objects[id] = new_LazyObject(id, *el.second, *this);
|
||||||
|
|
||||||
// grab all animation stacks upfront since there is no listing of them
|
// grab all animation stacks upfront since there is no listing of them
|
||||||
if(!strcmp(el.first.c_str(),"AnimationStack")) {
|
if(!strcmp(el.first.c_str(),"AnimationStack")) {
|
||||||
|
@ -454,8 +460,10 @@ void Document::ReadPropertyTemplates() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Document::ReadConnections() {
|
void Document::ReadConnections()
|
||||||
const Scope& sc = parser.GetRootScope();
|
{
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
|
const Scope &sc = parser.GetRootScope();
|
||||||
// read property templates from "Definitions" section
|
// read property templates from "Definitions" section
|
||||||
const Element* const econns = sc["Connections"];
|
const Element* const econns = sc["Connections"];
|
||||||
if(!econns || !econns->Compound()) {
|
if(!econns || !econns->Compound()) {
|
||||||
|
@ -494,7 +502,7 @@ void Document::ReadConnections() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add new connection
|
// add new connection
|
||||||
const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this);
|
const Connection* const c = new_Connection(insertionOrder++,src,dest,prop,*this);
|
||||||
src_connections.insert(ConnectionMap::value_type(src,c));
|
src_connections.insert(ConnectionMap::value_type(src,c));
|
||||||
dest_connections.insert(ConnectionMap::value_type(dest,c));
|
dest_connections.insert(ConnectionMap::value_type(dest,c));
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,10 @@ class BlendShape;
|
||||||
class Skin;
|
class Skin;
|
||||||
class Cluster;
|
class Cluster;
|
||||||
|
|
||||||
|
#define new_LazyObject new (allocator.Allocate(sizeof(LazyObject))) LazyObject
|
||||||
|
#define new_Connection new (allocator.Allocate(sizeof(Connection))) Connection
|
||||||
|
#define delete_LazyObject(_p) (_p)->~LazyObject()
|
||||||
|
#define delete_Connection(_p) (_p)->~Connection()
|
||||||
|
|
||||||
/** Represents a delay-parsed FBX objects. Many objects in the scene
|
/** Represents a delay-parsed FBX objects. Many objects in the scene
|
||||||
* are not needed by assimp, so it makes no sense to parse them
|
* are not needed by assimp, so it makes no sense to parse them
|
||||||
|
@ -1073,7 +1077,7 @@ private:
|
||||||
/** DOM root for a FBX file */
|
/** DOM root for a FBX file */
|
||||||
class Document {
|
class Document {
|
||||||
public:
|
public:
|
||||||
Document(const Parser& parser, const ImportSettings& settings);
|
Document(Parser& parser, const ImportSettings& settings);
|
||||||
|
|
||||||
~Document();
|
~Document();
|
||||||
|
|
||||||
|
@ -1157,7 +1161,7 @@ private:
|
||||||
const ImportSettings& settings;
|
const ImportSettings& settings;
|
||||||
|
|
||||||
ObjectMap objects;
|
ObjectMap objects;
|
||||||
const Parser& parser;
|
Parser& parser;
|
||||||
|
|
||||||
PropertyTemplateMap templates;
|
PropertyTemplateMap templates;
|
||||||
ConnectionMap src_connections;
|
ConnectionMap src_connections;
|
||||||
|
|
|
@ -152,19 +152,19 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
// broad-phase tokenized pass in which we identify the core
|
// broad-phase tokenized pass in which we identify the core
|
||||||
// syntax elements of FBX (brackets, commas, key:value mappings)
|
// syntax elements of FBX (brackets, commas, key:value mappings)
|
||||||
TokenList tokens;
|
TokenList tokens;
|
||||||
try {
|
Assimp::StackAllocator tempAllocator;
|
||||||
|
try {
|
||||||
bool is_binary = false;
|
bool is_binary = false;
|
||||||
if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
|
if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
|
||||||
is_binary = true;
|
is_binary = true;
|
||||||
TokenizeBinary(tokens, begin, contents.size());
|
TokenizeBinary(tokens, begin, contents.size(), tempAllocator);
|
||||||
} else {
|
} else {
|
||||||
Tokenize(tokens, begin);
|
Tokenize(tokens, begin, tempAllocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use this information to construct a very rudimentary
|
// use this information to construct a very rudimentary
|
||||||
// parse-tree representing the FBX scope structure
|
// parse-tree representing the FBX scope structure
|
||||||
Parser parser(tokens, is_binary);
|
Parser parser(tokens, tempAllocator, is_binary);
|
||||||
|
|
||||||
// take the raw parse-tree and convert it to a FBX DOM
|
// take the raw parse-tree and convert it to a FBX DOM
|
||||||
Document doc(parser, mSettings);
|
Document doc(parser, mSettings);
|
||||||
|
@ -183,10 +183,12 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
// assimp universal format (M)
|
// assimp universal format (M)
|
||||||
SetFileScale(size_relative_to_cm * 0.01f);
|
SetFileScale(size_relative_to_cm * 0.01f);
|
||||||
|
|
||||||
std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
|
// This collection does not own the memory for the tokens, but we need to call their d'tor
|
||||||
} catch (std::exception &) {
|
std::for_each(tokens.begin(), tokens.end(), Util::destructor_fun<Token>());
|
||||||
std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
|
|
||||||
throw;
|
} catch (std::exception &) {
|
||||||
|
std::for_each(tokens.begin(), tokens.end(), Util::destructor_fun<Token>());
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,20 +138,6 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Material::~Material() = default;
|
Material::~Material() = default;
|
||||||
|
|
||||||
aiVector2D uvTrans;
|
|
||||||
aiVector2D uvScaling;
|
|
||||||
ai_real uvRotation;
|
|
||||||
|
|
||||||
std::string type;
|
|
||||||
std::string relativeFileName;
|
|
||||||
std::string fileName;
|
|
||||||
std::string alphaSource;
|
|
||||||
std::shared_ptr<const PropertyTable> props;
|
|
||||||
|
|
||||||
unsigned int crop[4]{};
|
|
||||||
|
|
||||||
const Video* media;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
||||||
Object(id,element,name),
|
Object(id,element,name),
|
||||||
|
|
|
@ -88,6 +88,7 @@ namespace {
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
AI_WONT_RETURN void ParseError(const std::string& message, TokenPtr token) AI_WONT_RETURN_SUFFIX;
|
||||||
void ParseError(const std::string& message, TokenPtr token)
|
void ParseError(const std::string& message, TokenPtr token)
|
||||||
{
|
{
|
||||||
if(token) {
|
if(token) {
|
||||||
|
@ -115,8 +116,11 @@ namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Element::Element(const Token& key_token, Parser& parser) : key_token(key_token) {
|
Element::Element(const Token& key_token, Parser& parser) :
|
||||||
|
key_token(key_token), compound(nullptr)
|
||||||
|
{
|
||||||
TokenPtr n = nullptr;
|
TokenPtr n = nullptr;
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
do {
|
do {
|
||||||
n = parser.AdvanceToNextToken();
|
n = parser.AdvanceToNextToken();
|
||||||
if(!n) {
|
if(!n) {
|
||||||
|
@ -145,7 +149,7 @@ Element::Element(const Token& key_token, Parser& parser) : key_token(key_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n->Type() == TokenType_OPEN_BRACKET) {
|
if (n->Type() == TokenType_OPEN_BRACKET) {
|
||||||
compound.reset(new Scope(parser));
|
compound = new_Scope(parser);
|
||||||
|
|
||||||
// current token should be a TOK_CLOSE_BRACKET
|
// current token should be a TOK_CLOSE_BRACKET
|
||||||
n = parser.CurrentToken();
|
n = parser.CurrentToken();
|
||||||
|
@ -163,6 +167,15 @@ Element::Element(const Token& key_token, Parser& parser) : key_token(key_token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Element::~Element()
|
||||||
|
{
|
||||||
|
if (compound) {
|
||||||
|
delete_Scope(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no need to delete tokens, they are owned by the parser
|
||||||
|
}
|
||||||
|
|
||||||
Scope::Scope(Parser& parser,bool topLevel)
|
Scope::Scope(Parser& parser,bool topLevel)
|
||||||
{
|
{
|
||||||
if(!topLevel) {
|
if(!topLevel) {
|
||||||
|
@ -172,6 +185,7 @@ Scope::Scope(Parser& parser,bool topLevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackAllocator &allocator = parser.GetAllocator();
|
||||||
TokenPtr n = parser.AdvanceToNextToken();
|
TokenPtr n = parser.AdvanceToNextToken();
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
ParseError("unexpected end of file");
|
ParseError("unexpected end of file");
|
||||||
|
@ -188,36 +202,45 @@ Scope::Scope(Parser& parser,bool topLevel)
|
||||||
ParseError("unexpected content: empty string.");
|
ParseError("unexpected content: empty string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.insert(ElementMap::value_type(str,new_Element(*n,parser)));
|
auto *element = new_Element(*n, parser);
|
||||||
|
|
||||||
// Element() should stop at the next Key token (or right after a Close token)
|
// Element() should stop at the next Key token (or right after a Close token)
|
||||||
n = parser.CurrentToken();
|
n = parser.CurrentToken();
|
||||||
if (n == nullptr) {
|
if (n == nullptr) {
|
||||||
if (topLevel) {
|
if (topLevel) {
|
||||||
|
elements.insert(ElementMap::value_type(str, element));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
delete element;
|
||||||
ParseError("unexpected end of file",parser.LastToken());
|
ParseError("unexpected end of file",parser.LastToken());
|
||||||
|
} else {
|
||||||
|
elements.insert(ElementMap::value_type(str, element));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Scope::~Scope() {
|
Scope::~Scope()
|
||||||
for(ElementMap::value_type& v : elements) {
|
{
|
||||||
delete v.second;
|
// This collection does not own the memory for the elements, but we need to call their d'tor:
|
||||||
|
|
||||||
|
for (ElementMap::value_type &v : elements) {
|
||||||
|
delete_Element(v.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Parser::Parser (const TokenList& tokens, bool is_binary)
|
Parser::Parser(const TokenList &tokens, StackAllocator &allocator, bool is_binary) :
|
||||||
: tokens(tokens)
|
tokens(tokens), allocator(allocator), last(), current(), cursor(tokens.begin()), is_binary(is_binary)
|
||||||
, last()
|
|
||||||
, current()
|
|
||||||
, cursor(tokens.begin())
|
|
||||||
, is_binary(is_binary)
|
|
||||||
{
|
{
|
||||||
ASSIMP_LOG_DEBUG("Parsing FBX tokens");
|
ASSIMP_LOG_DEBUG("Parsing FBX tokens");
|
||||||
root.reset(new Scope(*this,true));
|
root = new_Scope(*this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
Parser::~Parser()
|
||||||
|
{
|
||||||
|
delete_Scope(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/LogAux.h>
|
#include <assimp/LogAux.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
|
|
||||||
|
#include "Common/StackAllocator.h"
|
||||||
#include "FBXCompileConfig.h"
|
#include "FBXCompileConfig.h"
|
||||||
#include "FBXTokenizer.h"
|
#include "FBXTokenizer.h"
|
||||||
|
|
||||||
|
@ -63,14 +64,14 @@ class Parser;
|
||||||
class Element;
|
class Element;
|
||||||
|
|
||||||
// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
|
// XXX should use C++11's unique_ptr - but assimp's need to keep working with 03
|
||||||
typedef std::vector< Scope* > ScopeList;
|
using ScopeList = std::vector<Scope*>;
|
||||||
typedef std::fbx_unordered_multimap< std::string, Element* > ElementMap;
|
using ElementMap = std::fbx_unordered_multimap< std::string, Element*>;
|
||||||
|
using ElementCollection = std::pair<ElementMap::const_iterator,ElementMap::const_iterator>;
|
||||||
typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> ElementCollection;
|
|
||||||
|
|
||||||
# define new_Scope new Scope
|
|
||||||
# define new_Element new Element
|
|
||||||
|
|
||||||
|
#define new_Scope new (allocator.Allocate(sizeof(Scope))) Scope
|
||||||
|
#define new_Element new (allocator.Allocate(sizeof(Element))) Element
|
||||||
|
#define delete_Scope(_p) (_p)->~Scope()
|
||||||
|
#define delete_Element(_p) (_p)->~Element()
|
||||||
|
|
||||||
/** FBX data entity that consists of a key:value tuple.
|
/** FBX data entity that consists of a key:value tuple.
|
||||||
*
|
*
|
||||||
|
@ -82,15 +83,16 @@ typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> Element
|
||||||
* @endverbatim
|
* @endverbatim
|
||||||
*
|
*
|
||||||
* As can be seen in this sample, elements can contain nested #Scope
|
* As can be seen in this sample, elements can contain nested #Scope
|
||||||
* as their trailing member. **/
|
* as their trailing member.
|
||||||
|
**/
|
||||||
class Element
|
class Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Element(const Token& key_token, Parser& parser);
|
Element(const Token& key_token, Parser& parser);
|
||||||
~Element() = default;
|
~Element();
|
||||||
|
|
||||||
const Scope* Compound() const {
|
const Scope* Compound() const {
|
||||||
return compound.get();
|
return compound;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token& KeyToken() const {
|
const Token& KeyToken() const {
|
||||||
|
@ -104,7 +106,7 @@ public:
|
||||||
private:
|
private:
|
||||||
const Token& key_token;
|
const Token& key_token;
|
||||||
TokenList tokens;
|
TokenList tokens;
|
||||||
std::unique_ptr<Scope> compound;
|
Scope* compound;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** FBX data entity that consists of a 'scope', a collection
|
/** FBX data entity that consists of a 'scope', a collection
|
||||||
|
@ -159,8 +161,8 @@ class Parser
|
||||||
public:
|
public:
|
||||||
/** Parse given a token list. Does not take ownership of the tokens -
|
/** Parse given a token list. Does not take ownership of the tokens -
|
||||||
* the objects must persist during the entire parser lifetime */
|
* the objects must persist during the entire parser lifetime */
|
||||||
Parser (const TokenList& tokens,bool is_binary);
|
Parser(const TokenList &tokens, StackAllocator &allocator, bool is_binary);
|
||||||
~Parser() = default;
|
~Parser();
|
||||||
|
|
||||||
const Scope& GetRootScope() const {
|
const Scope& GetRootScope() const {
|
||||||
return *root;
|
return *root;
|
||||||
|
@ -170,6 +172,10 @@ public:
|
||||||
return is_binary;
|
return is_binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StackAllocator &GetAllocator() {
|
||||||
|
return allocator;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Scope;
|
friend class Scope;
|
||||||
friend class Element;
|
friend class Element;
|
||||||
|
@ -180,10 +186,10 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TokenList& tokens;
|
const TokenList& tokens;
|
||||||
|
StackAllocator &allocator;
|
||||||
TokenPtr last, current;
|
TokenPtr last, current;
|
||||||
TokenList::const_iterator cursor;
|
TokenList::const_iterator cursor;
|
||||||
std::unique_ptr<Scope> root;
|
Scope *root;
|
||||||
|
|
||||||
const bool is_binary;
|
const bool is_binary;
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,7 +94,8 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line,
|
||||||
|
|
||||||
// process a potential data token up to 'cur', adding it to 'output_tokens'.
|
// process a potential data token up to 'cur', adding it to 'output_tokens'.
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*& end,
|
void ProcessDataToken(TokenList &output_tokens, StackAllocator &token_allocator,
|
||||||
|
const char*& start, const char*& end,
|
||||||
unsigned int line,
|
unsigned int line,
|
||||||
unsigned int column,
|
unsigned int column,
|
||||||
TokenType type = TokenType_DATA,
|
TokenType type = TokenType_DATA,
|
||||||
|
@ -131,8 +132,7 @@ void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Tokenize(TokenList& output_tokens, const char* input)
|
void Tokenize(TokenList &output_tokens, const char *input, StackAllocator &token_allocator) {
|
||||||
{
|
|
||||||
ai_assert(input);
|
ai_assert(input);
|
||||||
ASSIMP_LOG_DEBUG("Tokenizing ASCII FBX file");
|
ASSIMP_LOG_DEBUG("Tokenizing ASCII FBX file");
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
||||||
in_double_quotes = false;
|
in_double_quotes = false;
|
||||||
token_end = cur;
|
token_end = cur;
|
||||||
|
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
pending_data_token = false;
|
pending_data_token = false;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -181,30 +181,30 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case ';':
|
case ';':
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
comment = true;
|
comment = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end, line, column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column));
|
output_tokens.push_back(new_Token(cur,cur+1,TokenType_OPEN_BRACKET,line,column));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '}':
|
case '}':
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column);
|
||||||
output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column));
|
output_tokens.push_back(new_Token(cur,cur+1,TokenType_CLOSE_BRACKET,line,column));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
if (pending_data_token) {
|
if (pending_data_token) {
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_DATA,true);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column, TokenType_DATA, true);
|
||||||
}
|
}
|
||||||
output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column));
|
output_tokens.push_back(new_Token(cur,cur+1,TokenType_COMMA,line,column));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case ':':
|
case ':':
|
||||||
if (pending_data_token) {
|
if (pending_data_token) {
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column,TokenType_KEY,true);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column, TokenType_KEY, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TokenizeError("unexpected colon", line, column);
|
TokenizeError("unexpected colon", line, column);
|
||||||
|
@ -226,7 +226,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessDataToken(output_tokens,token_begin,token_end,line,column,type);
|
ProcessDataToken(output_tokens, token_allocator, token_begin, token_end, line, column, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_data_token = false;
|
pending_data_token = false;
|
||||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_FBX_TOKENIZER_H
|
#define INCLUDED_AI_FBX_TOKENIZER_H
|
||||||
|
|
||||||
#include "FBXCompileConfig.h"
|
#include "FBXCompileConfig.h"
|
||||||
|
#include "Common/StackAllocator.h"
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
#include <assimp/defs.h>
|
#include <assimp/defs.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -157,7 +158,8 @@ private:
|
||||||
typedef const Token* TokenPtr;
|
typedef const Token* TokenPtr;
|
||||||
typedef std::vector< TokenPtr > TokenList;
|
typedef std::vector< TokenPtr > TokenList;
|
||||||
|
|
||||||
#define new_Token new Token
|
#define new_Token new (token_allocator.Allocate(sizeof(Token))) Token
|
||||||
|
#define delete_Token(_p) (_p)->~Token()
|
||||||
|
|
||||||
|
|
||||||
/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens.
|
/** Main FBX tokenizer function. Transform input buffer into a list of preprocessed tokens.
|
||||||
|
@ -167,7 +169,7 @@ typedef std::vector< TokenPtr > TokenList;
|
||||||
* @param output_tokens Receives a list of all tokens in the input data.
|
* @param output_tokens Receives a list of all tokens in the input data.
|
||||||
* @param input_buffer Textual input buffer to be processed, 0-terminated.
|
* @param input_buffer Textual input buffer to be processed, 0-terminated.
|
||||||
* @throw DeadlyImportError if something goes wrong */
|
* @throw DeadlyImportError if something goes wrong */
|
||||||
void Tokenize(TokenList& output_tokens, const char* input);
|
void Tokenize(TokenList &output_tokens, const char *input, StackAllocator &tokenAllocator);
|
||||||
|
|
||||||
|
|
||||||
/** Tokenizer function for binary FBX files.
|
/** Tokenizer function for binary FBX files.
|
||||||
|
@ -178,7 +180,7 @@ void Tokenize(TokenList& output_tokens, const char* input);
|
||||||
* @param input_buffer Binary input buffer to be processed.
|
* @param input_buffer Binary input buffer to be processed.
|
||||||
* @param length Length of input buffer, in bytes. There is no 0-terminal.
|
* @param length Length of input buffer, in bytes. There is no 0-terminal.
|
||||||
* @throw DeadlyImportError if something goes wrong */
|
* @throw DeadlyImportError if something goes wrong */
|
||||||
void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length);
|
void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, StackAllocator &tokenAllocator);
|
||||||
|
|
||||||
|
|
||||||
} // ! FBX
|
} // ! FBX
|
||||||
|
|
|
@ -66,6 +66,17 @@ struct delete_fun
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** helper for std::for_each to call the destructor on all items in a container without freeing their heap*/
|
||||||
|
template <typename T>
|
||||||
|
struct destructor_fun {
|
||||||
|
void operator()(const volatile T* del) {
|
||||||
|
if (del) {
|
||||||
|
del->~T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Get a string representation for a #TokenType. */
|
/** Get a string representation for a #TokenType. */
|
||||||
const char* TokenTypeString(TokenType t);
|
const char* TokenTypeString(TokenType t);
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a HMP4 file
|
/** Import a HMP4 file
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HMP4();
|
AI_WONT_RETURN void InternReadFile_HMP4() AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a HMP5 file
|
/** Import a HMP5 file
|
||||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "AssetLib/IFC/IFCUtil.h"
|
#include "AssetLib/IFC/IFCUtil.h"
|
||||||
#include "Common/PolyTools.h"
|
#include "Common/PolyTools.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -235,7 +236,7 @@ IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const {
|
||||||
struct CompareVector {
|
struct CompareVector {
|
||||||
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
|
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
|
||||||
IfcVector3 d = a - b;
|
IfcVector3 d = a - b;
|
||||||
IfcFloat eps = ai_epsilon;
|
constexpr IfcFloat eps = ai_epsilon;
|
||||||
return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
|
return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,7 +65,6 @@ void LWOImporter::LoadLWOBFile()
|
||||||
if (mFileBuffer + head.length > end)
|
if (mFileBuffer + head.length > end)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError("LWOB: Invalid chunk length");
|
throw DeadlyImportError("LWOB: Invalid chunk length");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint8_t* const next = mFileBuffer+head.length;
|
uint8_t* const next = mFileBuffer+head.length;
|
||||||
switch (head.type)
|
switch (head.type)
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -51,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "AssetLib/LWO/LWOLoader.h"
|
#include "AssetLib/LWO/LWOLoader.h"
|
||||||
#include "PostProcessing/ConvertToLHProcess.h"
|
#include "PostProcessing/ConvertToLHProcess.h"
|
||||||
#include "PostProcessing/ProcessHelper.h"
|
#include "PostProcessing/ProcessHelper.h"
|
||||||
|
#include "Geometry/GeometryUtils.h"
|
||||||
|
|
||||||
#include <assimp/ByteSwapper.h>
|
#include <assimp/ByteSwapper.h>
|
||||||
#include <assimp/SGSpatialSort.h>
|
#include <assimp/SGSpatialSort.h>
|
||||||
|
@ -528,7 +527,6 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
|
||||||
continue;
|
continue;
|
||||||
vNormals += v;
|
vNormals += v;
|
||||||
}
|
}
|
||||||
mesh->mNormals[idx] = vNormals.Normalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,7 +547,6 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
|
||||||
const aiVector3D &v = faceNormals[*a];
|
const aiVector3D &v = faceNormals[*a];
|
||||||
vNormals += v;
|
vNormals += v;
|
||||||
}
|
}
|
||||||
vNormals.Normalize();
|
|
||||||
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
|
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
|
||||||
mesh->mNormals[*a] = vNormals;
|
mesh->mNormals[*a] = vNormals;
|
||||||
vertexDone[*a] = true;
|
vertexDone[*a] = true;
|
||||||
|
@ -557,6 +554,7 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
GeometryUtils::normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1486,7 +1484,6 @@ void LWOImporter::LoadLWO2File() {
|
||||||
|
|
||||||
if (mFileBuffer + head.length > end) {
|
if (mFileBuffer + head.length > end) {
|
||||||
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
uint8_t *const next = mFileBuffer + head.length;
|
uint8_t *const next = mFileBuffer + head.length;
|
||||||
mFileBuffer += bufOffset;
|
mFileBuffer += bufOffset;
|
||||||
|
|
|
@ -365,9 +365,7 @@ public:
|
||||||
static void ReportWarning (const char* warn, unsigned int line);
|
static void ReportWarning (const char* warn, unsigned int line);
|
||||||
|
|
||||||
|
|
||||||
void ReportError (const char* error) {
|
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
|
||||||
return ReportError(error, lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReportWarning (const char* warn) {
|
void ReportWarning (const char* warn) {
|
||||||
return ReportWarning(warn, lineNumber);
|
return ReportWarning(warn, lineNumber);
|
||||||
|
@ -404,6 +402,9 @@ private:
|
||||||
unsigned int lineNumber;
|
unsigned int lineNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void MD5Parser::ReportError(const char* error) {
|
||||||
|
ReportError(error, lineNumber);
|
||||||
|
}
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
|
||||||
++lineNumber;
|
++lineNumber;
|
||||||
|
|
|
@ -139,7 +139,7 @@ protected:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
/** Import a CS:S/HL2 MDL file (not fully implemented)
|
||||||
*/
|
*/
|
||||||
void InternReadFile_HL2( );
|
AI_WONT_RETURN void InternReadFile_HL2( ) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Check whether a given position is inside the valid range
|
/** Check whether a given position is inside the valid range
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <assimp/types.h>
|
||||||
#include "MMDCpp14.h"
|
#include "MMDCpp14.h"
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
|
@ -730,7 +731,7 @@ namespace pmx
|
||||||
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
std::unique_ptr<PmxAncherRigidBody []> anchers;
|
||||||
int pin_vertex_count;
|
int pin_vertex_count;
|
||||||
std::unique_ptr<int []> pin_vertices;
|
std::unique_ptr<int []> pin_vertices;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
AI_WONT_RETURN void Read(std::istream *stream, PmxSetting *setting) AI_WONT_RETURN_SUFFIX;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PmxModel
|
class PmxModel
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2023, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@ ObjFileImporter::ObjFileImporter() :
|
||||||
// Destructor.
|
// Destructor.
|
||||||
ObjFileImporter::~ObjFileImporter() {
|
ObjFileImporter::~ObjFileImporter() {
|
||||||
delete m_pRootObject;
|
delete m_pRootObject;
|
||||||
m_pRootObject = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -270,7 +269,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
|
||||||
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
|
||||||
unsigned int meshId = pObject->m_Meshes[i];
|
unsigned int meshId = pObject->m_Meshes[i];
|
||||||
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
aiMesh *pMesh = createTopology(pModel, pObject, meshId);
|
||||||
if (pMesh) {
|
if (pMesh != nullptr) {
|
||||||
if (pMesh->mNumFaces > 0) {
|
if (pMesh->mNumFaces > 0) {
|
||||||
MeshArray.push_back(pMesh);
|
MeshArray.push_back(pMesh);
|
||||||
} else {
|
} else {
|
||||||
|
@ -324,14 +323,13 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<aiMesh> pMesh(new aiMesh);
|
aiMesh *pMesh = new aiMesh;
|
||||||
if (!pObjMesh->m_name.empty()) {
|
if (!pObjMesh->m_name.empty()) {
|
||||||
pMesh->mName.Set(pObjMesh->m_name);
|
pMesh->mName.Set(pObjMesh->m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||||
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
const ObjFile::Face *inp = pObjMesh->m_Faces[index];
|
||||||
//ai_assert(nullptr != inp);
|
|
||||||
|
|
||||||
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->mPrimitiveType == aiPrimitiveType_LINE) {
|
||||||
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
|
||||||
|
@ -387,9 +385,9 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create mesh vertices
|
// Create mesh vertices
|
||||||
createVertexArray(pModel, pData, meshIndex, pMesh.get(), uiIdxCount);
|
createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
|
||||||
|
|
||||||
return pMesh.release();
|
return pMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -236,7 +236,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
|
||||||
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
||||||
insideCstype = name == "cstype";
|
insideCstype = name == "cstype";
|
||||||
goto pf_skip_line;
|
goto pf_skip_line;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
pf_skip_line:
|
pf_skip_line:
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Assimp {
|
||||||
namespace Ogre {
|
namespace Ogre {
|
||||||
|
|
||||||
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) AI_WONT_RETURN_SUFFIX;
|
||||||
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
|
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
|
||||||
if (!error.empty()) {
|
if (!error.empty()) {
|
||||||
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
|
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
|
||||||
|
@ -128,7 +128,6 @@ bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mesh XML constants
|
// Mesh XML constants
|
||||||
|
|
|
@ -460,14 +460,12 @@ void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No current node for name.");
|
throw DeadlyImportError("No current node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *val(node->getValue());
|
Value *val(node->getValue());
|
||||||
if (nullptr != val) {
|
if (nullptr != val) {
|
||||||
if (Value::ValueType::ddl_string != val->m_type) {
|
if (Value::ValueType::ddl_string != val->m_type) {
|
||||||
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
|
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string name(val->getString());
|
const std::string name(val->getString());
|
||||||
|
@ -508,7 +506,6 @@ static void getRefNames(DDLNode *node, std::vector<std::string> &names) {
|
||||||
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> objRefNames;
|
std::vector<std::string> objRefNames;
|
||||||
|
@ -532,7 +529,6 @@ void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
|
||||||
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> matRefNames;
|
std::vector<std::string> matRefNames;
|
||||||
|
@ -672,14 +668,12 @@ static void setMatrix(aiNode *node, DataArrayList *transformData) {
|
||||||
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == m_currentNode) {
|
if (nullptr == m_currentNode) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *transformData(node->getDataArrayList());
|
DataArrayList *transformData(node->getDataArrayList());
|
||||||
if (nullptr != transformData) {
|
if (nullptr != transformData) {
|
||||||
if (transformData->m_numItems != 16) {
|
if (transformData->m_numItems != 16) {
|
||||||
throw DeadlyImportError("Invalid number of data for transform matrix.");
|
throw DeadlyImportError("Invalid number of data for transform matrix.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setMatrix(m_currentNode, transformData);
|
setMatrix(m_currentNode, transformData);
|
||||||
}
|
}
|
||||||
|
@ -835,7 +829,6 @@ static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *
|
||||||
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Property *prop = node->getProperties();
|
Property *prop = node->getProperties();
|
||||||
|
@ -876,12 +869,10 @@ void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene *
|
||||||
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
|
||||||
if (nullptr == node) {
|
if (nullptr == node) {
|
||||||
throw DeadlyImportError("No parent node for name.");
|
throw DeadlyImportError("No parent node for name.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr == m_currentMesh) {
|
if (nullptr == m_currentMesh) {
|
||||||
throw DeadlyImportError("No current mesh for index data found.");
|
throw DeadlyImportError("No current mesh for index data found.");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DataArrayList *vaList = node->getDataArrayList();
|
DataArrayList *vaList = node->getDataArrayList();
|
||||||
|
|
|
@ -382,11 +382,10 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
goto outer;
|
goto outer;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw DeadlyImportError("Quick3D: Unknown chunk");
|
throw DeadlyImportError("Quick3D: Unknown chunk");
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
outer:
|
outer:
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Assimp {
|
||||||
class RAWImporter : public BaseImporter {
|
class RAWImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
RAWImporter();
|
RAWImporter();
|
||||||
~RAWImporter();
|
~RAWImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
|
|
@ -85,7 +85,7 @@ static const aiImporterDesc desc = {
|
||||||
struct SIBChunk {
|
struct SIBChunk {
|
||||||
uint32_t Tag;
|
uint32_t Tag;
|
||||||
uint32_t Size;
|
uint32_t Size;
|
||||||
} PACK_STRUCT;
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
POS,
|
POS,
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace Assimp {
|
||||||
class UnrealImporter : public BaseImporter {
|
class UnrealImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
UnrealImporter();
|
UnrealImporter();
|
||||||
~UnrealImporter();
|
~UnrealImporter() override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Returns whether we can handle the format of the given file
|
/** @brief Returns whether we can handle the format of the given file
|
||||||
|
|
|
@ -578,7 +578,7 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
|
||||||
aiString name;
|
aiString name;
|
||||||
pScene->mMaterials[b]->Get( AI_MATKEY_NAME, name);
|
pScene->mMaterials[b]->Get( AI_MATKEY_NAME, name);
|
||||||
if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 ) {
|
if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 ) {
|
||||||
oldMat.sceneIndex = a;
|
oldMat.sceneIndex = b;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -839,7 +839,6 @@ void XFileParser::ParseDataObjectAnimationKey(AnimBone *pAnimBone) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ThrowException("Unknown key type ", keyType, " in animation.");
|
ThrowException("Unknown key type ", keyType, " in animation.");
|
||||||
break;
|
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
// key separator
|
// key separator
|
||||||
|
|
|
@ -58,8 +58,6 @@ class X3DExporter {
|
||||||
Value(value) {
|
Value(value) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
SAttribute(SAttribute &&rhs) AI_NO_EXCEPT = default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
|
|
|
@ -55,6 +55,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
AI_WONT_RETURN inline void Throw_ArgOutOfRange(const std::string &argument) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_CloseNotFound(const std::string &node) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrF(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrD(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrB(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrI(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_DEF_And_USE(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_TagCountIncorrect(const std::string &pNode) AI_WONT_RETURN_SUFFIX;
|
||||||
|
AI_WONT_RETURN inline void Throw_USE_NotFound(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
inline void Throw_ArgOutOfRange(const std::string &argument) {
|
inline void Throw_ArgOutOfRange(const std::string &argument) {
|
||||||
throw DeadlyImportError("Argument value is out of range for: \"" + argument + "\".");
|
throw DeadlyImportError("Argument value is out of range for: \"" + argument + "\".");
|
||||||
|
|
|
@ -12,7 +12,6 @@ bool X3DXmlHelper::getColor3DAttribute(XmlNode &node, const char *attributeName,
|
||||||
tokenize<std::string>(val, values, " ");
|
tokenize<std::string>(val, values, " ");
|
||||||
if (values.size() != 3) {
|
if (values.size() != 3) {
|
||||||
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
color.r = stof(*it++);
|
color.r = stof(*it++);
|
||||||
|
@ -30,7 +29,6 @@ bool X3DXmlHelper::getVector2DAttribute(XmlNode &node, const char *attributeName
|
||||||
tokenize<std::string>(val, values, " ");
|
tokenize<std::string>(val, values, " ");
|
||||||
if (values.size() != 2) {
|
if (values.size() != 2) {
|
||||||
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
color.x = stof(*it++);
|
color.x = stof(*it++);
|
||||||
|
@ -47,7 +45,6 @@ bool X3DXmlHelper::getVector3DAttribute(XmlNode &node, const char *attributeName
|
||||||
tokenize<std::string>(val, values, " ");
|
tokenize<std::string>(val, values, " ");
|
||||||
if (values.size() != 3) {
|
if (values.size() != 3) {
|
||||||
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
auto it = values.begin();
|
auto it = values.begin();
|
||||||
color.x = stof(*it++);
|
color.x = stof(*it++);
|
||||||
|
|
|
@ -484,7 +484,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer();
|
Buffer();
|
||||||
~Buffer();
|
~Buffer() override;
|
||||||
|
|
||||||
void Read(Value &obj, Asset &r);
|
void Read(Value &obj, Asset &r);
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,8 @@ SET( Common_SRCS
|
||||||
Common/ScenePreprocessor.cpp
|
Common/ScenePreprocessor.cpp
|
||||||
Common/ScenePreprocessor.h
|
Common/ScenePreprocessor.h
|
||||||
Common/SkeletonMeshBuilder.cpp
|
Common/SkeletonMeshBuilder.cpp
|
||||||
|
Common/StackAllocator.h
|
||||||
|
Common/StackAllocator.inl
|
||||||
Common/StandardShapes.cpp
|
Common/StandardShapes.cpp
|
||||||
Common/TargetAnimation.cpp
|
Common/TargetAnimation.cpp
|
||||||
Common/TargetAnimation.h
|
Common/TargetAnimation.h
|
||||||
|
@ -1211,7 +1213,6 @@ IF (ASSIMP_WARNINGS_AS_ERRORS)
|
||||||
-Wno-undef
|
-Wno-undef
|
||||||
-Wno-suggest-destructor-override
|
-Wno-suggest-destructor-override
|
||||||
-Wno-suggest-override
|
-Wno-suggest-override
|
||||||
-Wno-inconsistent-missing-destructor-override
|
|
||||||
-Wno-zero-as-null-pointer-constant
|
-Wno-zero-as-null-pointer-constant
|
||||||
-Wno-global-constructors
|
-Wno-global-constructors
|
||||||
-Wno-exit-time-destructors
|
-Wno-exit-time-destructors
|
||||||
|
@ -1235,19 +1236,14 @@ IF (ASSIMP_WARNINGS_AS_ERRORS)
|
||||||
-Wno-header-hygiene
|
-Wno-header-hygiene
|
||||||
-Wno-tautological-value-range-compare
|
-Wno-tautological-value-range-compare
|
||||||
-Wno-tautological-type-limit-compare
|
-Wno-tautological-type-limit-compare
|
||||||
-Wno-missing-noreturn
|
|
||||||
-Wno-missing-variable-declarations
|
-Wno-missing-variable-declarations
|
||||||
-Wno-extra-semi
|
-Wno-extra-semi
|
||||||
-Wno-nonportable-system-include-path
|
-Wno-nonportable-system-include-path
|
||||||
-Wno-undefined-reinterpret-cast
|
-Wno-undefined-reinterpret-cast
|
||||||
-Wno-shift-sign-overflow
|
-Wno-shift-sign-overflow
|
||||||
-Wno-deprecated-copy-with-user-provided-dtor
|
|
||||||
-Wno-deprecated-copy-with-dtor
|
|
||||||
-Wno-deprecated
|
-Wno-deprecated
|
||||||
-Wno-format-nonliteral
|
-Wno-format-nonliteral
|
||||||
-Wno-comma
|
-Wno-comma
|
||||||
-Wno-unreachable-code-break
|
|
||||||
-Wno-unreachable-code-return
|
|
||||||
-Wno-implicit-fallthrough
|
-Wno-implicit-fallthrough
|
||||||
-Wno-unused-template
|
-Wno-unused-template
|
||||||
-Wno-undefined-func-template
|
-Wno-undefined-func-template
|
||||||
|
|
|
@ -1349,6 +1349,9 @@ void SceneCombiner::Copy(aiMetadata **_dest, const aiMetadata *src) {
|
||||||
case AI_AIVECTOR3D:
|
case AI_AIVECTOR3D:
|
||||||
out.mData = new aiVector3D(*static_cast<aiVector3D *>(in.mData));
|
out.mData = new aiVector3D(*static_cast<aiVector3D *>(in.mData));
|
||||||
break;
|
break;
|
||||||
|
case AI_AIMETADATA:
|
||||||
|
out.mData = new aiMetadata(*static_cast<aiMetadata *>(in.mData));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file StackAllocator.h
|
||||||
|
* @brief A very bare-bone allocator class that is suitable when
|
||||||
|
* allocating many small objects, e.g. during parsing.
|
||||||
|
* Individual objects are not freed, instead only the whole memory
|
||||||
|
* can be deallocated.
|
||||||
|
*/
|
||||||
|
#ifndef AI_STACK_ALLOCATOR_H_INC
|
||||||
|
#define AI_STACK_ALLOCATOR_H_INC
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
/** @brief A very bare-bone allocator class that is suitable when
|
||||||
|
* allocating many small objects, e.g. during parsing.
|
||||||
|
* Individual objects are not freed, instead only the whole memory
|
||||||
|
* can be deallocated.
|
||||||
|
*/
|
||||||
|
class StackAllocator {
|
||||||
|
public:
|
||||||
|
/// @brief Constructs the allocator
|
||||||
|
inline StackAllocator();
|
||||||
|
/// @brief Destructs the allocator and frees all memory
|
||||||
|
inline ~StackAllocator();
|
||||||
|
|
||||||
|
// non copyable
|
||||||
|
StackAllocator(const StackAllocator &) = delete;
|
||||||
|
StackAllocator &operator=(const StackAllocator &) = delete;
|
||||||
|
|
||||||
|
/// @brief Returns a pointer to byteSize bytes of heap memory that persists
|
||||||
|
/// for the lifetime of the allocator (or until FreeAll is called).
|
||||||
|
inline void *Allocate(size_t byteSize);
|
||||||
|
|
||||||
|
/// @brief Releases all the memory owned by this allocator.
|
||||||
|
// Memory provided through function Allocate is not valid anymore after this function has been called.
|
||||||
|
inline void FreeAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
constexpr const static size_t g_maxBytesPerBlock = 64 * 1024 * 1024; // The maximum size (in bytes) of a block
|
||||||
|
constexpr const static size_t g_startBytesPerBlock = 16 * 1024; // Size of the first block. Next blocks will double in size until maximum size of g_maxBytesPerBlock
|
||||||
|
size_t m_blockAllocationSize = g_startBytesPerBlock; // Block size of the current block
|
||||||
|
size_t m_subIndex = g_maxBytesPerBlock; // The current byte offset in the current block
|
||||||
|
std::vector<uint8_t *> m_storageBlocks; // A list of blocks
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
||||||
|
#include "StackAllocator.inl"
|
||||||
|
|
||||||
|
#endif // include guard
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
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 "StackAllocator.h"
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
inline StackAllocator::StackAllocator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StackAllocator::~StackAllocator() {
|
||||||
|
FreeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void *StackAllocator::Allocate(size_t byteSize) {
|
||||||
|
if (m_subIndex + byteSize > m_blockAllocationSize) // start a new block
|
||||||
|
{
|
||||||
|
// double block size every time, up to maximum of g_maxBytesPerBlock.
|
||||||
|
// Block size must be at least as large as byteSize, but we want to use this for small allocations anyway.
|
||||||
|
m_blockAllocationSize = std::max(std::min(m_blockAllocationSize * 2, g_maxBytesPerBlock), byteSize);
|
||||||
|
uint8_t *data = new uint8_t[m_blockAllocationSize];
|
||||||
|
m_storageBlocks.emplace_back(data);
|
||||||
|
m_subIndex = byteSize;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *data = m_storageBlocks.back();
|
||||||
|
data += m_subIndex;
|
||||||
|
m_subIndex += byteSize;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void StackAllocator::FreeAll() {
|
||||||
|
for (size_t i = 0; i < m_storageBlocks.size(); i++) {
|
||||||
|
delete [] m_storageBlocks[i];
|
||||||
|
}
|
||||||
|
std::vector<uint8_t *> empty;
|
||||||
|
m_storageBlocks.swap(empty);
|
||||||
|
// start over:
|
||||||
|
m_blockAllocationSize = g_startBytesPerBlock;
|
||||||
|
m_subIndex = g_maxBytesPerBlock;
|
||||||
|
}
|
|
@ -68,7 +68,7 @@ class ZipFile : public IOStream {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::string m_Filename;
|
std::string m_Filename;
|
||||||
virtual ~ZipFile();
|
virtual ~ZipFile() override;
|
||||||
|
|
||||||
// IOStream interface
|
// IOStream interface
|
||||||
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
|
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;
|
||||||
|
|
|
@ -45,35 +45,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
|
ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
|
||||||
ai_real s = (a + b + c) / 2;
|
const ai_real s = (a + b + c) / 2;
|
||||||
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
const ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_real GeometryUtils::distance3D( const aiVector3D &vA, aiVector3D &vB ) {
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ai_real GeometryUtils::distance3D( const aiVector3D &vA, const aiVector3D &vB ) {
|
||||||
const ai_real lx = ( vB.x - vA.x );
|
const ai_real lx = ( vB.x - vA.x );
|
||||||
const ai_real ly = ( vB.y - vA.y );
|
const ai_real ly = ( vB.y - vA.y );
|
||||||
const ai_real lz = ( vB.z - vA.z );
|
const ai_real lz = ( vB.z - vA.z );
|
||||||
ai_real a = lx*lx + ly*ly + lz*lz;
|
const ai_real a = lx*lx + ly*ly + lz*lz;
|
||||||
ai_real d = pow( a, (ai_real)0.5 );
|
const ai_real d = pow( a, (ai_real)0.5 );
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
||||||
ai_real area = 0;
|
ai_real area = 0;
|
||||||
|
|
||||||
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
|
const aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
|
||||||
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
|
const aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
|
||||||
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
|
const aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
|
||||||
|
|
||||||
ai_real a( distance3D( vA, vB ) );
|
const ai_real a = distance3D( vA, vB );
|
||||||
ai_real b( distance3D( vB, vC ) );
|
const ai_real b = distance3D( vB, vC );
|
||||||
ai_real c( distance3D( vC, vA ) );
|
const ai_real c = distance3D( vC, vA );
|
||||||
area = heron( a, b, c );
|
area = heron( a, b, c );
|
||||||
|
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Check whether a ray intersects a plane and find the intersection point
|
||||||
|
bool GeometryUtils::PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
|
||||||
|
const aiVector3D& planeNormal, aiVector3D& pos) {
|
||||||
|
const ai_real b = planeNormal * (planePos - ray.pos);
|
||||||
|
ai_real h = ray.dir * planeNormal;
|
||||||
|
if ((h < 10e-5 && h > -10e-5) || (h = b/h) < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pos = ray.pos + (ray.dir * h);
|
||||||
|
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 );
|
||||||
|
|
||||||
|
@ -55,13 +55,27 @@ public:
|
||||||
/// @param vA Vector a.
|
/// @param vA Vector a.
|
||||||
/// @param vB Vector b.
|
/// @param vB Vector b.
|
||||||
/// @return The distance.
|
/// @return The distance.
|
||||||
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB );
|
static ai_real distance3D( const aiVector3D &vA, const aiVector3D &vB );
|
||||||
|
|
||||||
/// @brief Will calculate the area of a triangle described by a aiFace.
|
/// @brief Will calculate the area of a triangle described by a aiFace.
|
||||||
/// @param face The face
|
/// @param face The face
|
||||||
/// @param mesh The mesh containing the face
|
/// @param mesh The mesh containing the face
|
||||||
/// @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 Will calculate the intersection between a ray and a plane
|
||||||
|
/// @param ray The ray to test for
|
||||||
|
/// @param planePos A point on the plane
|
||||||
|
/// @param planeNormal The plane normal to describe its orientation
|
||||||
|
/// @param pos The position of the intersection.
|
||||||
|
/// @return true is an intersection was detected, false if not.
|
||||||
|
static bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, const aiVector3D& planeNormal, aiVector3D& pos);
|
||||||
|
|
||||||
|
/// @brief Will normalize an array of vectors.
|
||||||
|
/// @param vectorArrayIn The incoming arra of vectors.
|
||||||
|
/// @param vectorArrayOut The normalized vectors.
|
||||||
|
/// @param numVectors The array size.
|
||||||
|
static void normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut, size_t numVectors);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
|
@ -43,15 +43,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
/// The default class constructor.
|
static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones) {
|
||||||
ArmaturePopulate::ArmaturePopulate() = default;
|
for (aiBone *bone : bones) {
|
||||||
|
if (bone->mName == bone_name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The class destructor.
|
return false;
|
||||||
ArmaturePopulate::~ArmaturePopulate() = default;
|
}
|
||||||
|
|
||||||
bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
|
bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
|
||||||
return (pFlags & aiProcess_PopulateArmatureData) != 0;
|
return (pFlags & aiProcess_PopulateArmatureData) != 0;
|
||||||
|
@ -70,7 +73,7 @@ void ArmaturePopulate::Execute(aiScene *out) {
|
||||||
BuildBoneList(out->mRootNode, out->mRootNode, out, bones);
|
BuildBoneList(out->mRootNode, out->mRootNode, out, bones);
|
||||||
BuildNodeList(out->mRootNode, nodes);
|
BuildNodeList(out->mRootNode, nodes);
|
||||||
|
|
||||||
BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes);
|
BuildBoneStack(out->mRootNode, out, bones, bone_stack, nodes);
|
||||||
|
|
||||||
ASSIMP_LOG_DEBUG("Bone stack size: ", bone_stack.size());
|
ASSIMP_LOG_DEBUG("Bone stack size: ", bone_stack.size());
|
||||||
|
|
||||||
|
@ -78,9 +81,8 @@ void ArmaturePopulate::Execute(aiScene *out) {
|
||||||
aiBone *bone = kvp.first;
|
aiBone *bone = kvp.first;
|
||||||
aiNode *bone_node = kvp.second;
|
aiNode *bone_node = kvp.second;
|
||||||
ASSIMP_LOG_VERBOSE_DEBUG("active node lookup: ", bone->mName.C_Str());
|
ASSIMP_LOG_VERBOSE_DEBUG("active node lookup: ", bone->mName.C_Str());
|
||||||
// lcl transform grab - done in generate_nodes :)
|
|
||||||
|
|
||||||
// bone->mOffsetMatrix = bone_node->mTransformation;
|
// lcl transform grab - done in generate_nodes :)
|
||||||
aiNode *armature = GetArmatureRoot(bone_node, bones);
|
aiNode *armature = GetArmatureRoot(bone_node, bones);
|
||||||
|
|
||||||
ai_assert(armature);
|
ai_assert(armature);
|
||||||
|
@ -159,8 +161,7 @@ void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
|
||||||
// A bone stack allows us to have multiple armatures, with the same bone names
|
// A bone stack allows us to have multiple armatures, with the same bone names
|
||||||
// A bone stack allows us also to retrieve bones true transform even with
|
// A bone stack allows us also to retrieve bones true transform even with
|
||||||
// duplicate names :)
|
// duplicate names :)
|
||||||
void ArmaturePopulate::BuildBoneStack(aiNode *,
|
void ArmaturePopulate::BuildBoneStack(const aiNode *root_node,
|
||||||
const aiNode *root_node,
|
|
||||||
const aiScene*,
|
const aiScene*,
|
||||||
const std::vector<aiBone *> &bones,
|
const std::vector<aiBone *> &bones,
|
||||||
std::map<aiBone *, aiNode *> &bone_stack,
|
std::map<aiBone *, aiNode *> &bone_stack,
|
||||||
|
@ -196,8 +197,7 @@ void ArmaturePopulate::BuildBoneStack(aiNode *,
|
||||||
// This is required to be detected for a bone initially, it will recurse up
|
// This is required to be detected for a bone initially, it will recurse up
|
||||||
// until it cannot find another bone and return the node No known failure
|
// until it cannot find another bone and return the node No known failure
|
||||||
// points. (yet)
|
// points. (yet)
|
||||||
aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
|
aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node, std::vector<aiBone *> &bone_list) {
|
||||||
std::vector<aiBone *> &bone_list) {
|
|
||||||
while (nullptr != bone_node) {
|
while (nullptr != bone_node) {
|
||||||
if (!IsBoneNode(bone_node->mName, bone_list)) {
|
if (!IsBoneNode(bone_node->mName, bone_list)) {
|
||||||
ASSIMP_LOG_VERBOSE_DEBUG("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str());
|
ASSIMP_LOG_VERBOSE_DEBUG("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str());
|
||||||
|
@ -212,18 +212,6 @@ aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simple IsBoneNode check if this could be a bone
|
|
||||||
bool ArmaturePopulate::IsBoneNode(const aiString &bone_name,
|
|
||||||
std::vector<aiBone *> &bones) {
|
|
||||||
for (aiBone *bone : bones) {
|
|
||||||
if (bone->mName == bone_name) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop this node by name from the stack if found
|
// Pop this node by name from the stack if found
|
||||||
// Used in multiple armature situations with duplicate node / bone names
|
// Used in multiple armature situations with duplicate node / bone names
|
||||||
// Known flaw: cannot have nodes with bone names, will be fixed in later release
|
// Known flaw: cannot have nodes with bone names, will be fixed in later release
|
||||||
|
|
|
@ -69,10 +69,10 @@ namespace Assimp {
|
||||||
class ASSIMP_API ArmaturePopulate : public BaseProcess {
|
class ASSIMP_API ArmaturePopulate : public BaseProcess {
|
||||||
public:
|
public:
|
||||||
/// The default class constructor.
|
/// The default class constructor.
|
||||||
ArmaturePopulate();
|
ArmaturePopulate() = default;
|
||||||
|
|
||||||
/// The class destructor.
|
/// The class destructor.
|
||||||
virtual ~ArmaturePopulate();
|
virtual ~ArmaturePopulate() = default;
|
||||||
|
|
||||||
/// Overwritten, @see BaseProcess
|
/// Overwritten, @see BaseProcess
|
||||||
virtual bool IsActive( unsigned int pFlags ) const;
|
virtual bool IsActive( unsigned int pFlags ) const;
|
||||||
|
@ -86,9 +86,6 @@ public:
|
||||||
static aiNode *GetArmatureRoot(aiNode *bone_node,
|
static aiNode *GetArmatureRoot(aiNode *bone_node,
|
||||||
std::vector<aiBone *> &bone_list);
|
std::vector<aiBone *> &bone_list);
|
||||||
|
|
||||||
static bool IsBoneNode(const aiString &bone_name,
|
|
||||||
std::vector<aiBone *> &bones);
|
|
||||||
|
|
||||||
static aiNode *GetNodeFromStack(const aiString &node_name,
|
static aiNode *GetNodeFromStack(const aiString &node_name,
|
||||||
std::vector<aiNode *> &nodes);
|
std::vector<aiNode *> &nodes);
|
||||||
|
|
||||||
|
@ -99,7 +96,7 @@ public:
|
||||||
const aiScene *scene,
|
const aiScene *scene,
|
||||||
std::vector<aiBone *> &bones);
|
std::vector<aiBone *> &bones);
|
||||||
|
|
||||||
static void BuildBoneStack(aiNode *current_node, const aiNode *root_node,
|
static void BuildBoneStack(const aiNode *root_node,
|
||||||
const aiScene *scene,
|
const aiScene *scene,
|
||||||
const std::vector<aiBone *> &bones,
|
const std::vector<aiBone *> &bones,
|
||||||
std::map<aiBone *, aiNode *> &bone_stack,
|
std::map<aiBone *, aiNode *> &bone_stack,
|
||||||
|
@ -108,5 +105,4 @@ public:
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
|
||||||
#endif // SCALE_PROCESS_H_
|
#endif // SCALE_PROCESS_H_
|
||||||
|
|
|
@ -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,8 @@ 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>
|
||||||
|
|
||||||
|
@ -51,39 +50,25 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Check whether a ray intersects a plane and find the intersection point
|
|
||||||
inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
|
|
||||||
const aiVector3D& planeNormal, aiVector3D& pos)
|
|
||||||
{
|
|
||||||
const ai_real b = planeNormal * (planePos - ray.pos);
|
|
||||||
ai_real h = ray.dir * planeNormal;
|
|
||||||
if ((h < 10e-5 && h > -10e-5) || (h = b/h) < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pos = ray.pos + (ray.dir * h);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
ASSIMP_LOG_ERROR("Unable to compute UV coordinates, no free UV slot found");
|
ASSIMP_LOG_ERROR("Unable to compute UV coordinates, no free UV slot found");
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
|
@ -91,22 +76,22 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int smallV = face.mNumIndices, large = smallV;
|
unsigned int smallV = face.mNumIndices, large = smallV;
|
||||||
bool zero = false, one = false, round_to_zero = false;
|
bool zero = false, one = false, round_to_zero = false;
|
||||||
|
@ -115,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
|
||||||
|
@ -137,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)
|
||||||
|
@ -156,9 +137,8 @@ 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)
|
||||||
out[face.mIndices[n]].x = 1.0;
|
out[face.mIndices[n]].x = 1.0;
|
||||||
|
@ -169,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);
|
||||||
|
|
||||||
|
@ -178,7 +157,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
||||||
// currently the mapping axis will always be one of x,y,z, except if the
|
// currently the mapping axis will always be one of x,y,z, except if the
|
||||||
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
||||||
// thus changing the mapping axis)
|
// thus changing the mapping axis)
|
||||||
if (axis * base_axis_x >= angle_epsilon) {
|
if (axis * base_axis_x >= angle_epsilon) {
|
||||||
|
|
||||||
// For each point get a normalized projection vector in the sphere,
|
// For each point get a normalized projection vector in the sphere,
|
||||||
// get its longitude and latitude and map them to their respective
|
// get its longitude and latitude and map them to their respective
|
||||||
|
@ -192,58 +171,54 @@ 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 ...
|
||||||
// currently the mapping axis will always be one of x,y,z, except if the
|
// currently the mapping axis will always be one of x,y,z, except if the
|
||||||
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
||||||
// thus changing the mapping axis)
|
// thus changing the mapping axis)
|
||||||
if (axis * base_axis_x >= angle_epsilon) {
|
if (axis * base_axis_x >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
const ai_real diff = max.x - min.x;
|
const ai_real diff = max.x - min.x;
|
||||||
|
|
||||||
|
@ -251,116 +226,110 @@ 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 ...
|
||||||
// currently the mapping axis will always be one of x,y,z, except if the
|
// currently the mapping axis will always be one of x,y,z, except if the
|
||||||
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
||||||
// thus changing the mapping axis)
|
// thus changing the mapping axis)
|
||||||
if (axis * base_axis_x >= angle_epsilon) {
|
if (axis * base_axis_x >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,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];
|
||||||
|
|
||||||
|
@ -386,23 +353,18 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -410,70 +372,62 @@ 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. ");
|
||||||
}
|
}
|
||||||
idx = outIdx;
|
idx = outIdx;
|
||||||
}
|
}
|
||||||
|
@ -483,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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -113,6 +111,12 @@ void MakeLeftHandedProcess::Execute(aiScene *pScene) {
|
||||||
ProcessAnimation(nodeAnim);
|
ProcessAnimation(nodeAnim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// process the cameras accordingly
|
||||||
|
for( unsigned int a = 0; a < pScene->mNumCameras; ++a)
|
||||||
|
{
|
||||||
|
ProcessCamera(pScene->mCameras[a]);
|
||||||
|
}
|
||||||
ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
|
ASSIMP_LOG_DEBUG("MakeLeftHandedProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,18 +223,18 @@ void MakeLeftHandedProcess::ProcessAnimation(aiNodeAnim *pAnim) {
|
||||||
|
|
||||||
// rotation keys
|
// rotation keys
|
||||||
for (unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) {
|
for (unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) {
|
||||||
/* That's the safe version, but the float errors add up. So we try the short version instead
|
|
||||||
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
|
|
||||||
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
|
|
||||||
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
|
|
||||||
aiQuaternion rotquat( rotmat);
|
|
||||||
pAnim->mRotationKeys[a].mValue = rotquat;
|
|
||||||
*/
|
|
||||||
pAnim->mRotationKeys[a].mValue.x *= -1.0f;
|
pAnim->mRotationKeys[a].mValue.x *= -1.0f;
|
||||||
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
|
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Converts a single camera to left handed coordinates.
|
||||||
|
void MakeLeftHandedProcess::ProcessCamera( aiCamera* pCam)
|
||||||
|
{
|
||||||
|
pCam->mLookAt = ai_real(2.0f) * pCam->mPosition - pCam->mLookAt;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
||||||
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
||||||
// # FlipUVsProcess
|
// # FlipUVsProcess
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct aiMesh;
|
||||||
struct aiNodeAnim;
|
struct aiNodeAnim;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
struct aiCamera;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -109,6 +110,14 @@ protected:
|
||||||
* @param pAnim The bone animation to transform
|
* @param pAnim The bone animation to transform
|
||||||
*/
|
*/
|
||||||
void ProcessAnimation( aiNodeAnim* pAnim);
|
void ProcessAnimation( aiNodeAnim* pAnim);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Converts a single camera to left handed coordinates.
|
||||||
|
* The camera viewing direction is inverted by reflecting mLookAt
|
||||||
|
* across mPosition.
|
||||||
|
* @param pCam The camera to convert
|
||||||
|
*/
|
||||||
|
void ProcessCamera( aiCamera* pCam);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -87,7 +86,7 @@ void DeboneProcess::Execute( aiScene* pScene) {
|
||||||
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
|
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
|
||||||
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
||||||
if(splitList[a]) {
|
if(splitList[a]) {
|
||||||
numSplits++;
|
++numSplits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,8 +118,8 @@ void DeboneProcess::Execute( aiScene* pScene) {
|
||||||
aiNode *theNode = find ? pScene->mRootNode->FindNode(*find) : nullptr;
|
aiNode *theNode = find ? pScene->mRootNode->FindNode(*find) : nullptr;
|
||||||
std::pair<unsigned int,aiNode*> push_pair(static_cast<unsigned int>(meshes.size()),theNode);
|
std::pair<unsigned int,aiNode*> push_pair(static_cast<unsigned int>(meshes.size()),theNode);
|
||||||
|
|
||||||
mSubMeshIndices[a].push_back(push_pair);
|
mSubMeshIndices[a].emplace_back(push_pair);
|
||||||
meshes.push_back(newMeshes[b].first);
|
meshes.emplace_back(newMeshes[b].first);
|
||||||
|
|
||||||
out+=newMeshes[b].first->mNumBones;
|
out+=newMeshes[b].first->mNumBones;
|
||||||
}
|
}
|
||||||
|
@ -360,9 +359,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const {
|
||||||
unsigned int m = static_cast<unsigned int>(pNode->mNumMeshes), n = static_cast<unsigned int>(mSubMeshIndices.size());
|
unsigned int m = static_cast<unsigned int>(pNode->mNumMeshes), n = static_cast<unsigned int>(mSubMeshIndices.size());
|
||||||
|
|
||||||
// first pass, look for meshes which have not moved
|
// first pass, look for meshes which have not moved
|
||||||
|
|
||||||
for(unsigned int a=0;a<m;a++) {
|
for(unsigned int a=0;a<m;a++) {
|
||||||
|
|
||||||
unsigned int srcIndex = pNode->mMeshes[a];
|
unsigned int srcIndex = pNode->mMeshes[a];
|
||||||
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
|
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
|
||||||
unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
|
unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
|
||||||
|
@ -376,8 +373,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const {
|
||||||
|
|
||||||
// second pass, collect deboned meshes
|
// second pass, collect deboned meshes
|
||||||
|
|
||||||
for(unsigned int a=0;a<n;a++)
|
for(unsigned int a=0;a<n;a++) {
|
||||||
{
|
|
||||||
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
|
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
|
||||||
unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
|
unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
|
||||||
|
|
||||||
|
|
|
@ -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,21 +69,21 @@ 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. "
|
||||||
"Face normals have been removed");
|
"Face normals have been removed");
|
||||||
} else {
|
} else {
|
||||||
ASSIMP_LOG_DEBUG("DropFaceNormalsProcess finished. "
|
ASSIMP_LOG_DEBUG("DropFaceNormalsProcess finished. "
|
||||||
"No normals were present");
|
"No normals were present");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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,30 +213,28 @@ 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;
|
||||||
face_dest.mIndices = face_src.mIndices;
|
face_dest.mIndices = face_src.mIndices;
|
||||||
|
|
||||||
if (&face_src != &face_dest) {
|
if (&face_src != &face_dest) {
|
||||||
// clear source
|
// clear source
|
||||||
face_src.mNumIndices = 0;
|
face_src.mNumIndices = 0;
|
||||||
face_src.mIndices = nullptr;
|
face_src.mIndices = nullptr;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Otherwise delete it if we don't need this face
|
// Otherwise delete it if we don't need this face
|
||||||
delete[] face_src.mIndices;
|
delete[] face_src.mIndices;
|
||||||
face_src.mIndices = nullptr;
|
face_src.mIndices = nullptr;
|
||||||
|
@ -247,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,39 +290,44 @@ 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) {
|
||||||
// Reverse the mesh face winding order
|
// Reverse the mesh face winding order
|
||||||
FlipWindingOrderProcess::ProcessMesh(mesh);
|
FlipWindingOrderProcess::ProcessMesh(mesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update positions
|
||||||
|
if (mesh->HasPositions()) {
|
||||||
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
|
mesh->mVertices[i] = mat * mesh->mVertices[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update positions
|
// Update normals and tangents
|
||||||
if (mesh->HasPositions()) {
|
if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
|
||||||
|
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
|
||||||
|
|
||||||
|
if (mesh->HasNormals()) {
|
||||||
|
normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
|
||||||
|
}
|
||||||
|
if (mesh->HasTangentsAndBitangents()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
mesh->mVertices[i] = mat * mesh->mVertices[i];
|
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
|
||||||
}
|
mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
|
||||||
}
|
|
||||||
|
|
||||||
// Update normals and tangents
|
|
||||||
if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
|
|
||||||
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
|
|
||||||
|
|
||||||
if (mesh->HasNormals()) {
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
|
||||||
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mesh->HasTangentsAndBitangents()) {
|
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
|
||||||
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
|
|
||||||
mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,40 +350,41 @@ 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) {
|
||||||
aiMesh *ctz = out[n];
|
aiMesh *ctz = out[n];
|
||||||
if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4 *>(ctz->mBones) == node->mTransformation) {
|
if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4 *>(ctz->mBones) == node->mTransformation) {
|
||||||
|
|
||||||
// ok, use this one. Update node mesh index
|
// ok, use this one. Update node mesh index
|
||||||
node->mMeshes[i] = numIn + n;
|
node->mMeshes[i] = numIn + n;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (node->mMeshes[i] < numIn) {
|
}
|
||||||
// Worst case. Need to operate on a full copy of the mesh
|
if (node->mMeshes[i] < numIn) {
|
||||||
ASSIMP_LOG_INFO("PretransformVertices: Copying mesh due to mismatching transforms");
|
// Worst case. Need to operate on a full copy of the mesh
|
||||||
aiMesh *ntz;
|
ASSIMP_LOG_INFO("PretransformVertices: Copying mesh due to mismatching transforms");
|
||||||
|
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);
|
||||||
|
|
||||||
out.push_back(ntz);
|
out.push_back(ntz);
|
||||||
|
|
||||||
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++;
|
}
|
||||||
|
++numFaces;
|
||||||
}
|
}
|
||||||
iFaces = 0;
|
numFaces = 0;
|
||||||
while ((*j) & (0x1000000 << iFaces))
|
while ((*j) & (0x1000000 << numFaces))
|
||||||
pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];
|
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.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -74,63 +72,6 @@ inline void ArrayDelete(T **&in, unsigned int &num) {
|
||||||
num = 0;
|
num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Updates the node graph - removes all nodes which have the "remove" flag set and the
|
|
||||||
// "don't remove" flag not set. Nodes with meshes are never deleted.
|
|
||||||
bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
|
|
||||||
{
|
|
||||||
bool b = false;
|
|
||||||
|
|
||||||
std::list<aiNode*> mine;
|
|
||||||
for (unsigned int i = 0; i < node->mNumChildren;++i)
|
|
||||||
{
|
|
||||||
if(UpdateNodeGraph(node->mChildren[i],mine,false))
|
|
||||||
b = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
|
|
||||||
// so we can do a simple comparison against MSB here
|
|
||||||
if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
|
|
||||||
{
|
|
||||||
// this node needs to be removed
|
|
||||||
if(node->mNumChildren)
|
|
||||||
{
|
|
||||||
childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
|
|
||||||
|
|
||||||
// set all children to nullptr to make sure they are not deleted when we delete ourself
|
|
||||||
for (unsigned int i = 0; i < node->mNumChildren;++i)
|
|
||||||
node->mChildren[i] = nullptr;
|
|
||||||
}
|
|
||||||
b = true;
|
|
||||||
delete node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AI_RC_UNMASK(node->mNumMeshes);
|
|
||||||
childsOfParent.push_back(node);
|
|
||||||
|
|
||||||
if (b)
|
|
||||||
{
|
|
||||||
// reallocate the array of our children here
|
|
||||||
node->mNumChildren = (unsigned int)mine.size();
|
|
||||||
aiNode** const children = new aiNode*[mine.size()];
|
|
||||||
aiNode** ptr = children;
|
|
||||||
|
|
||||||
for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
|
|
||||||
it != end; ++it)
|
|
||||||
{
|
|
||||||
*ptr++ = *it;
|
|
||||||
}
|
|
||||||
delete[] node->mChildren;
|
|
||||||
node->mChildren = children;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void RemoveVCProcess::Execute(aiScene *pScene) {
|
void RemoveVCProcess::Execute(aiScene *pScene) {
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -86,9 +85,9 @@ void ScaleProcess::Execute( aiScene* pScene ) {
|
||||||
return; // nothing to scale
|
return; // nothing to scale
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_assert( mScale != 0 );
|
ai_assert(mScale != 0 );
|
||||||
ai_assert( nullptr != pScene );
|
ai_assert(nullptr != pScene );
|
||||||
ai_assert( nullptr != pScene->mRootNode );
|
ai_assert(nullptr != pScene->mRootNode );
|
||||||
|
|
||||||
if ( nullptr == pScene ) {
|
if ( nullptr == pScene ) {
|
||||||
return;
|
return;
|
||||||
|
@ -140,7 +139,7 @@ void ScaleProcess::Execute( aiScene* pScene ) {
|
||||||
aiMatrix4x4 scaling;
|
aiMatrix4x4 scaling;
|
||||||
aiMatrix4x4::Scaling( aiVector3D(scale), scaling );
|
aiMatrix4x4::Scaling( aiVector3D(scale), scaling );
|
||||||
|
|
||||||
aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix());
|
const aiMatrix4x4 RotMatrix = aiMatrix4x4(rotation.GetMatrix());
|
||||||
|
|
||||||
bone->mOffsetMatrix = translation * RotMatrix * scaling;
|
bone->mOffsetMatrix = translation * RotMatrix * scaling;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -54,10 +52,7 @@ using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
SortByPTypeProcess::SortByPTypeProcess() :
|
SortByPTypeProcess::SortByPTypeProcess() : mConfigRemoveMeshes(0) {}
|
||||||
mConfigRemoveMeshes(0) {
|
|
||||||
// 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.
|
||||||
|
@ -104,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]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -155,7 +151,7 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
|
||||||
if (1 == num) {
|
if (1 == num) {
|
||||||
if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
|
if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
|
||||||
*meshIdx = static_cast<unsigned int>(outMeshes.size());
|
*meshIdx = static_cast<unsigned int>(outMeshes.size());
|
||||||
outMeshes.push_back(mesh);
|
outMeshes.emplace_back(mesh);
|
||||||
} else {
|
} else {
|
||||||
delete mesh;
|
delete mesh;
|
||||||
pScene->mMeshes[i] = nullptr;
|
pScene->mMeshes[i] = nullptr;
|
||||||
|
@ -311,21 +307,23 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
|
||||||
|
|
||||||
if (vert) {
|
if (vert) {
|
||||||
*vert++ = mesh->mVertices[idx];
|
*vert++ = mesh->mVertices[idx];
|
||||||
//mesh->mVertices[idx].x = get_qnan();
|
|
||||||
}
|
}
|
||||||
if (nor) *nor++ = mesh->mNormals[idx];
|
if (nor)
|
||||||
|
*nor++ = mesh->mNormals[idx];
|
||||||
if (tan) {
|
if (tan) {
|
||||||
*tan++ = mesh->mTangents[idx];
|
*tan++ = mesh->mTangents[idx];
|
||||||
*bit++ = mesh->mBitangents[idx];
|
*bit++ = mesh->mBitangents[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp) {
|
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp) {
|
||||||
if (!uv[pp]) break;
|
if (!uv[pp])
|
||||||
|
break;
|
||||||
*uv[pp]++ = mesh->mTextureCoords[pp][idx];
|
*uv[pp]++ = mesh->mTextureCoords[pp][idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp) {
|
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp) {
|
||||||
if (!cols[pp]) break;
|
if (!cols[pp])
|
||||||
|
break;
|
||||||
*cols[pp]++ = mesh->mColors[pp][idx];
|
*cols[pp]++ = mesh->mColors[pp][idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +349,7 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pp == mesh->mNumAnimMeshes)
|
if (pp == mesh->mNumAnimMeshes)
|
||||||
amIdx++;
|
++amIdx;
|
||||||
|
|
||||||
in.mIndices[q] = outIdx++;
|
in.mIndices[q] = outIdx++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -58,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.
|
||||||
|
@ -166,7 +163,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
unsigned int numBones = 0;
|
unsigned int numBones = 0;
|
||||||
std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
|
std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
|
||||||
// indices of the faces which are going to go into this submesh
|
// indices of the faces which are going to go into this submesh
|
||||||
std::vector<unsigned int> subMeshFaces;
|
IndexArray subMeshFaces;
|
||||||
subMeshFaces.reserve( pMesh->mNumFaces);
|
subMeshFaces.reserve( pMesh->mNumFaces);
|
||||||
// accumulated vertex count of all the faces in this submesh
|
// accumulated vertex count of all the faces in this submesh
|
||||||
unsigned int numSubMeshVertices = 0;
|
unsigned int numSubMeshVertices = 0;
|
||||||
|
@ -202,7 +199,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it) {
|
for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it) {
|
||||||
if (!isBoneUsed[*it]) {
|
if (!isBoneUsed[*it]) {
|
||||||
isBoneUsed[*it] = true;
|
isBoneUsed[*it] = true;
|
||||||
numBones++;
|
++numBones;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,18 +209,17 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
|
|
||||||
// remember that this face is handled
|
// remember that this face is handled
|
||||||
isFaceHandled[a] = true;
|
isFaceHandled[a] = true;
|
||||||
numFacesHandled++;
|
++numFacesHandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new mesh to hold this subset of the source mesh
|
// create a new mesh to hold this subset of the source mesh
|
||||||
aiMesh* newMesh = new aiMesh;
|
aiMesh* newMesh = new aiMesh;
|
||||||
if( pMesh->mName.length > 0 )
|
if( pMesh->mName.length > 0 ) {
|
||||||
{
|
|
||||||
newMesh->mName.Set( format() << pMesh->mName.data << "_sub" << poNewMeshes.size());
|
newMesh->mName.Set( format() << pMesh->mName.data << "_sub" << poNewMeshes.size());
|
||||||
}
|
}
|
||||||
newMesh->mMaterialIndex = pMesh->mMaterialIndex;
|
newMesh->mMaterialIndex = pMesh->mMaterialIndex;
|
||||||
newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
|
newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
|
||||||
poNewMeshes.push_back( newMesh);
|
poNewMeshes.emplace_back( newMesh);
|
||||||
|
|
||||||
// create all the arrays for this mesh if the old mesh contained them
|
// create all the arrays for this mesh if the old mesh contained them
|
||||||
newMesh->mNumVertices = numSubMeshVertices;
|
newMesh->mNumVertices = numSubMeshVertices;
|
||||||
|
@ -251,7 +247,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
// and copy over the data, generating faces with linear indices along the way
|
// and copy over the data, generating faces with linear indices along the way
|
||||||
newMesh->mFaces = new aiFace[subMeshFaces.size()];
|
newMesh->mFaces = new aiFace[subMeshFaces.size()];
|
||||||
unsigned int nvi = 0; // next vertex index
|
unsigned int nvi = 0; // next vertex index
|
||||||
std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
|
IndexArray previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
|
||||||
for( unsigned int a = 0; a < subMeshFaces.size(); ++a ) {
|
for( unsigned int a = 0; a < subMeshFaces.size(); ++a ) {
|
||||||
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
||||||
aiFace& dstFace = newMesh->mFaces[a];
|
aiFace& dstFace = newMesh->mFaces[a];
|
||||||
|
@ -399,10 +395,10 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
|
||||||
void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const {
|
void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const {
|
||||||
// rebuild the node's mesh index list
|
// rebuild the node's mesh index list
|
||||||
if( pNode->mNumMeshes == 0 ) {
|
if( pNode->mNumMeshes == 0 ) {
|
||||||
std::vector<unsigned int> newMeshList;
|
IndexArray newMeshList;
|
||||||
for( unsigned int a = 0; a < pNode->mNumMeshes; ++a) {
|
for( unsigned int a = 0; a < pNode->mNumMeshes; ++a) {
|
||||||
unsigned int srcIndex = pNode->mMeshes[a];
|
unsigned int srcIndex = pNode->mMeshes[a];
|
||||||
const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
|
const IndexArray& replaceMeshes = mSubMeshIndices[srcIndex];
|
||||||
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,10 @@ public:
|
||||||
/// basing on the Importer's configuration property list.
|
/// basing on the Importer's configuration property list.
|
||||||
virtual void SetupProperties(const Importer* pImp) override;
|
virtual void SetupProperties(const Importer* pImp) override;
|
||||||
|
|
||||||
|
/// @brief Will return the maximal number of bones.
|
||||||
|
/// @return The maximal number of bones.
|
||||||
|
size_t getMaxNumberOfBones() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Executes the post processing step on the given imported data.
|
/// Executes the post processing step on the given imported data.
|
||||||
/// At the moment a process is not supposed to fail.
|
/// At the moment a process is not supposed to fail.
|
||||||
|
@ -90,14 +94,19 @@ protected:
|
||||||
/// Recursively updates the node's mesh list to account for the changed mesh list
|
/// Recursively updates the node's mesh list to account for the changed mesh list
|
||||||
void UpdateNode( aiNode* pNode) const;
|
void UpdateNode( aiNode* pNode) const;
|
||||||
|
|
||||||
public:
|
private:
|
||||||
/// Max bone count. Splitting occurs if a mesh has more than that number of bones.
|
/// Max bone count. Splitting occurs if a mesh has more than that number of bones.
|
||||||
size_t mMaxBoneCount;
|
size_t mMaxBoneCount;
|
||||||
|
|
||||||
/// Per mesh index: Array of indices of the new submeshes.
|
/// Per mesh index: Array of indices of the new submeshes.
|
||||||
std::vector< std::vector<unsigned int> > mSubMeshIndices;
|
using IndexArray = std::vector<unsigned int>;
|
||||||
|
std::vector<IndexArray> mSubMeshIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline size_t SplitByBoneCountProcess::getMaxNumberOfBones() const {
|
||||||
|
return mMaxBoneCount;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
#endif // !!AI_SPLITBYBONECOUNTPROCESS_H_INC
|
#endif // !!AI_SPLITBYBONECOUNTPROCESS_H_INC
|
||||||
|
|
|
@ -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,22 +72,22 @@ 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) {
|
||||||
// it seems something has been split. rebuild the mesh list
|
|
||||||
delete[] pScene->mMeshes;
|
|
||||||
pScene->mNumMeshes = (unsigned int)avList.size();
|
|
||||||
pScene->mMeshes = new aiMesh*[avList.size()];
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < avList.size();++i) {
|
|
||||||
pScene->mMeshes[i] = avList[i].first;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now we need to update all nodes
|
|
||||||
this->UpdateNode(pScene->mRootNode,avList);
|
|
||||||
ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
|
|
||||||
} else {
|
|
||||||
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
|
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// it seems something has been split. rebuild the mesh list
|
||||||
|
delete[] pScene->mMeshes;
|
||||||
|
pScene->mNumMeshes = (unsigned int)avList.size();
|
||||||
|
pScene->mMeshes = new aiMesh*[avList.size()];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < avList.size();++i) {
|
||||||
|
pScene->mMeshes[i] = avList[i].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now we need to update all nodes
|
||||||
|
this->UpdateNode(pScene->mRootNode,avList);
|
||||||
|
ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -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,18 +108,21 @@ 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) {
|
||||||
if (!parray) {
|
return;
|
||||||
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
}
|
||||||
firstName, secondName, size);
|
|
||||||
}
|
if (!parray) {
|
||||||
for (unsigned int i = 0; i < size; ++i) {
|
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
||||||
if (!parray[i]) {
|
firstName, secondName, size);
|
||||||
ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
|
}
|
||||||
firstName, i, secondName, size);
|
|
||||||
}
|
for (unsigned int i = 0; i < size; ++i) {
|
||||||
Validate(parray[i]);
|
if (!parray[i]) {
|
||||||
|
ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
|
||||||
|
firstName, i, secondName, size);
|
||||||
}
|
}
|
||||||
|
Validate(parray[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,25 +131,27 @@ 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) {
|
||||||
if (!parray) {
|
return;
|
||||||
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
}
|
||||||
firstName, secondName, size);
|
|
||||||
}
|
|
||||||
for (unsigned int i = 0; i < size; ++i) {
|
|
||||||
if (!parray[i]) {
|
|
||||||
ReportError("aiScene::%s[%u] is nullptr (aiScene::%s is %u)",
|
|
||||||
firstName, i, secondName, size);
|
|
||||||
}
|
|
||||||
Validate(parray[i]);
|
|
||||||
|
|
||||||
// check whether there are duplicate names
|
if (!parray) {
|
||||||
for (unsigned int a = i + 1; a < size; ++a) {
|
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
|
||||||
if (parray[i]->mName == parray[a]->mName) {
|
firstName, secondName, size);
|
||||||
ReportError("aiScene::%s[%u] has the same name as "
|
}
|
||||||
"aiScene::%s[%u]",
|
for (unsigned int i = 0; i < size; ++i) {
|
||||||
firstName, i, secondName, a);
|
if (!parray[i]) {
|
||||||
}
|
ReportError("aiScene::%s[%u] is nullptr (aiScene::%s is %u)",
|
||||||
|
firstName, i, secondName, size);
|
||||||
|
}
|
||||||
|
Validate(parray[i]);
|
||||||
|
|
||||||
|
// check whether there are duplicate names
|
||||||
|
for (unsigned int a = i + 1; a < size; ++a) {
|
||||||
|
if (parray[i]->mName == parray[a]->mName) {
|
||||||
|
ReportError("aiScene::%s[%u] has the same name as "
|
||||||
|
"aiScene::%s[%u]",
|
||||||
|
firstName, i, secondName, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -290,7 +286,6 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh) {
|
||||||
switch (face.mNumIndices) {
|
switch (face.mNumIndices) {
|
||||||
case 0:
|
case 0:
|
||||||
ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
|
ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
|
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
|
||||||
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
|
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
|
||||||
|
@ -362,15 +357,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 +452,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
|
||||||
|
|
|
@ -92,6 +92,7 @@ namespace o3dgc
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
// - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
AI_WONT_RETURN static void AC_Error(const char * msg) AI_WONT_RETURN_SUFFIX;
|
||||||
static void AC_Error(const char * msg)
|
static void AC_Error(const char * msg)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "\n\n -> Arithmetic coding error: ");
|
fprintf(stderr, "\n\n -> Arithmetic coding error: ");
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
# pragma warning(disable : 4131 4244 4189 4245)
|
# pragma warning(disable : 4131 4244 4189 4245)
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
|
||||||
const char unz_copyright[] =
|
static const char unz_copyright[] =
|
||||||
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
|
||||||
|
|
||||||
/* unz_file_info_internal contain internal info about a file in zipfile*/
|
/* unz_file_info_internal contain internal info about a file in zipfile*/
|
||||||
|
|
|
@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <assimp/cimport.h>
|
#include <assimp/cimport.h>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
|
@ -53,6 +54,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
|
||||||
const aiScene *sc = importer.ReadFileFromMemory(data, dataSize,
|
const aiScene *sc = importer.ReadFileFromMemory(data, dataSize,
|
||||||
aiProcessPreset_TargetRealtime_Quality, nullptr );
|
aiProcessPreset_TargetRealtime_Quality, nullptr );
|
||||||
|
|
||||||
|
if (sc == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Exporter exporter;
|
||||||
|
exporter.ExportToBlob(sc, "fbx");
|
||||||
|
|
||||||
aiDetachLogStream(&stream);
|
aiDetachLogStream(&stream);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -66,7 +66,7 @@ ASSIMP_API void setAiAssertHandler(AiAssertHandler handler);
|
||||||
*
|
*
|
||||||
* @brief This issues a message to stderr and calls abort.
|
* @brief This issues a message to stderr and calls abort.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line);
|
AI_WONT_RETURN ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -84,7 +84,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Destructor public to allow simple deletion to close the file. */
|
/** Destructor public to allow simple deletion to close the file. */
|
||||||
~DefaultIOStream ();
|
~DefaultIOStream () override;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Read from stream
|
/// Read from stream
|
||||||
|
|
|
@ -145,7 +145,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Destructor.
|
/// @brief Destructor.
|
||||||
~MemoryIOSystem() = default;
|
~MemoryIOSystem() override = default;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// @brief Tests for the existence of a file at the given path.
|
/// @brief Tests for the existence of a file at the given path.
|
||||||
|
|
|
@ -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,15 +97,21 @@ 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;
|
||||||
Vertex() {}
|
aiVector3D normal;
|
||||||
|
aiVector3D tangent, bitangent;
|
||||||
|
|
||||||
|
aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
|
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||||
|
|
||||||
|
Vertex() = default;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Extract a particular vertex from a mesh and interleave all components */
|
/** Extract a particular vertex from a mesh and interleave all components */
|
||||||
|
@ -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];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
//! Open a Zip using the proffered IOSystem
|
//! Open a Zip using the proffered IOSystem
|
||||||
ZipArchiveIOSystem(IOSystem* pIOHandler, const char *pFilename, const char* pMode = "r");
|
ZipArchiveIOSystem(IOSystem* pIOHandler, const char *pFilename, const char* pMode = "r");
|
||||||
ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode = "r");
|
ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode = "r");
|
||||||
virtual ~ZipArchiveIOSystem();
|
virtual ~ZipArchiveIOSystem() override;
|
||||||
bool Exists(const char* pFilename) const override;
|
bool Exists(const char* pFilename) const override;
|
||||||
char getOsSeparator() const override;
|
char getOsSeparator() const override;
|
||||||
IOStream* Open(const char* pFilename, const char* pMode = "rb") override;
|
IOStream* Open(const char* pFilename, const char* pMode = "rb") override;
|
||||||
|
|
|
@ -184,6 +184,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
|
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
|
||||||
|
#elif _MSC_VER
|
||||||
|
#if defined(__clang__)
|
||||||
|
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
|
||||||
|
#else
|
||||||
|
# define AI_WONT_RETURN_SUFFIX
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
# define AI_WONT_RETURN_SUFFIX
|
# define AI_WONT_RETURN_SUFFIX
|
||||||
#endif // (defined __clang__)
|
#endif // (defined __clang__)
|
||||||
|
@ -283,7 +289,11 @@ typedef unsigned int ai_uint;
|
||||||
#define AI_RAD_TO_DEG(x) ((x) * (ai_real) 57.2957795)
|
#define AI_RAD_TO_DEG(x) ((x) * (ai_real) 57.2957795)
|
||||||
|
|
||||||
/* Numerical limits */
|
/* Numerical limits */
|
||||||
static const ai_real ai_epsilon = (ai_real) 1e-6;
|
#ifdef __cplusplus
|
||||||
|
constexpr ai_real ai_epsilon = (ai_real) 1e-6;
|
||||||
|
#else
|
||||||
|
const ai_real ai_epsilon = (ai_real) 1e-6;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Support for big-endian builds */
|
/* Support for big-endian builds */
|
||||||
#if defined(__BYTE_ORDER__)
|
#if defined(__BYTE_ORDER__)
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
const double fast_atof_table[16] = { // we write [16] here instead of [] to work around a swig bug
|
static constexpr size_t NumItems = 16;
|
||||||
|
|
||||||
|
constexpr double fast_atof_table[NumItems] = { // we write [16] here instead of [] to work around a swig bug
|
||||||
0.0,
|
0.0,
|
||||||
0.1,
|
0.1,
|
||||||
0.01,
|
0.01,
|
||||||
|
@ -58,12 +60,10 @@ const double fast_atof_table[16] = { // we write [16] here instead of [] to wo
|
||||||
0.000000000000001
|
0.000000000000001
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in decimal format to a number
|
// Convert a string in decimal format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul10( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul10( const char* in, const char** out=0) {
|
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
|
@ -83,8 +83,7 @@ unsigned int strtoul10( const char* in, const char** out=0) {
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in octal format to a number
|
// Convert a string in octal format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul8( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul8( const char* in, const char** out=0) {
|
|
||||||
unsigned int value( 0 );
|
unsigned int value( 0 );
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if ( *in < '0' || *in > '7' ) {
|
if ( *in < '0' || *in > '7' ) {
|
||||||
|
@ -103,8 +102,7 @@ unsigned int strtoul8( const char* in, const char** out=0) {
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a string in hex format to a number
|
// Convert a string in hex format to a number
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul16( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul16( const char* in, const char** out=0) {
|
|
||||||
unsigned int value( 0 );
|
unsigned int value( 0 );
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if ( *in >= '0' && *in <= '9' ) {
|
if ( *in >= '0' && *in <= '9' ) {
|
||||||
|
@ -128,8 +126,7 @@ unsigned int strtoul16( const char* in, const char** out=0) {
|
||||||
// Convert just one hex digit
|
// Convert just one hex digit
|
||||||
// Return value is UINT_MAX if the input character is not a hex digit.
|
// Return value is UINT_MAX if the input character is not a hex digit.
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int HexDigitToDecimal(char in) {
|
||||||
unsigned int HexDigitToDecimal(char in) {
|
|
||||||
unsigned int out( UINT_MAX );
|
unsigned int out( UINT_MAX );
|
||||||
if ( in >= '0' && in <= '9' ) {
|
if ( in >= '0' && in <= '9' ) {
|
||||||
out = in - '0';
|
out = in - '0';
|
||||||
|
@ -146,16 +143,14 @@ unsigned int HexDigitToDecimal(char in) {
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Convert a hex-encoded octet (2 characters, i.e. df or 1a).
|
// Convert a hex-encoded octet (2 characters, i.e. df or 1a).
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline uint8_t HexOctetToDecimal(const char* in) {
|
||||||
uint8_t HexOctetToDecimal(const char* in) {
|
|
||||||
return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
|
return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// signed variant of strtoul10
|
// signed variant of strtoul10
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline int strtol10( const char* in, const char** out=0) {
|
||||||
int strtol10( const char* in, const char** out=0) {
|
|
||||||
bool inv = (*in=='-');
|
bool inv = (*in=='-');
|
||||||
if ( inv || *in == '+' ) {
|
if ( inv || *in == '+' ) {
|
||||||
++in;
|
++in;
|
||||||
|
@ -163,7 +158,11 @@ int strtol10( const char* in, const char** out=0) {
|
||||||
|
|
||||||
int value = strtoul10(in,out);
|
int value = strtoul10(in,out);
|
||||||
if (inv) {
|
if (inv) {
|
||||||
value = -value;
|
if (value < INT_MAX) {
|
||||||
|
value = -value;
|
||||||
|
} else {
|
||||||
|
ASSIMP_LOG_WARN( "Converting the string \"", in, "\" into an inverted value resulted in overflow." );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -174,8 +173,7 @@ int strtol10( const char* in, const char** out=0) {
|
||||||
// 0NNN - oct
|
// 0NNN - oct
|
||||||
// NNN - dec
|
// NNN - dec
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
inline
|
inline unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
|
||||||
unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
|
|
||||||
if ('0' == in[0]) {
|
if ('0' == in[0]) {
|
||||||
return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out);
|
return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out);
|
||||||
}
|
}
|
||||||
|
@ -187,8 +185,7 @@ unsigned int strtoul_cppstyle( const char* in, const char** out=0) {
|
||||||
// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
|
// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) {
|
||||||
uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0) {
|
|
||||||
unsigned int cur = 0;
|
unsigned int cur = 0;
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
@ -241,8 +238,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino
|
||||||
// signed variant of strtoul10_64
|
// signed variant of strtoul10_64
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) {
|
||||||
int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0) {
|
|
||||||
bool inv = (*in == '-');
|
bool inv = (*in == '-');
|
||||||
if ( inv || *in == '+' ) {
|
if ( inv || *in == '+' ) {
|
||||||
++in;
|
++in;
|
||||||
|
@ -264,8 +260,7 @@ int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inou
|
||||||
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
|
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
template<typename Real, typename ExceptionType = DeadlyImportError>
|
template<typename Real, typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) {
|
||||||
const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true) {
|
|
||||||
Real f = 0;
|
Real f = 0;
|
||||||
|
|
||||||
bool inv = (*c == '-');
|
bool inv = (*c == '-');
|
||||||
|
@ -354,8 +349,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// The same but more human.
|
// The same but more human.
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline ai_real fast_atof(const char* c) {
|
||||||
ai_real fast_atof(const char* c) {
|
|
||||||
ai_real ret(0.0);
|
ai_real ret(0.0);
|
||||||
fast_atoreal_move<ai_real, ExceptionType>(c, ret);
|
fast_atoreal_move<ai_real, ExceptionType>(c, ret);
|
||||||
|
|
||||||
|
@ -372,8 +366,7 @@ ai_real fast_atof( const char* c, const char** cout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ExceptionType = DeadlyImportError>
|
template<typename ExceptionType = DeadlyImportError>
|
||||||
inline
|
inline ai_real fast_atof( const char** inout) {
|
||||||
ai_real fast_atof( const char** inout) {
|
|
||||||
ai_real ret(0.0);
|
ai_real ret(0.0);
|
||||||
*inout = fast_atoreal_move<ai_real, ExceptionType>(*inout, ret);
|
*inout = fast_atoreal_move<ai_real, ExceptionType>(*inout, ret);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -200,12 +204,13 @@ SET( POST_PROCESSES
|
||||||
unit/utGenBoundingBoxesProcess.cpp
|
unit/utGenBoundingBoxesProcess.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
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\\ImportExport FILES ${IMPORTERS} )
|
SOURCE_GROUP( UnitTests\\GeometryTools FILES ${Geometry} )
|
||||||
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
|
SOURCE_GROUP( UnitTests\\ImportExport FILES ${IMPORTERS} )
|
||||||
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
|
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
|
||||||
SOURCE_GROUP( UnitTests\\PostProcess FILES ${POST_PROCESSES})
|
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
|
||||||
|
SOURCE_GROUP( UnitTests\\PostProcess FILES ${POST_PROCESSES})
|
||||||
|
|
||||||
add_executable( unit
|
add_executable( unit
|
||||||
unit/CCompilerTest.c
|
unit/CCompilerTest.c
|
||||||
|
@ -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}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 192 KiB |
|
@ -1,6 +1,6 @@
|
||||||
class mar expands Actor;
|
class mar expands Actor;
|
||||||
|
|
||||||
#exec MESH IMPORT MESH=mar ANIVFILE=MODELS\mar_a.3d DATAFILE=MODELS\mar_d.3d X=0 Y=0 Z=0
|
#exec MESH IMPORT MESH=mar ANIVFILE=MODELS\mar_rifle_a.3d DATAFILE=MODELS\mar_rifle_d.3d X=0 Y=0 Z=0
|
||||||
#exec MESH ORIGIN MESH=mar X=0 Y=0 Z=0
|
#exec MESH ORIGIN MESH=mar X=0 Y=0 Z=0
|
||||||
|
|
||||||
#exec MESH SEQUENCE MESH=mar SEQ=All STARTFRAME=0 NUMFRAMES=30
|
#exec MESH SEQUENCE MESH=mar SEQ=All STARTFRAME=0 NUMFRAMES=30
|
||||||
|
@ -9,7 +9,7 @@ class mar expands Actor;
|
||||||
#exec MESHMAP NEW MESHMAP=mar MESH=mar
|
#exec MESHMAP NEW MESHMAP=mar MESH=mar
|
||||||
#exec MESHMAP SCALE MESHMAP=mar X=0.1 Y=0.1 Z=0.2
|
#exec MESHMAP SCALE MESHMAP=mar X=0.1 Y=0.1 Z=0.2
|
||||||
|
|
||||||
#exec TEXTURE IMPORT NAME=Jtex1 FILE=..\3DS\m_rifl.bmp GROUP=Skins FLAGS=2
|
#exec TEXTURE IMPORT NAME=Jtex1 FILE=m_rifl.bmp GROUP=Skins FLAGS=2
|
||||||
#exec TEXTURE IMPORT NAME=Jtex1 FILE=texture1.pcx GROUP=Skins PALETTE=Jtex1
|
#exec TEXTURE IMPORT NAME=Jtex1 FILE=texture1.pcx GROUP=Skins PALETTE=Jtex1
|
||||||
#exec MESHMAP SETTEXTURE MESHMAP=mar NUM=1 TEXTURE=Jtex1
|
#exec MESHMAP SETTEXTURE MESHMAP=mar NUM=1 TEXTURE=Jtex1
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -32,7 +32,7 @@
|
||||||
*MAP_CLASS "Bitmap"
|
*MAP_CLASS "Bitmap"
|
||||||
*MAP_SUBNO 1
|
*MAP_SUBNO 1
|
||||||
*MAP_AMOUNT 1.0000
|
*MAP_AMOUNT 1.0000
|
||||||
*BITMAP "../3DS/MP5SIL.BMP"
|
*BITMAP "mp5sil.bmp"
|
||||||
*MAP_TYPE Screen
|
*MAP_TYPE Screen
|
||||||
*UVW_U_OFFSET 0.000000
|
*UVW_U_OFFSET 0.000000
|
||||||
*UVW_V_OFFSET 0.000000
|
*UVW_V_OFFSET 0.000000
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
*MAP_CLASS "Bitmap"
|
*MAP_CLASS "Bitmap"
|
||||||
*MAP_SUBNO 1
|
*MAP_SUBNO 1
|
||||||
*MAP_AMOUNT 1.0000
|
*MAP_AMOUNT 1.0000
|
||||||
*BITMAP "../3DS/m_rifl.bmp"
|
*BITMAP "m_rifl.bmp"
|
||||||
*MAP_TYPE Screen
|
*MAP_TYPE Screen
|
||||||
*UVW_U_OFFSET 0.000000
|
*UVW_U_OFFSET 0.000000
|
||||||
*UVW_V_OFFSET 0.000000
|
*UVW_V_OFFSET 0.000000
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 192 KiB |
Binary file not shown.
After Width: | Height: | Size: 192 KiB |
Binary file not shown.
After Width: | Height: | Size: 192 KiB |
|
@ -4,4 +4,4 @@ Ka 0.588235 0.588235 0.588235
|
||||||
Ks 0.898039 0.898039 0.898039
|
Ks 0.898039 0.898039 0.898039
|
||||||
Ns 128
|
Ns 128
|
||||||
Tr 0
|
Tr 0
|
||||||
map_Kd ./../3DS/m_rifl.bmp
|
map_Kd m_rifl.bmp
|
||||||
|
|
|
@ -10,7 +10,7 @@ OBJECT poly
|
||||||
name "sphere"
|
name "sphere"
|
||||||
subdiv 3
|
subdiv 3
|
||||||
loc -0.0624103 -0.012381 0.0558408
|
loc -0.0624103 -0.012381 0.0558408
|
||||||
texture "./../LWO/LWO2/MappingModes/earthSpherical.jpg"
|
texture "earthSpherical.jpg"
|
||||||
crease 45.000000
|
crease 45.000000
|
||||||
numvert 134
|
numvert 134
|
||||||
-0.00202139 0.0563461 0
|
-0.00202139 0.0563461 0
|
||||||
|
|
|
@ -10,7 +10,7 @@ OBJECT poly
|
||||||
name "sphere"
|
name "sphere"
|
||||||
subdiv 4
|
subdiv 4
|
||||||
loc -0.0624103 -0.012381 0.0558408
|
loc -0.0624103 -0.012381 0.0558408
|
||||||
texture "./../LWO/LWO2/MappingModes/earthSpherical.jpg"
|
texture "earthSpherical.jpg"
|
||||||
texrep 1.9 2.5
|
texrep 1.9 2.5
|
||||||
texoff 0.019 0.5
|
texoff 0.019 0.5
|
||||||
crease 45.000000
|
crease 45.000000
|
||||||
|
|
Binary file not shown.
|
@ -9,7 +9,7 @@ kids 0
|
||||||
OBJECT poly
|
OBJECT poly
|
||||||
name "ä¸ĺ›˝čŹś"
|
name "ä¸ĺ›˝čŹś"
|
||||||
loc -0.0624103 -0.012381 0.0558408
|
loc -0.0624103 -0.012381 0.0558408
|
||||||
texture "./../LWO/LWO2/MappingModes/earthSpherical.jpg"
|
texture "earthSpherical.jpg"
|
||||||
crease 45.000000
|
crease 45.000000
|
||||||
numvert 134
|
numvert 134
|
||||||
-0.00202139 0.0563461 0
|
-0.00202139 0.0563461 0
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 412 KiB |
|
@ -329,7 +329,7 @@
|
||||||
<enum name="AutomaticCulling" value="box" />
|
<enum name="AutomaticCulling" value="box" />
|
||||||
<int name="DebugDataVisible" value="0" />
|
<int name="DebugDataVisible" value="0" />
|
||||||
<bool name="IsDebugObject" value="false" />
|
<bool name="IsDebugObject" value="false" />
|
||||||
<string name="Mesh" value="../X/dwarf.x" />
|
<string name="Mesh" value="dwarf.x" />
|
||||||
<bool name="Looping" value="true" />
|
<bool name="Looping" value="true" />
|
||||||
<bool name="ReadOnlyMaterials" value="false" />
|
<bool name="ReadOnlyMaterials" value="false" />
|
||||||
<float name="FramesPerSecond" value="0.250000" />
|
<float name="FramesPerSecond" value="0.250000" />
|
||||||
|
@ -345,7 +345,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/axe.jpg" />
|
<texture name="Texture1" value="axe.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -384,7 +384,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/dwarf.jpg" />
|
<texture name="Texture1" value="dwarf.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -468,7 +468,7 @@
|
||||||
<enum name="AutomaticCulling" value="box" />
|
<enum name="AutomaticCulling" value="box" />
|
||||||
<int name="DebugDataVisible" value="0" />
|
<int name="DebugDataVisible" value="0" />
|
||||||
<bool name="IsDebugObject" value="false" />
|
<bool name="IsDebugObject" value="false" />
|
||||||
<string name="Mesh" value="../X/dwarf.x" />
|
<string name="Mesh" value="dwarf.x" />
|
||||||
<bool name="Looping" value="true" />
|
<bool name="Looping" value="true" />
|
||||||
<bool name="ReadOnlyMaterials" value="false" />
|
<bool name="ReadOnlyMaterials" value="false" />
|
||||||
<float name="FramesPerSecond" value="0.250000" />
|
<float name="FramesPerSecond" value="0.250000" />
|
||||||
|
@ -484,7 +484,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/axe.jpg" />
|
<texture name="Texture1" value="axe.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -523,7 +523,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/dwarf.jpg" />
|
<texture name="Texture1" value="dwarf.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -723,7 +723,7 @@
|
||||||
<enum name="AutomaticCulling" value="box" />
|
<enum name="AutomaticCulling" value="box" />
|
||||||
<int name="DebugDataVisible" value="0" />
|
<int name="DebugDataVisible" value="0" />
|
||||||
<bool name="IsDebugObject" value="false" />
|
<bool name="IsDebugObject" value="false" />
|
||||||
<string name="Mesh" value="../X/dwarf.x" />
|
<string name="Mesh" value="dwarf.x" />
|
||||||
<bool name="Looping" value="true" />
|
<bool name="Looping" value="true" />
|
||||||
<bool name="ReadOnlyMaterials" value="false" />
|
<bool name="ReadOnlyMaterials" value="false" />
|
||||||
<float name="FramesPerSecond" value="0.250000" />
|
<float name="FramesPerSecond" value="0.250000" />
|
||||||
|
@ -739,7 +739,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/axe.jpg" />
|
<texture name="Texture1" value="axe.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -778,7 +778,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/dwarf.jpg" />
|
<texture name="Texture1" value="dwarf.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -920,7 +920,7 @@
|
||||||
<enum name="AutomaticCulling" value="box" />
|
<enum name="AutomaticCulling" value="box" />
|
||||||
<int name="DebugDataVisible" value="0" />
|
<int name="DebugDataVisible" value="0" />
|
||||||
<bool name="IsDebugObject" value="false" />
|
<bool name="IsDebugObject" value="false" />
|
||||||
<string name="Mesh" value="../X/dwarf.x" />
|
<string name="Mesh" value="dwarf.x" />
|
||||||
<bool name="Looping" value="true" />
|
<bool name="Looping" value="true" />
|
||||||
<bool name="ReadOnlyMaterials" value="false" />
|
<bool name="ReadOnlyMaterials" value="false" />
|
||||||
<float name="FramesPerSecond" value="0.250000" />
|
<float name="FramesPerSecond" value="0.250000" />
|
||||||
|
@ -936,7 +936,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/axe.jpg" />
|
<texture name="Texture1" value="axe.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
@ -975,7 +975,7 @@
|
||||||
<float name="Shininess" value="0.000000" />
|
<float name="Shininess" value="0.000000" />
|
||||||
<float name="Param1" value="0.000000" />
|
<float name="Param1" value="0.000000" />
|
||||||
<float name="Param2" value="0.000000" />
|
<float name="Param2" value="0.000000" />
|
||||||
<texture name="Texture1" value="../X/dwarf.jpg" />
|
<texture name="Texture1" value="dwarf.jpg" />
|
||||||
<texture name="Texture2" value="" />
|
<texture name="Texture2" value="" />
|
||||||
<texture name="Texture3" value="" />
|
<texture name="Texture3" value="" />
|
||||||
<texture name="Texture4" value="" />
|
<texture name="Texture4" value="" />
|
||||||
|
|
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue