Merge branch 'master' into patch-1

pull/5305/head
Kim Kulling 2023-11-16 08:51:13 +01:00 committed by GitHub
commit 6b80f78623
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
93 changed files with 1120 additions and 1212 deletions

View File

@ -52,9 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cctype> #include <cctype>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
static const unsigned int NotSet = 0xcdcdcdcd; static constexpr unsigned int NotSet = 0xcdcdcdcd;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup final material indices, generae a default material if necessary // Setup final material indices, generae a default material if necessary
@ -68,7 +68,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
unsigned int idx(NotSet); unsigned int idx(NotSet);
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) { for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
std::string s = mScene->mMaterials[i].mName; std::string s = mScene->mMaterials[i].mName;
for (char & it : s) { for (char &it : s) {
it = static_cast<char>(::tolower(static_cast<unsigned char>(it))); it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
} }
@ -262,7 +262,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
unsigned int iWire = 1; unsigned int iWire = 1;
mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME); mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
} }
[[fallthrough]]; [[fallthrough]];
case D3DS::Discreet3DS::Gouraud: case D3DS::Discreet3DS::Gouraud:
eShading = aiShadingMode_Gouraud; eShading = aiShadingMode_Gouraud;
@ -805,4 +805,6 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -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,
@ -57,8 +56,7 @@ struct aiNode;
struct aiMaterial; struct aiMaterial;
struct aiMesh; struct aiMesh;
namespace Assimp namespace Assimp {
{
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/** /**
@ -88,7 +86,7 @@ private:
std::map<const aiNode*, aiMatrix4x4> trafos; std::map<const aiNode*, aiMatrix4x4> trafos;
typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap; using MeshesByNodeMap = std::multimap<const aiNode*, unsigned int>;
MeshesByNodeMap meshes; MeshesByNodeMap meshes;
}; };

View File

@ -54,9 +54,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Discreet 3DS Importer", "Discreet 3DS Importer",
"", "",
"", "",
@ -103,10 +103,6 @@ Discreet3DSImporter::Discreet3DSImporter() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
Discreet3DSImporter::~Discreet3DSImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -1339,4 +1335,6 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
(void)bGamma; (void)bGamma;
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -59,7 +59,6 @@ struct aiNode;
namespace Assimp { namespace Assimp {
using namespace D3DS; using namespace D3DS;
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
@ -68,7 +67,7 @@ using namespace D3DS;
class Discreet3DSImporter : public BaseImporter { class Discreet3DSImporter : public BaseImporter {
public: public:
Discreet3DSImporter(); Discreet3DSImporter();
~Discreet3DSImporter() override; ~Discreet3DSImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -68,7 +68,7 @@ namespace Assimp {
using namespace D3MF; using namespace D3MF;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"3mf Importer", "3mf Importer",
"", "",
"", "",
@ -81,10 +81,6 @@ static const aiImporterDesc desc = {
"3mf" "3mf"
}; };
D3MFImporter::D3MFImporter() = default;
D3MFImporter::~D3MFImporter() = default;
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const { bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) { if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
return false; return false;

View File

@ -56,10 +56,10 @@ namespace Assimp {
class D3MFImporter : public BaseImporter { class D3MFImporter : public BaseImporter {
public: public:
/// @brief The default class constructor. /// @brief The default class constructor.
D3MFImporter(); D3MFImporter() = default;
/// @brief The class destructor. /// @brief The class destructor.
~D3MFImporter() override; ~D3MFImporter() override = default;
/// @brief Performs the data format detection. /// @brief Performs the data format detection.
/// @param pFile The filename to check. /// @param pFile The filename to check.

View File

@ -68,7 +68,7 @@ using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
class OpcPackageRelationshipReader { class OpcPackageRelationshipReader {
public: public:
OpcPackageRelationshipReader(XmlParser &parser) : OpcPackageRelationshipReader(XmlParser &parser) :
m_relationShips() { mRelations() {
XmlNode root = parser.getRootNode(); XmlNode root = parser.getRootNode();
ParseRootNode(root); ParseRootNode(root);
} }
@ -108,13 +108,13 @@ public:
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string(); relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string(); relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
if (validateRels(relPtr)) { if (validateRels(relPtr)) {
m_relationShips.push_back(relPtr); mRelations.push_back(relPtr);
} }
} }
} }
} }
std::vector<OpcPackageRelationshipPtr> m_relationShips; std::vector<OpcPackageRelationshipPtr> mRelations;
}; };
static bool IsEmbeddedTexture( const std::string &filename ) { static bool IsEmbeddedTexture( const std::string &filename ) {
@ -186,9 +186,6 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
D3MFOpcPackage::~D3MFOpcPackage() { D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream); mZipArchive->Close(mRootStream);
delete mZipArchive; delete mZipArchive;
for (auto tex : mEmbeddedTextures) {
delete tex;
}
} }
IOStream *D3MFOpcPackage::RootStream() const { IOStream *D3MFOpcPackage::RootStream() const {
@ -217,11 +214,11 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
OpcPackageRelationshipReader reader(xmlParser); OpcPackageRelationshipReader reader(xmlParser);
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) { auto itr = std::find_if(reader.mRelations.begin(), reader.mRelations.end(), [](const OpcPackageRelationshipPtr &rel) {
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE; return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
}); });
if (itr == reader.m_relationShips.end()) { if (itr == reader.mRelations.end()) {
throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE); throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
} }

View File

@ -49,12 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace D3MF { namespace D3MF {
static const int IdNotSet = -1; static constexpr int IdNotSet = -1;
namespace { namespace {
static const size_t ColRGBA_Len = 9; static constexpr size_t ColRGBA_Len = 9;
static const size_t ColRGB_Len = 7; static constexpr size_t ColRGB_Len = 7;
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1) // format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
bool validateColorString(const char *color) { bool validateColorString(const char *color) {

View File

@ -60,9 +60,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"AC3D Importer", "AC3D Importer",
"", "",
"", "",
@ -862,4 +862,6 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
} }
} }
} // namespace Assimp
#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER #endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER

View File

@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
const aiImporterDesc AMFImporter::Description = { static constexpr aiImporterDesc Description = {
"Additive manufacturing file format(AMF) Importer", "Additive manufacturing file format(AMF) Importer",
"smalcom", "smalcom",
"", "",

View File

@ -98,8 +98,12 @@ namespace Assimp {
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3> /// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
/// ///
class AMFImporter : public BaseImporter { class AMFImporter : public BaseImporter {
private: using AMFMetaDataArray = std::vector<AMFMetadata *>;
struct SPP_Material; // forward declaration using MeshArray = std::vector<aiMesh *>;
using NodeArray = std::vector<aiNode *>;
public:
struct SPP_Material;
/// Data type for post-processing step. More suitable container for part of material's composition. /// Data type for post-processing step. More suitable container for part of material's composition.
struct SPP_Composite { struct SPP_Composite {
@ -107,22 +111,6 @@ private:
std::string Formula; ///< Formula for calculating ratio of \ref Material. std::string Formula; ///< Formula for calculating ratio of \ref Material.
}; };
/// \struct SPP_Material
/// Data type for post-processing step. More suitable container for material.
struct SPP_Material {
std::string ID; ///< Material ID.
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
AMFColor *Color; ///< Color of material.
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
/// Return color calculated for specified coordinate.
/// \param [in] pX - "x" coordinate.
/// \param [in] pY - "y" coordinate.
/// \param [in] pZ - "z" coordinate.
/// \return calculated color.
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
};
/// Data type for post-processing step. More suitable container for texture. /// Data type for post-processing step. More suitable container for texture.
struct SPP_Texture { struct SPP_Texture {
std::string ID; std::string ID;
@ -139,10 +127,52 @@ private:
const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face. const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
}; };
using AMFMetaDataArray = std::vector<AMFMetadata*>; /// Data type for post-processing step. More suitable container for material.
using MeshArray = std::vector<aiMesh*>; struct SPP_Material {
using NodeArray = std::vector<aiNode*>; std::string ID; ///< Material ID.
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
AMFColor *Color; ///< Color of material.
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
/// Return color calculated for specified coordinate.
/// \param [in] pX - "x" coordinate.
/// \param [in] pY - "y" coordinate.
/// \param [in] pZ - "z" coordinate.
/// \return calculated color.
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
};
/// Default constructor.
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter() override;
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be thrown if trouble will found.
/// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
const aiImporterDesc *GetInfo() const override;
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_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter &operator=(const AMFImporter &pScene) = delete;
private:
/// Clear all temporary data. /// Clear all temporary data.
void Clear(); void Clear();
@ -262,40 +292,9 @@ private:
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>. /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false); void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
public:
/// Default constructor.
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter() override;
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
/// Also exception can be thrown if trouble will found.
/// \param [in] pFile - name of file to be parsed.
/// \param [in] pIOHandler - pointer to IO helper object.
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
const aiImporterDesc *GetInfo() const override;
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_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter &operator=(const AMFImporter &pScene) = delete;
private: private:
static const aiImporterDesc Description;
AMFNodeElementBase *mNodeElement_Cur; ///< Current element. AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph. std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
XmlParser *mXmlParser; XmlParser *mXmlParser;

View File

@ -63,10 +63,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// utilities // utilities
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
using namespace Assimp; namespace Assimp {
using namespace Assimp::ASE; using namespace Assimp::ASE;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"ASE Importer", "ASE Importer",
"", "",
"", "",
@ -1262,6 +1262,8 @@ bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) {
return false; return false;
} }
}
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER #endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER #endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

View File

@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
using namespace Assimp; namespace Assimp {
using namespace Assimp::ASE; using namespace Assimp::ASE;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1864,6 +1864,8 @@ void Parser::ParseLV4MeshLong(unsigned int &iOut) {
iOut = strtoul10(filePtr, &filePtr); iOut = strtoul10(filePtr, &filePtr);
} }
}
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER #endif // ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER #endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

View File

@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Assimp Binary Importer", "Assimp Binary Importer",
"Gargaj / Conspiracy", "Gargaj / Conspiracy",
"", "",

View File

@ -59,10 +59,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
using namespace std; using namespace std;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"BlitzBasic 3D Importer", "BlitzBasic 3D Importer",
"", "",
"", "",
@ -79,9 +79,9 @@ static const aiImporterDesc desc = {
#pragma warning(disable : 4018) #pragma warning(disable : 4018)
#endif #endif
//#define DEBUG_B3D // #define DEBUG_B3D
template<typename T> template <typename T>
void DeleteAllBarePointers(std::vector<T> &x) { void DeleteAllBarePointers(std::vector<T> &x) {
for (auto p : x) { for (auto p : x) {
delete p; delete p;
@ -329,7 +329,7 @@ void B3DImporter::ReadBRUS() {
mat->AddProperty(&i, 1, AI_MATKEY_TWOSIDED); mat->AddProperty(&i, 1, AI_MATKEY_TWOSIDED);
} }
//Textures // Textures
for (int i = 0; i < n_texs; ++i) { for (int i = 0; i < n_texs; ++i) {
int texid = ReadInt(); int texid = ReadInt();
if (texid < -1 || (texid >= 0 && texid >= static_cast<int>(_textures.size()))) { if (texid < -1 || (texid >= 0 && texid >= static_cast<int>(_textures.size()))) {
@ -372,7 +372,7 @@ void B3DImporter::ReadVRTS() {
} }
if (_vflags & 2) { if (_vflags & 2) {
ReadQuat(); //skip v 4bytes... ReadQuat(); // skip v 4bytes...
} }
for (int j = 0; j < _tcsets; ++j) { for (int j = 0; j < _tcsets; ++j) {
@ -704,22 +704,22 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
} }
} }
//nodes // nodes
scene->mRootNode = _nodes[0]; scene->mRootNode = _nodes[0];
_nodes.clear(); // node ownership now belongs to scene _nodes.clear(); // node ownership now belongs to scene
//material // material
if (!_materials.size()) { if (!_materials.size()) {
_materials.emplace_back(std::unique_ptr<aiMaterial>(new aiMaterial)); _materials.emplace_back(std::unique_ptr<aiMaterial>(new aiMaterial));
} }
scene->mNumMaterials = static_cast<unsigned int>(_materials.size()); scene->mNumMaterials = static_cast<unsigned int>(_materials.size());
scene->mMaterials = unique_to_array(_materials); scene->mMaterials = unique_to_array(_materials);
//meshes // meshes
scene->mNumMeshes = static_cast<unsigned int>(_meshes.size()); scene->mNumMeshes = static_cast<unsigned int>(_meshes.size());
scene->mMeshes = unique_to_array(_meshes); scene->mMeshes = unique_to_array(_meshes);
//animations // animations
if (_animations.size() == 1 && _nodeAnims.size()) { if (_animations.size() == 1 && _nodeAnims.size()) {
aiAnimation *anim = _animations.back().get(); aiAnimation *anim = _animations.back().get();
@ -738,4 +738,6 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
flip.Execute(scene); flip.Execute(scene);
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER #endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER

View File

@ -55,10 +55,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map> #include <map>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"BVH Importer (MoCap)", "BVH Importer (MoCap)",
"", "",
"", "",
@ -73,8 +74,8 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Aborts the file reading with an exception // Aborts the file reading with an exception
template<typename... T> template <typename... T>
AI_WONT_RETURN void BVHLoader::ThrowException(T&&... args) { AI_WONT_RETURN void BVHLoader::ThrowException(T &&...args) {
throw DeadlyImportError(mFileName, ":", mLine, " - ", args...); throw DeadlyImportError(mFileName, ":", mLine, " - ", args...);
} }
@ -426,7 +427,7 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
nodeAnim->mNodeName.Set(nodeName); nodeAnim->mNodeName.Set(nodeName);
std::map<BVHLoader::ChannelType, int> channelMap; std::map<BVHLoader::ChannelType, int> channelMap;
//Build map of channels // Build map of channels
for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel) { for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel) {
channelMap[node.mChannels[channel]] = channel; channelMap[node.mChannels[channel]] = channel;
} }
@ -441,7 +442,7 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
// Now compute all translations // Now compute all translations
for (BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel + 1)) { for (BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel + 1)) {
//Find channel in node // Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel); std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
if (mapIter == channelMap.end()) if (mapIter == channelMap.end())
@ -485,30 +486,27 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) { for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) {
aiMatrix4x4 temp; aiMatrix4x4 temp;
aiMatrix3x3 rotMatrix; aiMatrix3x3 rotMatrix;
for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++ channelIdx) { for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++channelIdx) {
switch (node.mChannels[channelIdx]) { switch (node.mChannels[channelIdx]) {
case Channel_RotationX: case Channel_RotationX: {
{
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); aiMatrix4x4::RotationX(angle, temp);
} rotMatrix *= aiMatrix3x3(temp);
break; } break;
case Channel_RotationY: case Channel_RotationY: {
{
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); aiMatrix4x4::RotationY(angle, temp);
} rotMatrix *= aiMatrix3x3(temp);
break; } break;
case Channel_RotationZ: case Channel_RotationZ: {
{
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); aiMatrix4x4::RotationZ(angle, temp);
} rotMatrix *= aiMatrix3x3(temp);
break; } break;
default: default:
break; break;
} }
} }
rotkey->mTime = double(fr); rotkey->mTime = double(fr);
rotkey->mValue = aiQuaternion(rotMatrix); rotkey->mValue = aiQuaternion(rotMatrix);
++rotkey; ++rotkey;
@ -525,4 +523,6 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER #endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER

View File

@ -69,11 +69,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// zlib is needed for compressed blend files // zlib is needed for compressed blend files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND #ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
#include "Common/Compression.h" #include "Common/Compression.h"
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
# else
# include "../contrib/zlib/zlib.h"
# endif*/
#endif #endif
namespace Assimp { namespace Assimp {
@ -89,7 +84,7 @@ using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static const aiImporterDesc blenderDesc = { static constexpr aiImporterDesc blenderDesc = {
"Blender 3D Importer (http://www.blender3d.org)", "Blender 3D Importer (http://www.blender3d.org)",
"", "",
"", "",

View File

@ -61,11 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
using namespace Assimp::COB; using namespace Assimp::COB;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static const float units[] = { static constexpr float units[] = {
1000.f, 1000.f,
100.f, 100.f,
1.f, 1.f,
@ -76,7 +76,7 @@ static const float units[] = {
1.f / 1609.344f 1.f / 1609.344f
}; };
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"TrueSpace Object Importer", "TrueSpace Object Importer",
"", "",
"", "",
@ -89,14 +89,6 @@ static const aiImporterDesc desc = {
"cob scn" "cob scn"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
COBImporter::COBImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
COBImporter::~COBImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -1172,4 +1164,6 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist"); ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
} }
}
#endif // ASSIMP_BUILD_NO_COB_IMPORTER #endif // ASSIMP_BUILD_NO_COB_IMPORTER

View File

@ -56,16 +56,16 @@ class LineSplitter;
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T, typename TR, typename A> template <typename T, typename TR, typename A>
class basic_formatter; class basic_formatter;
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format; typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
} // namespace Formatter } // namespace Formatter
// COBScene.h // COBScene.h
namespace COB { namespace COB {
struct ChunkInfo; struct ChunkInfo;
struct Node; struct Node;
struct Scene; struct Scene;
} // namespace COB } // namespace COB
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
@ -75,8 +75,8 @@ struct Scene;
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter { class COBImporter : public BaseImporter {
public: public:
COBImporter(); COBImporter() = default;
~COBImporter() override; ~COBImporter() override = default;
// -------------------- // --------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,

View File

@ -44,9 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file CSMLoader.cpp /** @file CSMLoader.cpp
* Implementation of the CSM importer class. * Implementation of the CSM importer class.
*/ */
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
#include "CSMLoader.h" #include "CSMLoader.h"
@ -63,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"CharacterStudio Motion Importer (MoCap)", "CharacterStudio Motion Importer (MoCap)",
"", "",
"", "",
@ -79,13 +76,9 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
CSMImporter::CSMImporter() CSMImporter::CSMImporter() : noSkeletonMesh(){
: noSkeletonMesh() // empty
{} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
CSMImporter::~CSMImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.

View File

@ -61,7 +61,7 @@ namespace Assimp {
class CSMImporter : public BaseImporter { class CSMImporter : public BaseImporter {
public: public:
CSMImporter(); CSMImporter();
~CSMImporter() override; ~CSMImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
@ -81,9 +81,8 @@ protected:
private: private:
bool noSkeletonMesh; bool noSkeletonMesh;
}; // end of class CSMImporter };
} // end of namespace Assimp } // namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC #endif // AI_AC3DIMPORTER_H_INC

View File

@ -64,7 +64,7 @@ namespace Assimp {
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
using namespace Assimp::Collada; using namespace Assimp::Collada;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Collada Importer", "Collada Importer",
"", "",
"", "",
@ -101,10 +101,6 @@ ColladaLoader::ColladaLoader() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
ColladaLoader::~ColladaLoader() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {

View File

@ -86,7 +86,7 @@ public:
ColladaLoader(); ColladaLoader();
/// The class destructor. /// The class destructor.
~ColladaLoader() override; ~ColladaLoader() override = default;
/// Returns whether the class can handle the format of the given file. /// Returns whether the class can handle the format of the given file.
/// @see BaseImporter::CanRead() for more details. /// @see BaseImporter::CanRead() for more details.

View File

@ -814,38 +814,38 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
if (!pImage.mFileName.length()) { if (!pImage.mFileName.length()) {
pImage.mFileName = "unknown_texture"; pImage.mFileName = "unknown_texture";
} }
} } else if (mFormat == FV_1_5_n) {
} else if (mFormat == FV_1_5_n) { std::string value;
std::string value; XmlNode refChild = currentNode.child("ref");
XmlNode refChild = currentNode.child("ref"); XmlNode hexChild = currentNode.child("hex");
XmlNode hexChild = currentNode.child("hex"); if (refChild) {
if (refChild) { // element content is filename - hopefully
// element content is filename - hopefully if (XmlParser::getValueAsString(refChild, value)) {
if (XmlParser::getValueAsString(refChild, value)) { aiString filepath(value);
aiString filepath(value); UriDecodePath(filepath);
UriDecodePath(filepath); pImage.mFileName = filepath.C_Str();
pImage.mFileName = filepath.C_Str(); }
} } else if (hexChild && !pImage.mFileName.length()) {
} else if (hexChild && !pImage.mFileName.length()) { // embedded image. get format
// embedded image. get format pImage.mEmbeddedFormat = hexChild.attribute("format").as_string();
pImage.mEmbeddedFormat = hexChild.attribute("format").as_string(); if (pImage.mEmbeddedFormat.empty()) {
if (pImage.mEmbeddedFormat.empty()) { ASSIMP_LOG_WARN("Collada: Unknown image file format");
ASSIMP_LOG_WARN("Collada: Unknown image file format"); }
}
XmlParser::getValueAsString(hexChild, value); XmlParser::getValueAsString(hexChild, value);
const char *data = value.c_str(); const char *data = value.c_str();
// hexadecimal-encoded binary octets. First of all, find the // hexadecimal-encoded binary octets. First of all, find the
// required buffer size to reserve enough storage. // required buffer size to reserve enough storage.
const char *cur = data; const char *cur = data;
while (!IsSpaceOrNewLine(*cur)) { while (!IsSpaceOrNewLine(*cur)) {
++cur; ++cur;
} }
const unsigned int size = (unsigned int)(cur - data) * 2; const unsigned int size = (unsigned int)(cur - data) * 2;
pImage.mImageData.resize(size); pImage.mImageData.resize(size);
for (unsigned int i = 0; i < size; ++i) { for (unsigned int i = 0; i < size; ++i) {
pImage.mImageData[i] = HexOctetToDecimal(data + (i << 1)); pImage.mImageData[i] = HexOctetToDecimal(data + (i << 1));
}
} }
} }
} }
@ -1274,9 +1274,7 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
return; return;
} }
XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode); for (XmlNode &currentNode : node.children()) {
XmlNode currentNode;
while (xmlIt.getNext(currentNode)) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "surface") { if (currentName == "surface") {
// image ID given inside <init_from> tags // image ID given inside <init_from> tags
@ -1289,22 +1287,24 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
} }
} else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) { } else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
// surface ID is given inside <source> tags // surface ID is given inside <source> tags
const char *content = currentNode.value(); XmlNode source = currentNode.child("source");
pParam.mType = Param_Sampler; if (source) {
pParam.mReference = content; std::string v;
XmlParser::getValueAsString(source, v);
pParam.mType = Param_Sampler;
pParam.mReference = v.c_str();
}
} else if (currentName == "sampler2D") { } else if (currentName == "sampler2D") {
// surface ID is given inside <instance_image> tags // surface ID is given inside <instance_image> tags
std::string url; XmlNode instance_image = currentNode.child("instance_image");
XmlParser::getStdStrAttribute(currentNode, "url", url); if (instance_image) {
if (url[0] != '#') { std::string url;
throw DeadlyImportError("Unsupported URL format in instance_image"); XmlParser::getStdStrAttribute(instance_image, "url", url);
} if (url[0] != '#') {
pParam.mType = Param_Sampler; throw DeadlyImportError("Unsupported URL format in instance_image");
pParam.mReference = url.c_str() + 1; }
} else if (currentName == "source") { pParam.mType = Param_Sampler;
const char *source = currentNode.child_value(); pParam.mReference = url.c_str() + 1;
if (nullptr != source) {
pParam.mReference = source;
} }
} }
} }

View File

@ -70,7 +70,7 @@ static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
// color indices for DXF - 16 are supported, the table is // color indices for DXF - 16 are supported, the table is
// taken directly from the DXF spec. // taken directly from the DXF spec.
static aiColor4D g_aclrDxfIndexColors[] = { static const aiColor4D g_aclrDxfIndexColors[] = {
aiColor4D(0.6f, 0.6f, 0.6f, 1.0f), aiColor4D(0.6f, 0.6f, 0.6f, 1.0f),
aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
@ -97,7 +97,7 @@ static const int GroupCode_XComp = 10;
static const int GroupCode_YComp = 20; static const int GroupCode_YComp = 20;
static const int GroupCode_ZComp = 30; static const int GroupCode_ZComp = 30;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Drawing Interchange Format (DXF) Importer", "Drawing Interchange Format (DXF) Importer",
"", "",
"", "",

View File

@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXUtil.h" #include "FBXUtil.h"
#include <assimp/defs.h> #include <assimp/defs.h>
#include <stdint.h> #include <stdint.h>
#include <cstdint>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>

View File

@ -577,16 +577,17 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
bool is_id[3] = { true, true, true }; bool is_id[3] = { true, true, true };
aiMatrix4x4 temp[3]; aiMatrix4x4 temp[3];
if (std::fabs(rotation.z) > angle_epsilon) { const auto rot = AI_DEG_TO_RAD(rotation);
aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z), temp[2]); if (std::fabs(rot.z) > angle_epsilon) {
aiMatrix4x4::RotationZ(rot.z, temp[2]);
is_id[2] = false; is_id[2] = false;
} }
if (std::fabs(rotation.y) > angle_epsilon) { if (std::fabs(rot.y) > angle_epsilon) {
aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y), temp[1]); aiMatrix4x4::RotationY(rot.y, temp[1]);
is_id[1] = false; is_id[1] = false;
} }
if (std::fabs(rotation.x) > angle_epsilon) { if (std::fabs(rot.x) > angle_epsilon) {
aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x), temp[0]); aiMatrix4x4::RotationX(rot.x, temp[0]);
is_id[0] = false; is_id[0] = false;
} }
@ -3225,7 +3226,6 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f)); aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f)); aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f)); aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
aiVectorKey* outTranslations = new aiVectorKey[keyCount]; aiVectorKey* outTranslations = new aiVectorKey[keyCount];
aiQuatKey* outRotations = new aiQuatKey[keyCount]; aiQuatKey* outRotations = new aiQuatKey[keyCount];
@ -3241,8 +3241,9 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
} }
if (keyframeLists[TransformationComp_Rotation].size() > 0) { if (keyframeLists[TransformationComp_Rotation].size() > 0) {
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder); InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], AI_DEG_TO_RAD(defRotation), maxTime, minTime, rotOrder);
} else { } else {
aiQuaternion defQuat = EulerToQuaternion(AI_DEG_TO_RAD(defRotation), rotOrder);
for (size_t i = 0; i < keyCount; ++i) { for (size_t i = 0; i < keyCount; ++i) {
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps; outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
outRotations[i].mValue = defQuat; outRotations[i].mValue = defQuat;
@ -3264,7 +3265,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok); const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
if (ok && preRotation.SquareLength() > zero_epsilon) { if (ok && preRotation.SquareLength() > zero_epsilon) {
const aiQuaternion preQuat = EulerToQuaternion(preRotation, Model::RotOrder_EulerXYZ); const aiQuaternion preQuat = EulerToQuaternion(AI_DEG_TO_RAD(preRotation), Model::RotOrder_EulerXYZ);
for (size_t i = 0; i < keyCount; ++i) { for (size_t i = 0; i < keyCount; ++i) {
outRotations[i].mValue = preQuat * outRotations[i].mValue; outRotations[i].mValue = preQuat * outRotations[i].mValue;
} }
@ -3272,7 +3273,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
const aiVector3D& postRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok); const aiVector3D& postRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
if (ok && postRotation.SquareLength() > zero_epsilon) { if (ok && postRotation.SquareLength() > zero_epsilon) {
const aiQuaternion postQuat = EulerToQuaternion(postRotation, Model::RotOrder_EulerXYZ); const aiQuaternion postQuat = EulerToQuaternion(AI_DEG_TO_RAD(postRotation), Model::RotOrder_EulerXYZ);
for (size_t i = 0; i < keyCount; ++i) { for (size_t i = 0; i < keyCount; ++i) {
outRotations[i].mValue = outRotations[i].mValue * postQuat; outRotations[i].mValue = outRotations[i].mValue * postQuat;
} }

View File

@ -74,8 +74,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// https://code.blender.org/2013/08/fbx-binary-file-format-specification/ // https://code.blender.org/2013/08/fbx-binary-file-format-specification/
// https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure // https://wiki.blender.org/index.php/User:Mont29/Foundation/FBX_File_Structure
const ai_real DEG = ai_real( 57.29577951308232087679815481 ); // degrees per radian
using namespace Assimp; using namespace Assimp;
using namespace Assimp::FBX; using namespace Assimp::FBX;
@ -2434,7 +2432,7 @@ void FBXExporter::WriteObjects ()
aiMatrix4x4 m(k.mValue.GetMatrix()); aiMatrix4x4 m(k.mValue.GetMatrix());
aiVector3D qs, qr, qt; aiVector3D qs, qr, qt;
m.Decompose(qs, qr, qt); m.Decompose(qs, qr, qt);
qr *= DEG; qr = AI_RAD_TO_DEG(qr);
xval.push_back(qr.x); xval.push_back(qr.x);
yval.push_back(qr.y); yval.push_back(qr.y);
zval.push_back(qr.z); zval.push_back(qr.z);
@ -2515,9 +2513,10 @@ void FBXExporter::WriteModelNode(
); );
} }
if (r != zero) { if (r != zero) {
r = AI_RAD_TO_DEG(r);
p.AddP70( p.AddP70(
"Lcl Rotation", "Lcl Rotation", "", "A", "Lcl Rotation", "Lcl Rotation", "", "A",
double(DEG*r.x), double(DEG*r.y), double(DEG*r.z) double(r.x), double(r.y), double(r.z)
); );
} }
if (s != one) { if (s != one) {
@ -2601,8 +2600,7 @@ void FBXExporter::WriteModelNodes(
transform_chain.emplace_back(elem->first, t); transform_chain.emplace_back(elem->first, t);
break; break;
case 'r': // rotation case 'r': // rotation
r *= float(DEG); transform_chain.emplace_back(elem->first, AI_RAD_TO_DEG(r));
transform_chain.emplace_back(elem->first, r);
break; break;
case 's': // scale case 's': // scale
transform_chain.emplace_back(elem->first, s); transform_chain.emplace_back(elem->first, s);

View File

@ -72,30 +72,25 @@ using namespace Assimp::Formatter;
using namespace Assimp::FBX; using namespace Assimp::FBX;
namespace { namespace {
static constexpr aiImporterDesc desc = {
static const aiImporterDesc desc = { "Autodesk FBX Importer",
"Autodesk FBX Importer", "",
"", "",
"", "",
"", aiImporterFlags_SupportTextFlavour,
aiImporterFlags_SupportTextFlavour, 0,
0, 0,
0, 0,
0, 0,
0, "fbx"
"fbx" };
};
} }
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by #Importer
FBXImporter::FBXImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const { bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
static const char *tokens[] = { "fbx" }; static const char *tokens[] = { " \n\r\n " };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
} }

View File

@ -70,7 +70,7 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> { class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
public: public:
/// @brief The class constructor. /// @brief The class constructor.
FBXImporter(); FBXImporter() = default;
/// @brief The class destructor, default implementation. /// @brief The class destructor, default implementation.
~FBXImporter() override = default; ~FBXImporter() override = default;

View File

@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"3D GameStudio Heightmap (HMP) Importer", "3D GameStudio Heightmap (HMP) Importer",
"", "",
"", "",

View File

@ -103,7 +103,7 @@ void ConvertUnit(const ::Assimp::STEP::EXPRESS::DataType &dt, ConversionData &co
} // namespace } // namespace
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Industry Foundation Classes (IFC) Importer", "Industry Foundation Classes (IFC) Importer",
"", "",
"", "",
@ -185,7 +185,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
size_t total = 0; size_t total = 0;
int read = 0; int read = 0;
do { do {
int bufferSize = fileInfo.uncompressed_size < INT16_MAX ? fileInfo.uncompressed_size : INT16_MAX; unsigned bufferSize = fileInfo.uncompressed_size < INT16_MAX ? static_cast<unsigned>(fileInfo.uncompressed_size) : INT16_MAX;
void *buffer = malloc(bufferSize); void *buffer = malloc(bufferSize);
read = unzReadCurrentFile(zip, buffer, bufferSize); read = unzReadCurrentFile(zip, buffer, bufferSize);
if (read > 0) { if (read > 0) {

View File

@ -59,7 +59,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// http://sauerbraten.org/iqm/ // http://sauerbraten.org/iqm/
// https://github.com/lsalzman/iqm // https://github.com/lsalzman/iqm
inline void swap_block( uint32_t *block, size_t size ){ inline void swap_block( uint32_t *block, size_t size ){
(void)block; // suppress 'unreferenced formal parameter' MSVC warning (void)block; // suppress 'unreferenced formal parameter' MSVC warning
size >>= 2; size >>= 2;
@ -67,7 +66,7 @@ inline void swap_block( uint32_t *block, size_t size ){
AI_SWAP4( block[ i ] ); AI_SWAP4( block[ i ] );
} }
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Inter-Quake Model Importer", "Inter-Quake Model Importer",
"", "",
"", "",
@ -100,13 +99,6 @@ bool IQMImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
if (!pIOHandler) { if (!pIOHandler) {
return true; return true;
} }
/*
* don't use CheckMagicToken because that checks with swapped bytes too, leading to false
* positives. This magic is not uint32_t, but char[4], so memcmp is the best way
const char* tokens[] = {"3DMO", "3dmo"};
return CheckMagicToken(pIOHandler,pFile,tokens,2,0,4);
*/
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
unsigned char data[15]; unsigned char data[15];
if (!pStream || 15 != pStream->Read(data, 1, 15)) { if (!pStream || 15 != pStream->Read(data, 1, 15)) {

View File

@ -66,7 +66,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Irrlicht Scene Reader", "Irrlicht Scene Reader",
"", "",
"", "",

View File

@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Irrlicht Mesh Reader", "Irrlicht Mesh Reader",
"", "",
"", "",

View File

@ -51,64 +51,56 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "LWOLoader.h" #include "LWOLoader.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOBFile() void LWOImporter::LoadLWOBFile() {
{
LE_NCONST uint8_t* const end = mFileBuffer + fileSize; LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
bool running = true; bool running = true;
while (running) while (running) {
{ if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break; break;
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer); const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
if (mFileBuffer + head.length > end) if (mFileBuffer + head.length > end) {
{
throw DeadlyImportError("LWOB: Invalid chunk length"); throw DeadlyImportError("LWOB: Invalid chunk length");
} }
uint8_t* const next = mFileBuffer+head.length; uint8_t* const next = mFileBuffer+head.length;
switch (head.type) switch (head.type) {
{
// vertex list // vertex list
case AI_LWO_PNTS: case AI_LWO_PNTS: {
{
if (!mCurLayer->mTempPoints.empty()) if (!mCurLayer->mTempPoints.empty())
ASSIMP_LOG_WARN("LWO: PNTS chunk encountered twice"); ASSIMP_LOG_WARN("LWO: PNTS chunk encountered twice");
else LoadLWOPoints(head.length); else
break; LoadLWOPoints(head.length);
} } break;
// face list case AI_LWO_POLS: { // face list
case AI_LWO_POLS: if (!mCurLayer->mFaces.empty())
{ ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice");
else
LoadLWOBPolygons(head.length);
} break;
case AI_LWO_SRFS: // list of tags
{
if (!mTags->empty())
ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
else
LoadLWOTags(head.length);
} break;
if (!mCurLayer->mFaces.empty()) case AI_LWO_SURF: // surface chunk
ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice"); {
else LoadLWOBPolygons(head.length); LoadLWOBSurface(head.length);
break; } break;
}
// list of tags
case AI_LWO_SRFS:
{
if (!mTags->empty())
ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
else LoadLWOTags(head.length);
break;
}
// surface chunk default:
case AI_LWO_SURF:
{
LoadLWOBSurface(head.length);
break; break;
}
} }
mFileBuffer = next; mFileBuffer = next;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOBPolygons(unsigned int length) void LWOImporter::LoadLWOBPolygons(unsigned int length) {
{
// first find out how many faces and vertices we'll finally need // first find out how many faces and vertices we'll finally need
LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length); LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer; LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
@ -123,8 +115,7 @@ void LWOImporter::LoadLWOBPolygons(unsigned int length)
CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end); CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
// allocate the output array and copy face indices // allocate the output array and copy face indices
if (iNumFaces) if (iNumFaces) {
{
cursor = (LE_NCONST uint16_t*)mFileBuffer; cursor = (LE_NCONST uint16_t*)mFileBuffer;
mCurLayer->mFaces.resize(iNumFaces); mCurLayer->mFaces.resize(iNumFaces);
@ -135,10 +126,8 @@ void LWOImporter::LoadLWOBPolygons(unsigned int length)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces, void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max) LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max) {
{ while (cursor < end && max--) {
while (cursor < end && max--)
{
uint16_t numIndices; uint16_t numIndices;
// must have 2 shorts left for numIndices and surface // must have 2 shorts left for numIndices and surface
if (end - cursor < 2) { if (end - cursor < 2) {
@ -154,8 +143,7 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
cursor += numIndices; cursor += numIndices;
int16_t surface; int16_t surface;
::memcpy(&surface, cursor++, 2); ::memcpy(&surface, cursor++, 2);
if (surface < 0) if (surface < 0) {
{
// there are detail polygons // there are detail polygons
::memcpy(&numIndices, cursor++, 2); ::memcpy(&numIndices, cursor++, 2);
CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices); CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
@ -167,18 +155,14 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it, void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
LE_NCONST uint16_t*& cursor, LE_NCONST uint16_t*& cursor,
const uint16_t* const end, const uint16_t* const end,
unsigned int max) unsigned int max) {
{ while (cursor < end && max--) {
while (cursor < end && max--)
{
LWO::Face& face = *it;++it; LWO::Face& face = *it;++it;
uint16_t numIndices; uint16_t numIndices;
::memcpy(&numIndices, cursor++, 2); ::memcpy(&numIndices, cursor++, 2);
face.mNumIndices = numIndices; face.mNumIndices = numIndices;
if(face.mNumIndices) if(face.mNumIndices) {
{ if (cursor + face.mNumIndices >= end) {
if (cursor + face.mNumIndices >= end)
{
break; break;
} }
face.mIndices = new unsigned int[face.mNumIndices]; face.mIndices = new unsigned int[face.mNumIndices];
@ -187,8 +171,7 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
uint16_t index; uint16_t index;
::memcpy(&index, cursor++, 2); ::memcpy(&index, cursor++, 2);
mi = index; mi = index;
if (mi > mCurLayer->mTempPoints.size()) if (mi > mCurLayer->mTempPoints.size()) {
{
ASSIMP_LOG_WARN("LWOB: face index is out of range"); ASSIMP_LOG_WARN("LWOB: face index is out of range");
mi = (unsigned int)mCurLayer->mTempPoints.size()-1; mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
} }
@ -198,15 +181,13 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
} }
int16_t surface; int16_t surface;
::memcpy(&surface, cursor++, 2); ::memcpy(&surface, cursor++, 2);
if (surface < 0) if (surface < 0) {
{
surface = -surface; surface = -surface;
// there are detail polygons. // there are detail polygons.
uint16_t numPolygons; uint16_t numPolygons;
::memcpy(&numPolygons, cursor++, 2); ::memcpy(&numPolygons, cursor++, 2);
if (cursor < end) if (cursor < end) {
{
CopyFaceIndicesLWOB(it,cursor,end,numPolygons); CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
} }
} }
@ -215,8 +196,7 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size) LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size) {
{
list.emplace_back(); list.emplace_back();
LWO::Texture* tex = &list.back(); LWO::Texture* tex = &list.back();
@ -224,8 +204,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
GetS0(type,size); GetS0(type,size);
const char* s = type.c_str(); const char* s = type.c_str();
if(strstr(s, "Image Map")) if(strstr(s, "Image Map")) {
{
// Determine mapping type // Determine mapping type
if(strstr(s, "Planar")) if(strstr(s, "Planar"))
tex->mapMode = LWO::Texture::Planar; tex->mapMode = LWO::Texture::Planar;
@ -237,9 +216,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
tex->mapMode = LWO::Texture::Cubic; tex->mapMode = LWO::Texture::Cubic;
else if(strstr(s, "Front")) else if(strstr(s, "Front"))
tex->mapMode = LWO::Texture::FrontProjection; tex->mapMode = LWO::Texture::FrontProjection;
} } else {
else
{
// procedural or gradient, not supported // procedural or gradient, not supported
ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type); ASSIMP_LOG_ERROR("LWOB: Unsupported legacy texture: ", type);
} }
@ -248,8 +225,7 @@ LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned i
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void LWOImporter::LoadLWOBSurface(unsigned int size) void LWOImporter::LoadLWOBSurface(unsigned int size) {
{
LE_NCONST uint8_t* const end = mFileBuffer + size; LE_NCONST uint8_t* const end = mFileBuffer + size;
mSurfaces->push_back( LWO::Surface () ); mSurfaces->push_back( LWO::Surface () );
@ -277,148 +253,147 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
} }
uint8_t* const next = mFileBuffer+head.length; uint8_t* const next = mFileBuffer+head.length;
switch (head.type) switch (head.type) {
{ // diffuse color
// diffuse color case AI_LWO_COLR:
case AI_LWO_COLR: {
{ AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,3);
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,3); surf.mColor.r = GetU1() / 255.0f;
surf.mColor.r = GetU1() / 255.0f; surf.mColor.g = GetU1() / 255.0f;
surf.mColor.g = GetU1() / 255.0f; surf.mColor.b = GetU1() / 255.0f;
surf.mColor.b = GetU1() / 255.0f; break;
break;
}
// diffuse strength ...
case AI_LWO_DIFF:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,2);
surf.mDiffuseValue = GetU2() / 255.0f;
break;
}
// specular strength ...
case AI_LWO_SPEC:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,2);
surf.mSpecularValue = GetU2() / 255.0f;
break;
}
// luminosity ...
case AI_LWO_LUMI:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LUMI,2);
surf.mLuminosity = GetU2() / 255.0f;
break;
}
// transparency
case AI_LWO_TRAN:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,2);
surf.mTransparency = GetU2() / 255.0f;
break;
}
// surface flags
case AI_LWO_FLAG:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,FLAG,2);
uint16_t flag = GetU2();
if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
if (flag & 0x8 ) surf.mColorHighlights = 1.f;
if (flag & 0x100) surf.bDoubleSided = true;
break;
}
// maximum smoothing angle
case AI_LWO_SMAN:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
surf.mMaximumSmoothAngle = std::fabs( GetF4() );
break;
}
// glossiness
case AI_LWO_GLOS:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,2);
surf.mGlossiness = (float)GetU2();
break;
}
// color texture
case AI_LWO_CTEX:
{
pTex = SetupNewTextureLWOB(surf.mColorTextures,
head.length);
break;
}
// diffuse texture
case AI_LWO_DTEX:
{
pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
head.length);
break;
}
// specular texture
case AI_LWO_STEX:
{
pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
head.length);
break;
}
// bump texture
case AI_LWO_BTEX:
{
pTex = SetupNewTextureLWOB(surf.mBumpTextures,
head.length);
break;
}
// transparency texture
case AI_LWO_TTEX:
{
pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
head.length);
break;
}
// texture path
case AI_LWO_TIMG:
{
if (pTex) {
GetS0(pTex->mFileName,head.length);
} else {
ASSIMP_LOG_WARN("LWOB: Unexpected TIMG chunk");
} }
break; // diffuse strength ...
} case AI_LWO_DIFF:
// texture strength {
case AI_LWO_TVAL: AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,2);
{ surf.mDiffuseValue = GetU2() / 255.0f;
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1); break;
if (pTex) {
pTex->mStrength = (float)GetU1()/ 255.f;
} else {
ASSIMP_LOG_ERROR("LWOB: Unexpected TVAL chunk");
} }
break; // specular strength ...
} case AI_LWO_SPEC:
// texture flags {
case AI_LWO_TFLG: AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,2);
{ surf.mSpecularValue = GetU2() / 255.0f;
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2); break;
}
if (nullptr != pTex) { // luminosity ...
const uint16_t s = GetU2(); case AI_LWO_LUMI:
if (s & 1) {
pTex->majorAxis = LWO::Texture::AXIS_X; AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LUMI,2);
else if (s & 2) surf.mLuminosity = GetU2() / 255.0f;
pTex->majorAxis = LWO::Texture::AXIS_Y; break;
else if (s & 4) }
pTex->majorAxis = LWO::Texture::AXIS_Z; // transparency
case AI_LWO_TRAN:
if (s & 16) { {
ASSIMP_LOG_WARN("LWOB: Ignoring \'negate\' flag on texture"); AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,2);
surf.mTransparency = GetU2() / 255.0f;
break;
}
// surface flags
case AI_LWO_FLAG:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,FLAG,2);
uint16_t flag = GetU2();
if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
if (flag & 0x8 ) surf.mColorHighlights = 1.f;
if (flag & 0x100) surf.bDoubleSided = true;
break;
}
// maximum smoothing angle
case AI_LWO_SMAN:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
surf.mMaximumSmoothAngle = std::fabs( GetF4() );
break;
}
// glossiness
case AI_LWO_GLOS:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,2);
surf.mGlossiness = (float)GetU2();
break;
}
// color texture
case AI_LWO_CTEX:
{
pTex = SetupNewTextureLWOB(surf.mColorTextures,
head.length);
break;
}
// diffuse texture
case AI_LWO_DTEX:
{
pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
head.length);
break;
}
// specular texture
case AI_LWO_STEX:
{
pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
head.length);
break;
}
// bump texture
case AI_LWO_BTEX:
{
pTex = SetupNewTextureLWOB(surf.mBumpTextures,
head.length);
break;
}
// transparency texture
case AI_LWO_TTEX:
{
pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
head.length);
break;
}
// texture path
case AI_LWO_TIMG:
{
if (pTex) {
GetS0(pTex->mFileName,head.length);
} else {
ASSIMP_LOG_WARN("LWOB: Unexpected TIMG chunk");
} }
break;
} }
else { // texture strength
ASSIMP_LOG_WARN("LWOB: Unexpected TFLG chunk"); case AI_LWO_TVAL:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1);
if (pTex) {
pTex->mStrength = (float)GetU1()/ 255.f;
} else {
ASSIMP_LOG_ERROR("LWOB: Unexpected TVAL chunk");
}
break;
}
// texture flags
case AI_LWO_TFLG:
{
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2);
if (nullptr != pTex) {
const uint16_t s = GetU2();
if (s & 1)
pTex->majorAxis = LWO::Texture::AXIS_X;
else if (s & 2)
pTex->majorAxis = LWO::Texture::AXIS_Y;
else if (s & 4)
pTex->majorAxis = LWO::Texture::AXIS_Z;
if (s & 16) {
ASSIMP_LOG_WARN("LWOB: Ignoring \'negate\' flag on texture");
}
}
else {
ASSIMP_LOG_WARN("LWOB: Unexpected TFLG chunk");
}
break;
} }
break;
}
} }
mFileBuffer = next; mFileBuffer = next;
} }

View File

@ -63,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"LightWave Scene Importer", "LightWave Scene Importer",
"", "",
"", "",
@ -139,10 +139,6 @@ LWSImporter::LWSImporter() :
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
LWSImporter::~LWSImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool LWSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {

View File

@ -174,7 +174,7 @@ struct NodeDesc {
class LWSImporter : public BaseImporter { class LWSImporter : public BaseImporter {
public: public:
LWSImporter(); LWSImporter();
~LWSImporter() override; ~LWSImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Check whether we can read a specific file // Check whether we can read a specific file

View File

@ -85,7 +85,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
are listed in aiScene->mRootNode->children, but all without meshes are listed in aiScene->mRootNode->children, but all without meshes
*/ */
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Model 3D Importer", "Model 3D Importer",
"", "",
"", "",

View File

@ -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,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER #ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
/** @file Implementation of the MD2 importer class */ /** @file Implementation of the MD2 importer class */
@ -65,7 +62,7 @@ using namespace Assimp::MD2;
# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0]))) # define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
#endif #endif
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Quake II Mesh Importer", "Quake II Mesh Importer",
"", "",
"", "",
@ -79,7 +76,7 @@ static const aiImporterDesc desc = {
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Helper function to lookup a normal in Quake 2's precalculated table // Helper function to lookup a normal in Quake 2's pre-calculated table
void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut) void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
{ {
// make sure the normal index has a valid value // make sure the normal index has a valid value
@ -100,10 +97,6 @@ MD2Importer::MD2Importer()
fileSize() fileSize()
{} {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MD2Importer::~MD2Importer() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const

View File

@ -63,7 +63,7 @@ using namespace MD2;
class MD2Importer : public BaseImporter { class MD2Importer : public BaseImporter {
public: public:
MD2Importer(); MD2Importer();
~MD2Importer() override; ~MD2Importer() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -70,7 +70,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Quake III Mesh Importer", "Quake III Mesh Importer",
"", "",
"", "",

View File

@ -64,7 +64,7 @@ using namespace Assimp;
// Minimum weight value. Weights inside [-n ... n] are ignored // Minimum weight value. Weights inside [-n ... n] are ignored
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>() #define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Doom 3 / MD5 Mesh Importer", "Doom 3 / MD5 Mesh Importer",
"", "",
"", "",
@ -92,10 +92,6 @@ MD5Importer::MD5Importer() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MD5Importer::~MD5Importer() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {

View File

@ -65,7 +65,7 @@ using namespace Assimp::MD5;
class MD5Importer : public BaseImporter { class MD5Importer : public BaseImporter {
public: public:
MD5Importer(); MD5Importer();
~MD5Importer() override; ~MD5Importer() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
using namespace Assimp::MDC; using namespace Assimp::MDC;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Return To Castle Wolfenstein Mesh Importer", "Return To Castle Wolfenstein Mesh Importer",
"", "",
"", "",
@ -103,10 +103,6 @@ MDCImporter::MDCImporter() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MDCImporter::~MDCImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool MDCImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {

View File

@ -62,7 +62,7 @@ using namespace MDC;
class MDCImporter : public BaseImporter { class MDCImporter : public BaseImporter {
public: public:
MDCImporter(); MDCImporter();
~MDCImporter() override; ~MDCImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Quake Mesh / 3D GameStudio Mesh Importer", "Quake Mesh / 3D GameStudio Mesh Importer",
"", "",
"", "",
@ -96,10 +96,6 @@ MDLImporter::MDLImporter() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MDLImporter::~MDLImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MDLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool MDLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {

View File

@ -39,10 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/// @file MDLLoader.h
/** @file MDLLoader.h /// @brief Declaration of the loader for MDL files
* @brief Declaration of the loader for MDL files
*/
#pragma once #pragma once
#ifndef AI_MDLLOADER_H_INCLUDED #ifndef AI_MDLLOADER_H_INCLUDED
#define AI_MDLLOADER_H_INCLUDED #define AI_MDLLOADER_H_INCLUDED
@ -83,11 +81,10 @@ using namespace MDL;
* them all with a single 1000-line function-beast. However, it has been * them all with a single 1000-line function-beast. However, it has been
* split into several code paths to make the code easier to read and maintain. * split into several code paths to make the code easier to read and maintain.
*/ */
class MDLImporter : public BaseImporter class MDLImporter : public BaseImporter {
{
public: public:
MDLImporter(); MDLImporter();
~MDLImporter() override; ~MDLImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -57,7 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
#include <sstream> #include <sstream>
static const aiImporterDesc desc = { "MMD Importer", static constexpr aiImporterDesc desc = { "MMD Importer",
"", "",
"", "",
"surfaces supported?", "surfaces supported?",
@ -81,10 +81,6 @@ MMDImporter::MMDImporter() :
m_strAbsPath = io.getOsSeparator(); m_strAbsPath = io.getOsSeparator();
} }
// ------------------------------------------------------------------------------------------------
// Destructor.
MMDImporter::~MMDImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if file is an pmx file. // Returns true, if file is an pmx file.
bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,

View File

@ -50,46 +50,34 @@ struct aiMesh;
namespace Assimp { namespace Assimp {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/// \class MMDImporter /// @class MMDImporter
/// \brief Imports MMD a pmx/pmd/vmd file /// @brief Imports MMD a pmx/pmd/vmd file
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class MMDImporter : public BaseImporter { class MMDImporter : public BaseImporter {
public: public:
/// \brief Default constructor /// @brief Default constructor
MMDImporter(); MMDImporter();
/// \brief Destructor /// @brief Destructor
~MMDImporter() override; ~MMDImporter() override = default;
public: public:
/// \brief Returns whether the class can handle the format of the given file. /// @brief Returns whether the class can handle the format of the given file.
/// \remark See BaseImporter::CanRead() for details. /// @remark See BaseImporter::CanRead() for details.
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
private: private:
//! \brief Appends the supported extension.
const aiImporterDesc* GetInfo() const override; const aiImporterDesc* GetInfo() const override;
//! \brief File import implementation.
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override; void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
//! \brief Create the data from imported content.
void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene); void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
//! \brief Create the mesh
aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount); aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
//! \brief Create the material
aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel); aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
private: private:
//! Data buffer
std::vector<char> m_Buffer; std::vector<char> m_Buffer;
//! Absolute pathname of model in file system
std::string m_strAbsPath; std::string m_strAbsPath;
}; };
// ------------------------------------------------------------------------------------------------
} // Namespace Assimp } // Namespace Assimp

View File

@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Milkshape 3D Importer", "Milkshape 3D Importer",
"", "",
"", "",
@ -84,9 +84,6 @@ MS3DImporter::MS3DImporter()
: mScene() : mScene()
{} {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
MS3DImporter::~MS3DImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/StreamReader.h> #include <assimp/StreamReader.h>
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
@ -58,7 +59,7 @@ namespace Assimp {
class MS3DImporter : public BaseImporter { class MS3DImporter : public BaseImporter {
public: public:
MS3DImporter(); MS3DImporter();
~MS3DImporter() override; ~MS3DImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -43,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Implementation of the NDO importer class. * Implementation of the NDO importer class.
*/ */
#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER #ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
#include "NDOLoader.h" #include "NDOLoader.h"
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Nendo Mesh Importer", "Nendo Mesh Importer",
"", "",
"", "",
@ -69,14 +69,6 @@ static const aiImporterDesc desc = {
"ndo" "ndo"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
NDOImporter::NDOImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
NDOImporter::~NDOImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const

View File

@ -65,8 +65,8 @@ class Importer;
*/ */
class NDOImporter : public BaseImporter { class NDOImporter : public BaseImporter {
public: public:
NDOImporter(); NDOImporter() = default;
~NDOImporter() override; ~NDOImporter() override = default;
//! Represents a single edge //! Represents a single edge
struct Edge { struct Edge {

View File

@ -56,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Neutral File Format Importer", "Neutral File Format Importer",
"", "",
"", "",
@ -71,14 +71,6 @@ static const aiImporterDesc desc = {
"enff nff" "enff nff"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
NFFImporter::NFFImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
NFFImporter::~NFFImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool NFFImporter::CanRead(const std::string & pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool NFFImporter::CanRead(const std::string & pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
@ -94,7 +86,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_FLOAT(f) \ #define AI_NFF_PARSE_FLOAT(f) \
SkipSpaces(&sz); \ SkipSpaces(&sz); \
if (!::IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f); if (!IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_TRIPLE(v) \ #define AI_NFF_PARSE_TRIPLE(v) \
@ -338,8 +330,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
break; break;
} }
// read the numbr of vertices // read the number of vertices
unsigned int num = ::strtoul10(sz, &sz); unsigned int num = strtoul10(sz, &sz);
// temporary storage // temporary storage
std::vector<aiColor4D> tempColors; std::vector<aiColor4D> tempColors;
@ -365,7 +357,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// color definition // color definition
if (TokenMatch(sz, "0x", 2)) { if (TokenMatch(sz, "0x", 2)) {
hasColor = true; hasColor = true;
unsigned int numIdx = ::strtoul16(sz, &sz); unsigned int numIdx = strtoul16(sz, &sz);
aiColor4D clr; aiColor4D clr;
clr.a = 1.f; clr.a = 1.f;
@ -403,15 +395,16 @@ void NFFImporter::InternReadFile(const std::string &pFile,
} }
AI_NFF2_GET_NEXT_TOKEN(); AI_NFF2_GET_NEXT_TOKEN();
if (!num) throw DeadlyImportError("NFF2: There are zero vertices"); if (!num)
num = ::strtoul10(sz, &sz); throw DeadlyImportError("NFF2: There are zero vertices");
num = strtoul10(sz, &sz);
std::vector<unsigned int> tempIdx; std::vector<unsigned int> tempIdx;
tempIdx.reserve(10); tempIdx.reserve(10);
for (unsigned int i = 0; i < num; ++i) { for (unsigned int i = 0; i < num; ++i) {
AI_NFF2_GET_NEXT_TOKEN(); AI_NFF2_GET_NEXT_TOKEN();
SkipSpaces(line, &sz); SkipSpaces(line, &sz);
unsigned int numIdx = ::strtoul10(sz, &sz); unsigned int numIdx = strtoul10(sz, &sz);
// read all faces indices // read all faces indices
if (numIdx) { if (numIdx) {
@ -421,7 +414,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
for (unsigned int a = 0; a < numIdx; ++a) { for (unsigned int a = 0; a < numIdx; ++a) {
SkipSpaces(sz, &sz); SkipSpaces(sz, &sz);
unsigned int m = ::strtoul10(sz, &sz); unsigned int m = strtoul10(sz, &sz);
if (m >= (unsigned int)tempPositions.size()) { if (m >= (unsigned int)tempPositions.size()) {
ASSIMP_LOG_ERROR("NFF2: Vertex index overflow"); ASSIMP_LOG_ERROR("NFF2: Vertex index overflow");
m = 0; m = 0;
@ -446,7 +439,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
if (TokenMatch(sz, "0x", 2)) { if (TokenMatch(sz, "0x", 2)) {
hasColor = true; hasColor = true;
const char *sz2 = sz; const char *sz2 = sz;
numIdx = ::strtoul16(sz, &sz); numIdx = strtoul16(sz, &sz);
const unsigned int diff = (unsigned int)(sz - sz2); const unsigned int diff = (unsigned int)(sz - sz2);
// 0xRRGGBB // 0xRRGGBB
@ -518,7 +511,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// Material ID? // Material ID?
else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) { else if (!materialTable.empty() && TokenMatch(sz, "matid", 5)) {
SkipSpaces(&sz); SkipSpaces(&sz);
matIdx = ::strtoul10(sz, &sz); matIdx = strtoul10(sz, &sz);
if (matIdx >= materialTable.size()) { if (matIdx >= materialTable.size()) {
ASSIMP_LOG_ERROR("NFF2: Material index overflow."); ASSIMP_LOG_ERROR("NFF2: Material index overflow.");
matIdx = 0; matIdx = 0;
@ -1165,4 +1158,6 @@ void NFFImporter::InternReadFile(const std::string &pFile,
pScene->mRootNode = root; pScene->mRootNode = root;
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER #endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER

View File

@ -63,8 +63,8 @@ namespace Assimp {
*/ */
class NFFImporter : public BaseImporter { class NFFImporter : public BaseImporter {
public: public:
NFFImporter(); NFFImporter() = default;
~NFFImporter() override; ~NFFImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the OFF importer class * @brief Implementation of the OFF importer class
*/ */
#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER #ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
// internal headers // internal headers
@ -56,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"OFF Importer", "OFF Importer",
"", "",
"", "",
@ -71,99 +70,92 @@ static const aiImporterDesc desc = {
"off" "off"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
OFFImporter::OFFImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
OFFImporter::~OFFImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const bool OFFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
{ static const char *tokens[] = { "off" };
static const char* tokens[] = { "off" }; return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens), 3);
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens),3);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* OFFImporter::GetInfo () const const aiImporterDesc *OFFImporter::GetInfo() const {
{
return &desc; return &desc;
} }
// skip blank space, lines and comments // skip blank space, lines and comments
static void NextToken(const char **car, const char* end) { static void NextToken(const char **car, const char *end) {
SkipSpacesAndLineEnd(car);
while (*car < end && (**car == '#' || **car == '\n' || **car == '\r')) {
SkipLine(car);
SkipSpacesAndLineEnd(car); SkipSpacesAndLineEnd(car);
} while (*car < end && (**car == '#' || **car == '\n' || **car == '\r')) {
SkipLine(car);
SkipSpacesAndLineEnd(car);
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { void OFFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if (file == nullptr) { if (file == nullptr) {
throw DeadlyImportError("Failed to open OFF file ", pFile, "."); throw DeadlyImportError("Failed to open OFF file ", pFile, ".");
} }
// allocate storage and copy the contents of the file to a memory buffer // allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2); TextFileToBuffer(file.get(), mBuffer2);
const char* buffer = &mBuffer2[0]; const char *buffer = &mBuffer2[0];
// Proper OFF header parser. We only implement normal loading for now. // Proper OFF header parser. We only implement normal loading for now.
bool hasTexCoord = false, hasNormals = false, hasColors = false; bool hasTexCoord = false, hasNormals = false, hasColors = false;
bool hasHomogenous = false, hasDimension = false; bool hasHomogenous = false, hasDimension = false;
unsigned int dimensions = 3; unsigned int dimensions = 3;
const char* car = buffer; const char *car = buffer;
const char* end = buffer + mBuffer2.size(); const char *end = buffer + mBuffer2.size();
NextToken(&car, end); NextToken(&car, end);
if (car < end - 2 && car[0] == 'S' && car[1] == 'T') { if (car < end - 2 && car[0] == 'S' && car[1] == 'T') {
hasTexCoord = true; car += 2; hasTexCoord = true;
car += 2;
} }
if (car < end - 1 && car[0] == 'C') { if (car < end - 1 && car[0] == 'C') {
hasColors = true; car++; hasColors = true;
car++;
} }
if (car < end- 1 && car[0] == 'N') { if (car < end - 1 && car[0] == 'N') {
hasNormals = true; car++; hasNormals = true;
car++;
} }
if (car < end - 1 && car[0] == '4') { if (car < end - 1 && car[0] == '4') {
hasHomogenous = true; car++; hasHomogenous = true;
car++;
} }
if (car < end - 1 && car[0] == 'n') { if (car < end - 1 && car[0] == 'n') {
hasDimension = true; car++; hasDimension = true;
car++;
} }
if (car < end - 3 && car[0] == 'O' && car[1] == 'F' && car[2] == 'F') { if (car < end - 3 && car[0] == 'O' && car[1] == 'F' && car[2] == 'F') {
car += 3; car += 3;
NextToken(&car, end); NextToken(&car, end);
} else { } else {
// in case there is no OFF header (which is allowed by the // in case there is no OFF header (which is allowed by the
// specification...), then we might have unintentionally read an // specification...), then we might have unintentionally read an
// additional dimension from the primitive count fields // additional dimension from the primitive count fields
dimensions = 3; dimensions = 3;
hasHomogenous = false; hasHomogenous = false;
NextToken(&car, end); NextToken(&car, end);
// at this point the next token should be an integer number // at this point the next token should be an integer number
if (car >= end - 1 || *car < '0' || *car > '9') { if (car >= end - 1 || *car < '0' || *car > '9') {
throw DeadlyImportError("OFF: Header is invalid"); throw DeadlyImportError("OFF: Header is invalid");
} }
} }
if (hasDimension) { if (hasDimension) {
dimensions = strtoul10(car, &car); dimensions = strtoul10(car, &car);
NextToken(&car, end); NextToken(&car, end);
} }
if (dimensions > 3) { if (dimensions > 3) {
throw DeadlyImportError throw DeadlyImportError("OFF: Number of vertex coordinates higher than 3 unsupported");
("OFF: Number of vertex coordinates higher than 3 unsupported");
} }
NextToken(&car, end); NextToken(&car, end);
@ -171,7 +163,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
NextToken(&car, end); NextToken(&car, end);
const unsigned int numFaces = strtoul10(car, &car); const unsigned int numFaces = strtoul10(car, &car);
NextToken(&car, end); NextToken(&car, end);
strtoul10(car, &car); // skip edge count strtoul10(car, &car); // skip edge count
NextToken(&car, end); NextToken(&car, end);
if (!numVertices) { if (!numVertices) {
@ -182,13 +174,13 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
} }
pScene->mNumMeshes = 1; pScene->mNumMeshes = 1;
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
aiMesh* mesh = new aiMesh(); aiMesh *mesh = new aiMesh();
pScene->mMeshes[0] = mesh; pScene->mMeshes[0] = mesh;
mesh->mNumFaces = numFaces; mesh->mNumFaces = numFaces;
aiFace* faces = new aiFace[mesh->mNumFaces]; aiFace *faces = new aiFace[mesh->mNumFaces];
mesh->mFaces = faces; mesh->mFaces = faces;
mesh->mNumVertices = numVertices; mesh->mNumVertices = numVertices;
@ -206,100 +198,101 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// now read all vertex lines // now read all vertex lines
for (unsigned int i = 0; i < numVertices; ++i) { for (unsigned int i = 0; i < numVertices; ++i) {
if(!GetNextLine(buffer, line)) { if (!GetNextLine(buffer, line)) {
ASSIMP_LOG_ERROR("OFF: The number of verts in the header is incorrect"); ASSIMP_LOG_ERROR("OFF: The number of verts in the header is incorrect");
break; break;
} }
aiVector3D& v = mesh->mVertices[i]; aiVector3D &v = mesh->mVertices[i];
sz = line; sz = line;
// helper array to write a for loop over possible dimension values // helper array to write a for loop over possible dimension values
ai_real* vec[3] = {&v.x, &v.y, &v.z}; ai_real *vec[3] = { &v.x, &v.y, &v.z };
// stop at dimensions: this allows loading 1D or 2D coordinate vertices // stop at dimensions: this allows loading 1D or 2D coordinate vertices
for (unsigned int dim = 0; dim < dimensions; ++dim ) { for (unsigned int dim = 0; dim < dimensions; ++dim) {
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz, *vec[dim]); sz = fast_atoreal_move<ai_real>(sz, *vec[dim]);
} }
// if has homogeneous coordinate, divide others by this one // if has homogeneous coordinate, divide others by this one
if (hasHomogenous) { if (hasHomogenous) {
SkipSpaces(&sz); SkipSpaces(&sz);
ai_real w = 1.; ai_real w = 1.;
sz = fast_atoreal_move<ai_real>(sz, w); sz = fast_atoreal_move<ai_real>(sz, w);
for (unsigned int dim = 0; dim < dimensions; ++dim ) { for (unsigned int dim = 0; dim < dimensions; ++dim) {
*(vec[dim]) /= w; *(vec[dim]) /= w;
} }
} }
// read optional normals // read optional normals
if (hasNormals) { if (hasNormals) {
aiVector3D& n = mesh->mNormals[i]; aiVector3D &n = mesh->mNormals[i];
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)n.x); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.x);
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)n.y); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)n.y);
SkipSpaces(&sz); SkipSpaces(&sz);
fast_atoreal_move<ai_real>(sz,(ai_real&)n.z); fast_atoreal_move<ai_real>(sz, (ai_real &)n.z);
} }
// reading colors is a pain because the specification says it can be // reading colors is a pain because the specification says it can be
// integers or floats, and any number of them between 1 and 4 included, // integers or floats, and any number of them between 1 and 4 included,
// until the next comment or end of line // until the next comment or end of line
// in theory should be testing type ! // in theory should be testing type !
if (hasColors) { if (hasColors) {
aiColor4D& c = mesh->mColors[0][i]; aiColor4D &c = mesh->mColors[0][i];
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.r); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.r);
if (*sz != '#' && *sz != '\n' && *sz != '\r') { if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.g); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.g);
} else { } else {
c.g = 0.; c.g = 0.;
} }
if (*sz != '#' && *sz != '\n' && *sz != '\r') { if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.b); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.b);
} else { } else {
c.b = 0.; c.b = 0.;
} }
if (*sz != '#' && *sz != '\n' && *sz != '\r') { if (*sz != '#' && *sz != '\n' && *sz != '\r') {
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)c.a); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)c.a);
} else { } else {
c.a = 1.; c.a = 1.;
} }
} }
if (hasTexCoord) { if (hasTexCoord) {
aiVector3D& t = mesh->mTextureCoords[0][i]; aiVector3D &t = mesh->mTextureCoords[0][i];
SkipSpaces(&sz); SkipSpaces(&sz);
sz = fast_atoreal_move<ai_real>(sz,(ai_real&)t.x); sz = fast_atoreal_move<ai_real>(sz, (ai_real &)t.x);
SkipSpaces(&sz); SkipSpaces(&sz);
fast_atoreal_move<ai_real>(sz,(ai_real&)t.y); fast_atoreal_move<ai_real>(sz, (ai_real &)t.y);
} }
} }
// load faces with their indices // load faces with their indices
faces = mesh->mFaces; faces = mesh->mFaces;
for (unsigned int i = 0; i < numFaces; ) { for (unsigned int i = 0; i < numFaces;) {
if(!GetNextLine(buffer,line)) { if (!GetNextLine(buffer, line)) {
ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect"); ASSIMP_LOG_ERROR("OFF: The number of faces in the header is incorrect");
throw DeadlyImportError("OFF: The number of faces in the header is incorrect"); throw DeadlyImportError("OFF: The number of faces in the header is incorrect");
} }
unsigned int idx; unsigned int idx;
sz = line; SkipSpaces(&sz); sz = line;
idx = strtoul10(sz,&sz); SkipSpaces(&sz);
if(!idx || idx > 9) { idx = strtoul10(sz, &sz);
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed"); if (!idx || idx > 9) {
ASSIMP_LOG_ERROR("OFF: Faces with zero indices aren't allowed");
--mesh->mNumFaces; --mesh->mNumFaces;
++i; ++i;
continue; continue;
} }
faces->mNumIndices = idx; faces->mNumIndices = idx;
faces->mIndices = new unsigned int[faces->mNumIndices]; faces->mIndices = new unsigned int[faces->mNumIndices];
for (unsigned int m = 0; m < faces->mNumIndices;++m) { for (unsigned int m = 0; m < faces->mNumIndices; ++m) {
SkipSpaces(&sz); SkipSpaces(&sz);
idx = strtoul10(sz,&sz); idx = strtoul10(sz, &sz);
if (idx >= numVertices) { if (idx >= numVertices) {
ASSIMP_LOG_ERROR("OFF: Vertex index is out of range"); ASSIMP_LOG_ERROR("OFF: Vertex index is out of range");
idx = numVertices - 1; idx = numVertices - 1;
@ -314,20 +307,22 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<OFFRoot>"); pScene->mRootNode->mName.Set("<OFFRoot>");
pScene->mRootNode->mNumMeshes = 1; pScene->mRootNode->mNumMeshes = 1;
pScene->mRootNode->mMeshes = new unsigned int [pScene->mRootNode->mNumMeshes]; pScene->mRootNode->mMeshes = new unsigned int[pScene->mRootNode->mNumMeshes];
pScene->mRootNode->mMeshes[0] = 0; pScene->mRootNode->mMeshes[0] = 0;
// generate a default material // generate a default material
pScene->mNumMaterials = 1; pScene->mNumMaterials = 1;
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
aiMaterial* pcMat = new aiMaterial(); aiMaterial *pcMat = new aiMaterial();
aiColor4D clr( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 1.0 ) ); aiColor4D clr(ai_real(0.6), ai_real(0.6), ai_real(0.6), ai_real(1.0));
pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE); pcMat->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pScene->mMaterials[0] = pcMat; pScene->mMaterials[0] = pcMat;
const int twosided = 1; const int twosided = 1;
pcMat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED); pcMat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED);
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER #endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER

View File

@ -57,8 +57,8 @@ namespace Assimp {
*/ */
class OFFImporter : public BaseImporter { class OFFImporter : public BaseImporter {
public: public:
OFFImporter(); OFFImporter() = default;
~OFFImporter() override; ~OFFImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ObjMaterial.h> #include <assimp/ObjMaterial.h>
#include <memory> #include <memory>
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Wavefront Object Importer", "Wavefront Object Importer",
"", "",
"", "",
@ -78,7 +78,9 @@ using namespace std;
ObjFileImporter::ObjFileImporter() : ObjFileImporter::ObjFileImporter() :
m_Buffer(), m_Buffer(),
m_pRootObject(nullptr), m_pRootObject(nullptr),
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {} m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {
// empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
@ -101,8 +103,13 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Obj-file import implementation // Obj-file import implementation
void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) { void ObjFileImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSystem *pIOHandler) {
if (m_pRootObject != nullptr) {
delete m_pRootObject;
m_pRootObject = nullptr;
}
// Read file into memory // Read file into memory
static const std::string mode = "rb"; static constexpr char mode[] = "rb";
auto streamCloser = [&](IOStream *pStream) { auto streamCloser = [&](IOStream *pStream) {
pIOHandler->Close(pStream); pIOHandler->Close(pStream);
}; };

View File

@ -605,7 +605,8 @@ void ObjFileParser::getMaterialDesc() {
} }
if (needsNewMesh(strName)) { if (needsNewMesh(strName)) {
createMesh(strName); auto newMeshName = m_pModel->mActiveGroup.empty() ? strName : m_pModel->mActiveGroup;
createMesh(newMeshName);
} }
m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName); m_pModel->mCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);

View File

@ -48,7 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <memory> #include <memory>
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Ogre3D Mesh Importer", "Ogre3D Mesh Importer",
"", "",
"", "",

View File

@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h> #include <assimp/scene.h>
#include <openddlparser/OpenDDLParser.h> #include <openddlparser/OpenDDLParser.h>
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Open Game Engine Exchange", "Open Game Engine Exchange",
"", "",
"", "",
@ -66,42 +66,42 @@ static const aiImporterDesc desc = {
}; };
namespace Grammar { namespace Grammar {
static const char* MetricType = "Metric"; static constexpr char MetricType[] = "Metric";
static const char *Metric_DistanceType = "distance"; static constexpr char Metric_DistanceType[] = "distance";
static const char *Metric_AngleType = "angle"; static constexpr char Metric_AngleType[] = "angle";
static const char *Metric_TimeType = "time"; static constexpr char Metric_TimeType[] = "time";
static const char *Metric_UpType = "up"; static constexpr char Metric_UpType[] = "up";
static const char *NameType = "Name"; static constexpr char NameType[] = "Name";
static const char *ObjectRefType = "ObjectRef"; static constexpr char ObjectRefType[] = "ObjectRef";
static const char *MaterialRefType = "MaterialRef"; static constexpr char MaterialRefType[] = "MaterialRef";
static const char *MetricKeyType = "key"; static constexpr char MetricKeyType[] = "key";
static const char *GeometryNodeType = "GeometryNode"; static constexpr char GeometryNodeType[] = "GeometryNode";
static const char *CameraNodeType = "CameraNode"; static constexpr char CameraNodeType[] = "CameraNode";
static const char *LightNodeType = "LightNode"; static constexpr char LightNodeType[] = "LightNode";
static const char *GeometryObjectType = "GeometryObject"; static constexpr char GeometryObjectType[] = "GeometryObject";
static const char *CameraObjectType = "CameraObject"; static constexpr char CameraObjectType[] = "CameraObject";
static const char *LightObjectType = "LightObject"; static constexpr char LightObjectType[] = "LightObject";
static const char *TransformType = "Transform"; static constexpr char TransformType[] = "Transform";
static const char *MeshType = "Mesh"; static constexpr char MeshType[] = "Mesh";
static const char *VertexArrayType = "VertexArray"; static constexpr char VertexArrayType[] = "VertexArray";
static const char *IndexArrayType = "IndexArray"; static constexpr char IndexArrayType[] = "IndexArray";
static const char *MaterialType = "Material"; static constexpr char MaterialType[] = "Material";
static const char *ColorType = "Color"; static constexpr char ColorType[] = "Color";
static const char *ParamType = "Param"; static constexpr char ParamType[] = "Param";
static const char *TextureType = "Texture"; static constexpr char TextureType[] = "Texture";
static const char *AttenType = "Atten"; static constexpr char AttenType[] = "Atten";
static const char *DiffuseColorToken = "diffuse"; static constexpr char DiffuseColorToken[] = "diffuse";
static const char *SpecularColorToken = "specular"; static constexpr char SpecularColorToken[] = "specular";
static const char *EmissionColorToken = "emission"; static constexpr char EmissionColorToken[] = "emission";
static const char *DiffuseTextureToken = "diffuse"; static constexpr char DiffuseTextureToken[] = "diffuse";
static const char *DiffuseSpecularTextureToken = "specular"; static constexpr char DiffuseSpecularTextureToken[] = "specular";
static const char *SpecularPowerTextureToken = "specular_power"; static constexpr char SpecularPowerTextureToken[] = "specular_power";
static const char *EmissionTextureToken = "emission"; static constexpr char EmissionTextureToken[] = "emission";
static const char *OpacyTextureToken = "opacity"; static constexpr char OpacyTextureToken[] = "opacity";
static const char *TransparencyTextureToken = "transparency"; static constexpr char TransparencyTextureToken[] = "transparency";
static const char *NormalTextureToken = "normal"; static constexpr char NormalTextureToken[] = "normal";
enum TokenType { enum TokenType {
NoneType = -1, NoneType = -1,
@ -139,7 +139,7 @@ namespace Grammar {
return false; return false;
} }
int idx(-1); int idx = -1;
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
if (ValidMetricToken[i] == token) { if (ValidMetricToken[i] == token) {
idx = (int)i; idx = (int)i;

View File

@ -53,9 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
using namespace ::Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Stanford Polygon Library (PLY) Importer", "Stanford Polygon Library (PLY) Importer",
"", "",
"", "",
@ -71,16 +71,16 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Internal stuff // Internal stuff
namespace { namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Checks that property index is within range // Checks that property index is within range
template <class T> template <class T>
inline const T &GetProperty(const std::vector<T> &props, int idx) { inline const T &GetProperty(const std::vector<T> &props, int idx) {
if (static_cast<size_t>(idx) >= props.size()) { if (static_cast<size_t>(idx) >= props.size()) {
throw DeadlyImportError("Invalid .ply file: Property index is out of range."); throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
} }
return props[idx]; return props[idx];
} }
} // namespace } // namespace
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -92,10 +92,6 @@ PLYImporter::PLYImporter() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
PLYImporter::~PLYImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool PLYImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -215,7 +211,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
throw DeadlyImportError("Invalid .ply file: Missing format specification"); throw DeadlyImportError("Invalid .ply file: Missing format specification");
} }
//free the file buffer // free the file buffer
streamedBuffer.close(); streamedBuffer.close();
if (mGeneratedMesh == nullptr) { if (mGeneratedMesh == nullptr) {
@ -376,7 +372,7 @@ void PLYImporter::LoadVertex(const PLY::Element *pcElement, const PLY::ElementIn
haveNormal = true; haveNormal = true;
} }
//Colors // Colors
aiColor4D cOut; aiColor4D cOut;
bool haveColor = false; bool haveColor = false;
if (0xFFFFFFFF != aiColors[0]) { if (0xFFFFFFFF != aiColors[0]) {
@ -415,7 +411,7 @@ void PLYImporter::LoadVertex(const PLY::Element *pcElement, const PLY::ElementIn
haveColor = true; haveColor = true;
} }
//Texture coordinates // Texture coordinates
aiVector3D tOut; aiVector3D tOut;
tOut.z = 0; tOut.z = 0;
bool haveTextureCoords = false; bool haveTextureCoords = false;
@ -431,7 +427,7 @@ void PLYImporter::LoadVertex(const PLY::Element *pcElement, const PLY::ElementIn
haveTextureCoords = true; haveTextureCoords = true;
} }
//create aiMesh if needed // create aiMesh if needed
if (nullptr == mGeneratedMesh) { if (nullptr == mGeneratedMesh) {
mGeneratedMesh = new aiMesh(); mGeneratedMesh = new aiMesh();
mGeneratedMesh->mMaterialIndex = 0; mGeneratedMesh->mMaterialIndex = 0;
@ -512,8 +508,8 @@ void PLYImporter::LoadFace(const PLY::Element *pcElement, const PLY::ElementInst
bool bIsTriStrip = false; bool bIsTriStrip = false;
// index of the material index property // index of the material index property
//unsigned int iMaterialIndex = 0xFFFFFFFF; // unsigned int iMaterialIndex = 0xFFFFFFFF;
//PLY::EDataType eType2 = EDT_Char; // PLY::EDataType eType2 = EDT_Char;
// texture coordinates // texture coordinates
unsigned int iTextureCoord = 0xFFFFFFFF; unsigned int iTextureCoord = 0xFFFFFFFF;
@ -595,7 +591,7 @@ void PLYImporter::LoadFace(const PLY::Element *pcElement, const PLY::ElementInst
if (0xFFFFFFFF != iTextureCoord) { if (0xFFFFFFFF != iTextureCoord) {
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size(); const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
//should be 6 coords // should be 6 coords
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p = std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
GetProperty(instElement->alProperties, iTextureCoord).avList.begin(); GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
@ -625,7 +621,7 @@ void PLYImporter::LoadFace(const PLY::Element *pcElement, const PLY::ElementInst
// a value of -1 indicates a restart of the strip // a value of -1 indicates a restart of the strip
bool flip = false; bool flip = false;
const std::vector<PLY::PropertyInstance::ValueUnion> &quak = GetProperty(instElement->alProperties, iProperty).avList; const std::vector<PLY::PropertyInstance::ValueUnion> &quak = GetProperty(instElement->alProperties, iProperty).avList;
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption // pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
int aiTable[2] = { -1, -1 }; int aiTable[2] = { -1, -1 };
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) { for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
@ -863,7 +859,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
const int two_sided = 1; const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
//default texture // default texture
if (!defaultTexture.empty()) { if (!defaultTexture.empty()) {
const aiString name(defaultTexture.c_str()); const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0); pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
@ -873,7 +869,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
} }
//set to wireframe, so when using this material info we can switch to points rendering // set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly) { if (pointsOnly) {
const int wireframe = 1; const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME); pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
@ -890,7 +886,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
int iMode = (int)aiShadingMode_Gouraud; int iMode = (int)aiShadingMode_Gouraud;
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL); pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
//generate white material most 3D engine just multiply ambient / diffuse color with actual ambient / light color // generate white material most 3D engine just multiply ambient / diffuse color with actual ambient / light color
aiColor3D clr; aiColor3D clr;
clr.b = clr.g = clr.r = 1.0f; clr.b = clr.g = clr.r = 1.0f;
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE); pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
@ -906,13 +902,13 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED); pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
} }
//default texture // default texture
if (!defaultTexture.empty()) { if (!defaultTexture.empty()) {
const aiString name(defaultTexture.c_str()); const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0); pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
} }
//set to wireframe, so when using this material info we can switch to points rendering // set to wireframe, so when using this material info we can switch to points rendering
if (pointsOnly) { if (pointsOnly) {
const int wireframe = 1; const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME); pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
@ -922,4 +918,6 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER #endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER

View File

@ -65,7 +65,7 @@ using namespace PLY;
class PLYImporter : public BaseImporter { class PLYImporter : public BaseImporter {
public: public:
PLYImporter(); PLYImporter();
~PLYImporter() override; ~PLYImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream> #include <sstream>
#include <vector> #include <vector>
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Quake III BSP Importer", "Quake III BSP Importer",
"", "",
"", "",
@ -146,7 +146,11 @@ Q3BSPFileImporter::Q3BSPFileImporter() :
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
Q3BSPFileImporter::~Q3BSPFileImporter() { Q3BSPFileImporter::~Q3BSPFileImporter() {
// Clear face-to-material map clear();
}
// ------------------------------------------------------------------------------------------------
void Q3BSPFileImporter::clear() {
for (FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) { for (FaceMap::iterator it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
const std::string &matName = it->first; const std::string &matName = it->first;
if (!matName.empty()) { if (!matName.empty()) {
@ -173,6 +177,7 @@ const aiImporterDesc *Q3BSPFileImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Import method. // Import method.
void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, IOSystem *ioHandler) { void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene, IOSystem *ioHandler) {
clear();
ZipArchiveIOSystem Archive(ioHandler, rFile); ZipArchiveIOSystem Archive(ioHandler, rFile);
if (!Archive.isOpen()) { if (!Archive.isOpen()) {
throw DeadlyImportError("Failed to open file ", rFile, "."); throw DeadlyImportError("Failed to open file ", rFile, ".");

View File

@ -81,6 +81,7 @@ protected:
using FaceMapIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator; using FaceMapIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator;
using FaceMapConstIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator; using FaceMapConstIt = std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator;
void clear();
const aiImporterDesc* GetInfo () const override; const aiImporterDesc* GetInfo () const override;
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override; void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName ); void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName );

View File

@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Quick3D Importer", "Quick3D Importer",
"", "",
"", "",
@ -127,7 +127,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
std::vector<Material> materials; std::vector<Material> materials;
try { try {
materials.reserve(numMats); materials.reserve(numMats);
} catch(const std::bad_alloc&) { } catch (const std::bad_alloc &) {
ASSIMP_LOG_ERROR("Invalid alloc for materials."); ASSIMP_LOG_ERROR("Invalid alloc for materials.");
throw DeadlyImportError("Invalid Quick3D-file, material allocation failed."); throw DeadlyImportError("Invalid Quick3D-file, material allocation failed.");
} }
@ -135,7 +135,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
std::vector<Mesh> meshes; std::vector<Mesh> meshes;
try { try {
meshes.reserve(numMeshes); meshes.reserve(numMeshes);
} catch(const std::bad_alloc&) { } catch (const std::bad_alloc &) {
ASSIMP_LOG_ERROR("Invalid alloc for meshes."); ASSIMP_LOG_ERROR("Invalid alloc for meshes.");
throw DeadlyImportError("Invalid Quick3D-file, mesh allocation failed."); throw DeadlyImportError("Invalid Quick3D-file, mesh allocation failed.");
} }
@ -237,7 +237,6 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
if (minor > '0' && major == '3') if (minor > '0' && major == '3')
stream.IncPtr(mesh.faces.size()); stream.IncPtr(mesh.faces.size());
} }
// stream.IncPtr(4); // unknown value here
} break; } break;
// materials chunk // materials chunk
@ -275,8 +274,6 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
// read the transparency // read the transparency
mat.transparency = stream.GetF4(); mat.transparency = stream.GetF4();
// unknown value here
// stream.IncPtr(4);
// FIX: it could be the texture index ... // FIX: it could be the texture index ...
mat.texIdx = (unsigned int)stream.GetI4(); mat.texIdx = (unsigned int)stream.GetI4();
} }
@ -425,7 +422,8 @@ outer:
pScene->mMeshes = new aiMesh *[pScene->mNumMaterials]; pScene->mMeshes = new aiMesh *[pScene->mNumMaterials];
for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) { for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) {
if (fidx[i].empty()) continue; if (fidx[i].empty())
continue;
// Allocate a mesh and a material // Allocate a mesh and a material
aiMesh *mesh = pScene->mMeshes[real] = new aiMesh(); aiMesh *mesh = pScene->mMeshes[real] = new aiMesh();
@ -548,14 +546,9 @@ outer:
// Now we need to attach the meshes to the root node of the scene // Now we need to attach the meshes to the root node of the scene
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mRootNode->mMeshes[i] = i; pScene->mRootNode->mMeshes[i] = i;
}
/*pScene->mRootNode->mTransformation *= aiMatrix4x4(
1.f, 0.f, 0.f, 0.f,
0.f, -1.f,0.f, 0.f,
0.f, 0.f, 1.f, 0.f,
0.f, 0.f, 0.f, 1.f);*/
// Add cameras and light sources to the scene root node // Add cameras and light sources to the scene root node
pScene->mRootNode->mNumChildren = pScene->mNumLights + pScene->mNumCameras; pScene->mRootNode->mNumChildren = pScene->mNumLights + pScene->mNumCameras;
@ -577,4 +570,6 @@ outer:
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER #endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER

View File

@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Raw Importer", "Raw Importer",
"", "",
"", "",
@ -70,14 +70,6 @@ static const aiImporterDesc desc = {
"raw" "raw"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
RAWImporter::RAWImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
RAWImporter::~RAWImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool RAWImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool RAWImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
@ -295,4 +287,6 @@ void RAWImporter::InternReadFile(const std::string &pFile,
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER #endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER

View File

@ -57,8 +57,8 @@ namespace Assimp {
*/ */
class RAWImporter : public BaseImporter { class RAWImporter : public BaseImporter {
public: public:
RAWImporter(); RAWImporter() = default;
~RAWImporter() override; ~RAWImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -69,9 +69,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <map> #include <map>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Silo SIB Importer", "Silo SIB Importer",
"Richard Mitton (http://www.codersnotes.com/about)", "Richard Mitton (http://www.codersnotes.com/about)",
"", "",
@ -94,7 +94,7 @@ enum {
N N
}; };
typedef std::pair<uint32_t, uint32_t> SIBPair; using SIBPair = std::pair<uint32_t, uint32_t>;
struct SIBEdge { struct SIBEdge {
uint32_t faceA, faceB; uint32_t faceA, faceB;
@ -199,15 +199,6 @@ static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) {
return result; return result;
} }
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SIBImporter::SIBImporter() = default;
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
SIBImporter::~SIBImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool SIBImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool SIBImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
@ -882,4 +873,6 @@ void SIBImporter::InternReadFile(const std::string &pFile,
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_SIB_IMPORTER #endif // !! ASSIMP_BUILD_NO_SIB_IMPORTER

View File

@ -57,8 +57,8 @@ namespace Assimp {
*/ */
class ASSIMP_API SIBImporter : public BaseImporter { class ASSIMP_API SIBImporter : public BaseImporter {
public: public:
SIBImporter(); SIBImporter() = default;
~SIBImporter() override; ~SIBImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.

View File

@ -64,9 +64,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define strtok_s strtok_r #define strtok_s strtok_r
#endif #endif
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Valve SMD Importer", "Valve SMD Importer",
"", "",
"", "",
@ -1077,4 +1077,6 @@ void SMDImporter::ParseVertex(const char* szCurrent,
SMDI_PARSE_RETURN; SMDI_PARSE_RETURN;
} }
}
#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER #endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER

View File

@ -52,11 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
namespace { namespace {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Stereolithography (STL) Importer", "Stereolithography (STL) Importer",
"", "",
"", "",
@ -129,7 +129,7 @@ STLImporter::STLImporter() :
mBuffer(), mBuffer(),
mFileSize(0), mFileSize(0),
mScene() { mScene() {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -250,13 +250,13 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
sz += 5; // skip the "solid" sz += 5; // skip the "solid"
SkipSpaces(&sz); SkipSpaces(&sz);
const char *szMe = sz; const char *szMe = sz;
while (!::IsSpaceOrNewLine(*sz)) { while (!IsSpaceOrNewLine(*sz)) {
sz++; sz++;
} }
size_t temp = (size_t)(sz - szMe); size_t temp = (size_t)(sz - szMe);
// setup the name of the node // setup the name of the node
if ( temp ) { if (temp) {
if (temp >= MAXLEN) { if (temp >= MAXLEN) {
throw DeadlyImportError("STL: Node name too long"); throw DeadlyImportError("STL: Node name too long");
} }
@ -303,7 +303,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
normalBuffer.emplace_back(vn); normalBuffer.emplace_back(vn);
normalBuffer.emplace_back(vn); normalBuffer.emplace_back(vn);
} }
} else if (!strncmp(sz, "vertex", 6) && ::IsSpaceOrNewLine(*(sz + 6))) { // vertex 1.50000 1.50000 0.00000 } else if (!strncmp(sz, "vertex", 6) && IsSpaceOrNewLine(*(sz + 6))) { // vertex 1.50000 1.50000 0.00000
if (faceVertexCounter >= 3) { if (faceVertexCounter >= 3) {
ASSIMP_LOG_ERROR("STL: a facet with more than 3 vertices has been found"); ASSIMP_LOG_ERROR("STL: a facet with more than 3 vertices has been found");
++sz; ++sz;
@ -325,14 +325,14 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
} else if (!::strncmp(sz, "endsolid", 8)) { } else if (!::strncmp(sz, "endsolid", 8)) {
do { do {
++sz; ++sz;
} while (!::IsLineEnd(*sz)); } while (!IsLineEnd(*sz));
SkipSpacesAndLineEnd(&sz); SkipSpacesAndLineEnd(&sz);
// finished! // finished!
break; break;
} else { // else skip the whole identifier } else { // else skip the whole identifier
do { do {
++sz; ++sz;
} while (!::IsSpaceOrNewLine(*sz)); } while (!IsSpaceOrNewLine(*sz));
} }
} }
@ -349,14 +349,14 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
throw DeadlyImportError("Normal buffer size does not match position buffer size"); throw DeadlyImportError("Normal buffer size does not match position buffer size");
} }
// only process positionbuffer when filled, else exception when accessing with index operator // only process position buffer when filled, else exception when accessing with index operator
// see line 353: only warning is triggered // see line 353: only warning is triggered
// see line 373(now): access to empty positionbuffer with index operator forced exception // see line 373(now): access to empty position buffer with index operator forced exception
if (!positionBuffer.empty()) { if (!positionBuffer.empty()) {
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3); pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size()); pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
for (size_t i=0; i<pMesh->mNumVertices; ++i ) { for (size_t i = 0; i < pMesh->mNumVertices; ++i) {
pMesh->mVertices[i].x = positionBuffer[i].x; pMesh->mVertices[i].x = positionBuffer[i].x;
pMesh->mVertices[i].y = positionBuffer[i].y; pMesh->mVertices[i].y = positionBuffer[i].y;
pMesh->mVertices[i].z = positionBuffer[i].z; pMesh->mVertices[i].z = positionBuffer[i].z;
@ -366,7 +366,7 @@ void STLImporter::LoadASCIIFile(aiNode *root) {
// also only process normalBuffer when filled, else exception when accessing with index operator // also only process normalBuffer when filled, else exception when accessing with index operator
if (!normalBuffer.empty()) { if (!normalBuffer.empty()) {
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
for (size_t i=0; i<pMesh->mNumVertices; ++i ) { for (size_t i = 0; i < pMesh->mNumVertices; ++i) {
pMesh->mNormals[i].x = normalBuffer[i].x; pMesh->mNormals[i].x = normalBuffer[i].x;
pMesh->mNormals[i].y = normalBuffer[i].y; pMesh->mNormals[i].y = normalBuffer[i].y;
pMesh->mNormals[i].z = normalBuffer[i].z; pMesh->mNormals[i].z = normalBuffer[i].z;
@ -450,9 +450,8 @@ bool STLImporter::LoadBinaryFile() {
aiVector3D *vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices]; aiVector3D *vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
aiVector3D *vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices]; aiVector3D *vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
typedef aiVector3t<float> aiVector3F; aiVector3f *theVec;
aiVector3F *theVec; aiVector3f theVec3F;
aiVector3F theVec3F;
for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) { for (unsigned int i = 0; i < pMesh->mNumFaces; ++i) {
// NOTE: Blender sometimes writes empty normals ... this is not // NOTE: Blender sometimes writes empty normals ... this is not
@ -460,8 +459,8 @@ bool STLImporter::LoadBinaryFile() {
// There's one normal for the face in the STL; use it three times // There's one normal for the face in the STL; use it three times
// for vertex normals // for vertex normals
theVec = (aiVector3F *)sz; theVec = (aiVector3f *)sz;
::memcpy(&theVec3F, theVec, sizeof(aiVector3F)); ::memcpy(&theVec3F, theVec, sizeof(aiVector3f));
vn->x = theVec3F.x; vn->x = theVec3F.x;
vn->y = theVec3F.y; vn->y = theVec3F.y;
vn->z = theVec3F.z; vn->z = theVec3F.z;
@ -471,7 +470,7 @@ bool STLImporter::LoadBinaryFile() {
vn += 3; vn += 3;
// vertex 1 // vertex 1
::memcpy(&theVec3F, theVec, sizeof(aiVector3F)); ::memcpy(&theVec3F, theVec, sizeof(aiVector3f));
vp->x = theVec3F.x; vp->x = theVec3F.x;
vp->y = theVec3F.y; vp->y = theVec3F.y;
vp->z = theVec3F.z; vp->z = theVec3F.z;
@ -479,7 +478,7 @@ bool STLImporter::LoadBinaryFile() {
++vp; ++vp;
// vertex 2 // vertex 2
::memcpy(&theVec3F, theVec, sizeof(aiVector3F)); ::memcpy(&theVec3F, theVec, sizeof(aiVector3f));
vp->x = theVec3F.x; vp->x = theVec3F.x;
vp->y = theVec3F.y; vp->y = theVec3F.y;
vp->z = theVec3F.z; vp->z = theVec3F.z;
@ -487,7 +486,7 @@ bool STLImporter::LoadBinaryFile() {
++vp; ++vp;
// vertex 3 // vertex 3
::memcpy(&theVec3F, theVec, sizeof(aiVector3F)); ::memcpy(&theVec3F, theVec, sizeof(aiVector3f));
vp->x = theVec3F.x; vp->x = theVec3F.x;
vp->y = theVec3F.y; vp->y = theVec3F.y;
vp->z = theVec3F.z; vp->z = theVec3F.z;
@ -570,4 +569,6 @@ void STLImporter::pushMeshesToNode(std::vector<unsigned int> &meshIndices, aiNod
meshIndices.clear(); meshIndices.clear();
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER #endif // !! ASSIMP_BUILD_NO_STL_IMPORTER

View File

@ -51,9 +51,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
using namespace Assimp; namespace Assimp {
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Terragen Heightmap Importer", "Terragen Heightmap Importer",
"", "",
"", "",
@ -73,10 +73,6 @@ TerragenImporter::TerragenImporter() :
// empty // empty
} }
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
TerragenImporter::~TerragenImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@ -244,4 +240,6 @@ void TerragenImporter::InternReadFile(const std::string &pFile,
pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN; pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_TERRAGEN_IMPORTER #endif // !! ASSIMP_BUILD_NO_TERRAGEN_IMPORTER

View File

@ -73,7 +73,7 @@ namespace Assimp {
class TerragenImporter : public BaseImporter { class TerragenImporter : public BaseImporter {
public: public:
TerragenImporter(); TerragenImporter();
~TerragenImporter() override; ~TerragenImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,

View File

@ -63,7 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
namespace Unreal { namespace Unreal {
@ -152,7 +152,7 @@ inline void DecompressVertex(aiVector3D &v, int32_t in) {
} // end namespace Unreal } // end namespace Unreal
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Unreal Mesh Importer", "Unreal Mesh Importer",
"", "",
"", "",
@ -178,7 +178,7 @@ UnrealImporter::~UnrealImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool UnrealImporter::CanRead(const std::string & filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const { bool UnrealImporter::CanRead(const std::string &filename, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(filename, "3d", "uc"); return SimpleExtensionCheck(filename, "3d", "uc");
} }
@ -336,12 +336,12 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
tempTextures.emplace_back(); tempTextures.emplace_back();
std::pair<std::string, std::string> &me = tempTextures.back(); std::pair<std::string, std::string> &me = tempTextures.back();
for (; !IsLineEnd(*data); ++data) { for (; !IsLineEnd(*data); ++data) {
if (!::ASSIMP_strincmp(data, "NAME=", 5)) { if (!ASSIMP_strincmp(data, "NAME=", 5)) {
const char *d = data += 5; const char *d = data += 5;
for (; !IsSpaceOrNewLine(*data); ++data) for (; !IsSpaceOrNewLine(*data); ++data)
; ;
me.first = std::string(d, (size_t)(data - d)); me.first = std::string(d, (size_t)(data - d));
} else if (!::ASSIMP_strincmp(data, "FILE=", 5)) { } else if (!ASSIMP_strincmp(data, "FILE=", 5)) {
const char *d = data += 5; const char *d = data += 5;
for (; !IsSpaceOrNewLine(*data); ++data) for (; !IsSpaceOrNewLine(*data); ++data)
; ;
@ -363,10 +363,10 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
std::pair<unsigned int, std::string> &me = textures.back(); std::pair<unsigned int, std::string> &me = textures.back();
for (; !IsLineEnd(*data); ++data) { for (; !IsLineEnd(*data); ++data) {
if (!::ASSIMP_strincmp(data, "NUM=", 4)) { if (!ASSIMP_strincmp(data, "NUM=", 4)) {
data += 4; data += 4;
me.first = strtoul10(data, &data); me.first = strtoul10(data, &data);
} else if (!::ASSIMP_strincmp(data, "TEXTURE=", 8)) { } else if (!ASSIMP_strincmp(data, "TEXTURE=", 8)) {
data += 8; data += 8;
const char *d = data; const char *d = data;
for (; !IsSpaceOrNewLine(*data); ++data) for (; !IsSpaceOrNewLine(*data); ++data)
@ -516,4 +516,6 @@ void UnrealImporter::InternReadFile(const std::string &pFile,
flipper.Execute(pScene); flipper.Execute(pScene);
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3D_IMPORTER #endif // !! ASSIMP_BUILD_NO_3D_IMPORTER

View File

@ -57,10 +57,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cctype> #include <cctype>
#include <memory> #include <memory>
using namespace Assimp; namespace Assimp {
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"Direct3D XFile Importer", "Direct3D XFile Importer",
"", "",
"", "",
@ -73,142 +74,137 @@ static const aiImporterDesc desc = {
"x" "x"
}; };
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
XFileImporter::XFileImporter() = default;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const { bool XFileImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const uint32_t token[] = { AI_MAKE_MAGIC("xof ") }; static const uint32_t token[] = { AI_MAKE_MAGIC("xof ") };
return CheckMagicToken(pIOHandler,pFile,token,AI_COUNT_OF(token)); return CheckMagicToken(pIOHandler, pFile, token, AI_COUNT_OF(token));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get file extension list // Get file extension list
const aiImporterDesc* XFileImporter::GetInfo () const { const aiImporterDesc *XFileImporter::GetInfo() const {
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) { void XFileImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
// read file into memory // read file into memory
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile)); std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
if (file == nullptr) { if (file == nullptr) {
throw DeadlyImportError( "Failed to open file ", pFile, "." ); throw DeadlyImportError("Failed to open file ", pFile, ".");
} }
static const size_t MinSize = 16; static const size_t MinSize = 16;
size_t fileSize = file->FileSize(); size_t fileSize = file->FileSize();
if ( fileSize < MinSize ) { if (fileSize < MinSize) {
throw DeadlyImportError( "XFile is too small." ); throw DeadlyImportError("XFile is too small.");
} }
// in the hope that binary files will never start with a BOM ... // in the hope that binary files will never start with a BOM ...
mBuffer.resize( fileSize + 1); mBuffer.resize(fileSize + 1);
file->Read( &mBuffer.front(), 1, fileSize); file->Read(&mBuffer.front(), 1, fileSize);
ConvertToUTF8(mBuffer); ConvertToUTF8(mBuffer);
// parse the file into a temporary representation // parse the file into a temporary representation
XFileParser parser( mBuffer); XFileParser parser(mBuffer);
// and create the proper return structures out of it // and create the proper return structures out of it
CreateDataRepresentationFromImport( pScene, parser.GetImportedData()); CreateDataRepresentationFromImport(pScene, parser.GetImportedData());
// if nothing came from it, report it as error // if nothing came from it, report it as error
if ( !pScene->mRootNode ) { if (!pScene->mRootNode) {
throw DeadlyImportError( "XFile is ill-formatted - no content imported." ); throw DeadlyImportError("XFile is ill-formatted - no content imported.");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructs the return data structure out of the imported data. // Constructs the return data structure out of the imported data.
void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData) void XFileImporter::CreateDataRepresentationFromImport(aiScene *pScene, XFile::Scene *pData) {
{
// Read the global materials first so that meshes referring to them can find them later // Read the global materials first so that meshes referring to them can find them later
ConvertMaterials( pScene, pData->mGlobalMaterials); ConvertMaterials(pScene, pData->mGlobalMaterials);
// copy nodes, extracting meshes and materials on the way // copy nodes, extracting meshes and materials on the way
pScene->mRootNode = CreateNodes( pScene, nullptr, pData->mRootNode); pScene->mRootNode = CreateNodes(pScene, nullptr, pData->mRootNode);
// extract animations // extract animations
CreateAnimations( pScene, pData); CreateAnimations(pScene, pData);
// read the global meshes that were stored outside of any node // read the global meshes that were stored outside of any node
if( !pData->mGlobalMeshes.empty() ) { if (!pData->mGlobalMeshes.empty()) {
// create a root node to hold them if there isn't any, yet // create a root node to hold them if there isn't any, yet
if( pScene->mRootNode == nullptr ) { if (pScene->mRootNode == nullptr) {
pScene->mRootNode = new aiNode; pScene->mRootNode = new aiNode;
pScene->mRootNode->mName.Set( "$dummy_node"); pScene->mRootNode->mName.Set("$dummy_node");
} }
// convert all global meshes and store them in the root node. // convert all global meshes and store them in the root node.
// If there was one before, the global meshes now suddenly have its transformation matrix... // If there was one before, the global meshes now suddenly have its transformation matrix...
// Don't know what to do there, I don't want to insert another node under the present root node // Don't know what to do there, I don't want to insert another node under the present root node
// just to avoid this. // just to avoid this.
CreateMeshes( pScene, pScene->mRootNode, pData->mGlobalMeshes); CreateMeshes(pScene, pScene->mRootNode, pData->mGlobalMeshes);
} }
if (!pScene->mRootNode) { if (!pScene->mRootNode) {
throw DeadlyImportError( "No root node" ); throw DeadlyImportError("No root node");
} }
// Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
MakeLeftHandedProcess convertProcess; MakeLeftHandedProcess convertProcess;
convertProcess.Execute( pScene); convertProcess.Execute(pScene);
FlipWindingOrderProcess flipper; FlipWindingOrderProcess flipper;
flipper.Execute(pScene); flipper.Execute(pScene);
// finally: create a dummy material if not material was imported // finally: create a dummy material if not material was imported
if( pScene->mNumMaterials == 0) { if (pScene->mNumMaterials == 0) {
pScene->mNumMaterials = 1; pScene->mNumMaterials = 1;
// create the Material // create the Material
aiMaterial* mat = new aiMaterial; aiMaterial *mat = new aiMaterial;
int shadeMode = (int) aiShadingMode_Gouraud; int shadeMode = (int)aiShadingMode_Gouraud;
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL); mat->AddProperty<int>(&shadeMode, 1, AI_MATKEY_SHADING_MODEL);
// material colours // material colours
int specExp = 1; int specExp = 1;
aiColor3D clr = aiColor3D( 0, 0, 0); aiColor3D clr = aiColor3D(0, 0, 0);
mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_EMISSIVE); mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_EMISSIVE);
mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_SPECULAR); mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
clr = aiColor3D( 0.5f, 0.5f, 0.5f); clr = aiColor3D(0.5f, 0.5f, 0.5f);
mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS); mat->AddProperty(&specExp, 1, AI_MATKEY_SHININESS);
pScene->mMaterials = new aiMaterial*[1]; pScene->mMaterials = new aiMaterial *[1];
pScene->mMaterials[0] = mat; pScene->mMaterials[0] = mat;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively creates scene nodes from the imported hierarchy. // Recursively creates scene nodes from the imported hierarchy.
aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFile::Node* pNode) { aiNode *XFileImporter::CreateNodes(aiScene *pScene, aiNode *pParent, const XFile::Node *pNode) {
if ( !pNode ) { if (!pNode) {
return nullptr; return nullptr;
} }
// create node // create node
aiNode* node = new aiNode; aiNode *node = new aiNode;
node->mName.length = (ai_uint32)pNode->mName.length(); node->mName.length = (ai_uint32)pNode->mName.length();
node->mParent = pParent; node->mParent = pParent;
memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length()); memcpy(node->mName.data, pNode->mName.c_str(), pNode->mName.length());
node->mName.data[node->mName.length] = 0; node->mName.data[node->mName.length] = 0;
node->mTransformation = pNode->mTrafoMatrix; node->mTransformation = pNode->mTrafoMatrix;
// convert meshes from the source node // convert meshes from the source node
CreateMeshes( pScene, node, pNode->mMeshes); CreateMeshes(pScene, node, pNode->mMeshes);
// handle children // handle children
if( !pNode->mChildren.empty() ) { if (!pNode->mChildren.empty()) {
node->mNumChildren = (unsigned int)pNode->mChildren.size(); node->mNumChildren = (unsigned int)pNode->mChildren.size();
node->mChildren = new aiNode* [node->mNumChildren]; node->mChildren = new aiNode *[node->mNumChildren];
for ( unsigned int a = 0; a < pNode->mChildren.size(); ++a ) { for (unsigned int a = 0; a < pNode->mChildren.size(); ++a) {
node->mChildren[ a ] = CreateNodes( pScene, node, pNode->mChildren[ a ] ); node->mChildren[a] = CreateNodes(pScene, node, pNode->mChildren[a]);
} }
} }
@ -217,55 +213,55 @@ aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFil
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the meshes for the given node. // Creates the meshes for the given node.
void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vector<XFile::Mesh*>& pMeshes) { void XFileImporter::CreateMeshes(aiScene *pScene, aiNode *pNode, const std::vector<XFile::Mesh *> &pMeshes) {
if (pMeshes.empty()) { if (pMeshes.empty()) {
return; return;
} }
// create a mesh for each mesh-material combination in the source node // create a mesh for each mesh-material combination in the source node
std::vector<aiMesh*> meshes; std::vector<aiMesh *> meshes;
for( unsigned int a = 0; a < pMeshes.size(); ++a ) { for (unsigned int a = 0; a < pMeshes.size(); ++a) {
XFile::Mesh* sourceMesh = pMeshes[a]; XFile::Mesh *sourceMesh = pMeshes[a];
if ( nullptr == sourceMesh ) { if (nullptr == sourceMesh) {
continue; continue;
} }
// first convert its materials so that we can find them with their index afterwards // first convert its materials so that we can find them with their index afterwards
ConvertMaterials( pScene, sourceMesh->mMaterials); ConvertMaterials(pScene, sourceMesh->mMaterials);
unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u); unsigned int numMaterials = std::max((unsigned int)sourceMesh->mMaterials.size(), 1u);
for( unsigned int b = 0; b < numMaterials; ++b ) { for (unsigned int b = 0; b < numMaterials; ++b) {
// collect the faces belonging to this material // collect the faces belonging to this material
std::vector<unsigned int> faces; std::vector<unsigned int> faces;
unsigned int numVertices = 0; unsigned int numVertices = 0;
if( !sourceMesh->mFaceMaterials.empty() ) { if (!sourceMesh->mFaceMaterials.empty()) {
// if there is a per-face material defined, select the faces with the corresponding material // if there is a per-face material defined, select the faces with the corresponding material
for( unsigned int c = 0; c < sourceMesh->mFaceMaterials.size(); ++c ) { for (unsigned int c = 0; c < sourceMesh->mFaceMaterials.size(); ++c) {
if( sourceMesh->mFaceMaterials[c] == b) { if (sourceMesh->mFaceMaterials[c] == b) {
faces.push_back( c); faces.push_back(c);
numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size(); numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
} }
} }
} else { } else {
// if there is no per-face material, place everything into one mesh // if there is no per-face material, place everything into one mesh
for( unsigned int c = 0; c < sourceMesh->mPosFaces.size(); ++c ) { for (unsigned int c = 0; c < sourceMesh->mPosFaces.size(); ++c) {
faces.push_back( c); faces.push_back(c);
numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size(); numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
} }
} }
// no faces/vertices using this material? strange... // no faces/vertices using this material? strange...
if ( numVertices == 0 ) { if (numVertices == 0) {
continue; continue;
} }
// create a submesh using this material // create a submesh using this material
aiMesh* mesh = new aiMesh; aiMesh *mesh = new aiMesh;
meshes.push_back( mesh); meshes.push_back(mesh);
// find the material in the scene's material list. Either own material // find the material in the scene's material list. Either own material
// or referenced material, it should already have a valid index // or referenced material, it should already have a valid index
if( !sourceMesh->mFaceMaterials.empty() ) { if (!sourceMesh->mFaceMaterials.empty()) {
mesh->mMaterialIndex = static_cast<unsigned int>(sourceMesh->mMaterials[b].sceneIndex); mesh->mMaterialIndex = static_cast<unsigned int>(sourceMesh->mMaterials[b].sceneIndex);
} else { } else {
mesh->mMaterialIndex = 0; mesh->mMaterialIndex = 0;
@ -282,41 +278,41 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
mesh->mName.Set(sourceMesh->mName); mesh->mName.Set(sourceMesh->mName);
// normals? // normals?
if ( sourceMesh->mNormals.size() > 0 ) { if (sourceMesh->mNormals.size() > 0) {
mesh->mNormals = new aiVector3D[ numVertices ]; mesh->mNormals = new aiVector3D[numVertices];
} }
// texture coords // texture coords
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c ) { for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) {
if ( !sourceMesh->mTexCoords[ c ].empty() ) { if (!sourceMesh->mTexCoords[c].empty()) {
mesh->mTextureCoords[ c ] = new aiVector3D[ numVertices ]; mesh->mTextureCoords[c] = new aiVector3D[numVertices];
} }
} }
// vertex colors // vertex colors
for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c ) { for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
if ( !sourceMesh->mColors[ c ].empty() ) { if (!sourceMesh->mColors[c].empty()) {
mesh->mColors[ c ] = new aiColor4D[ numVertices ]; mesh->mColors[c] = new aiColor4D[numVertices];
} }
} }
// now collect the vertex data of all data streams present in the imported mesh // now collect the vertex data of all data streams present in the imported mesh
unsigned int newIndex( 0 ); unsigned int newIndex(0);
std::vector<unsigned int> orgPoints; // from which original point each new vertex stems std::vector<unsigned int> orgPoints; // from which original point each new vertex stems
orgPoints.resize( numVertices, 0); orgPoints.resize(numVertices, 0);
for( unsigned int c = 0; c < faces.size(); ++c ) { for (unsigned int c = 0; c < faces.size(); ++c) {
unsigned int f = faces[c]; // index of the source face unsigned int f = faces[c]; // index of the source face
const XFile::Face& pf = sourceMesh->mPosFaces[f]; // position source face const XFile::Face &pf = sourceMesh->mPosFaces[f]; // position source face
// create face. either triangle or triangle fan depending on the index count // create face. either triangle or triangle fan depending on the index count
aiFace& df = mesh->mFaces[c]; // destination face aiFace &df = mesh->mFaces[c]; // destination face
df.mNumIndices = (unsigned int)pf.mIndices.size(); df.mNumIndices = (unsigned int)pf.mIndices.size();
df.mIndices = new unsigned int[ df.mNumIndices]; df.mIndices = new unsigned int[df.mNumIndices];
// collect vertex data for indices of this face // collect vertex data for indices of this face
for( unsigned int d = 0; d < df.mNumIndices; ++d ) { for (unsigned int d = 0; d < df.mNumIndices; ++d) {
df.mIndices[ d ] = newIndex; df.mIndices[d] = newIndex;
const unsigned int newIdx( pf.mIndices[ d ] ); const unsigned int newIdx = pf.mIndices[d];
if ( newIdx > sourceMesh->mPositions.size() ) { if (newIdx >= sourceMesh->mPositions.size()) {
continue; continue;
} }
@ -325,24 +321,26 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
// Position // Position
mesh->mVertices[newIndex] = sourceMesh->mPositions[pf.mIndices[d]]; mesh->mVertices[newIndex] = sourceMesh->mPositions[pf.mIndices[d]];
// Normal, if present // Normal, if present
if ( mesh->HasNormals() ) { if (mesh->HasNormals()) {
if ( sourceMesh->mNormFaces[ f ].mIndices.size() > d ) { if (sourceMesh->mNormFaces[f].mIndices.size() > d) {
const size_t idx( sourceMesh->mNormFaces[ f ].mIndices[ d ] ); const size_t idx(sourceMesh->mNormFaces[f].mIndices[d]);
mesh->mNormals[ newIndex ] = sourceMesh->mNormals[ idx ]; if (idx < sourceMesh->mNormals.size()) {
mesh->mNormals[newIndex] = sourceMesh->mNormals[idx];
}
} }
} }
// texture coord sets // texture coord sets
for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++e ) { for (unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++e) {
if( mesh->HasTextureCoords( e)) { if (mesh->HasTextureCoords(e)) {
aiVector2D tex = sourceMesh->mTexCoords[e][pf.mIndices[d]]; aiVector2D tex = sourceMesh->mTexCoords[e][pf.mIndices[d]];
mesh->mTextureCoords[e][newIndex] = aiVector3D( tex.x, 1.0f - tex.y, 0.0f); mesh->mTextureCoords[e][newIndex] = aiVector3D(tex.x, 1.0f - tex.y, 0.0f);
} }
} }
// vertex color sets // vertex color sets
for ( unsigned int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; ++e ) { for (unsigned int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; ++e) {
if ( mesh->HasVertexColors( e ) ) { if (mesh->HasVertexColors(e)) {
mesh->mColors[ e ][ newIndex ] = sourceMesh->mColors[ e ][ pf.mIndices[ d ] ]; mesh->mColors[e][newIndex] = sourceMesh->mColors[e][pf.mIndices[d]];
} }
} }
@ -351,63 +349,66 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
} }
// there should be as much new vertices as we calculated before // there should be as much new vertices as we calculated before
ai_assert( newIndex == numVertices); ai_assert(newIndex == numVertices);
// convert all bones of the source mesh which influence vertices in this newly created mesh // convert all bones of the source mesh which influence vertices in this newly created mesh
const std::vector<XFile::Bone>& bones = sourceMesh->mBones; const std::vector<XFile::Bone> &bones = sourceMesh->mBones;
std::vector<aiBone*> newBones; std::vector<aiBone *> newBones;
for( unsigned int c = 0; c < bones.size(); ++c ) { for (unsigned int c = 0; c < bones.size(); ++c) {
const XFile::Bone& obone = bones[c]; const XFile::Bone &obone = bones[c];
// set up a vertex-linear array of the weights for quick searching if a bone influences a vertex // set up a vertex-linear array of the weights for quick searching if a bone influences a vertex
std::vector<ai_real> oldWeights( sourceMesh->mPositions.size(), 0.0); std::vector<ai_real> oldWeights(sourceMesh->mPositions.size(), 0.0);
for ( unsigned int d = 0; d < obone.mWeights.size(); ++d ) { for (unsigned int d = 0; d < obone.mWeights.size(); ++d) {
oldWeights[ obone.mWeights[ d ].mVertex ] = obone.mWeights[ d ].mWeight; const unsigned int boneIdx = obone.mWeights[d].mVertex;
if (boneIdx < obone.mWeights.size()) {
oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight;
}
} }
// collect all vertex weights that influence a vertex in the new mesh // collect all vertex weights that influence a vertex in the new mesh
std::vector<aiVertexWeight> newWeights; std::vector<aiVertexWeight> newWeights;
newWeights.reserve( numVertices); newWeights.reserve(numVertices);
for( unsigned int d = 0; d < orgPoints.size(); ++d ) { for (unsigned int d = 0; d < orgPoints.size(); ++d) {
// does the new vertex stem from an old vertex which was influenced by this bone? // does the new vertex stem from an old vertex which was influenced by this bone?
ai_real w = oldWeights[orgPoints[d]]; ai_real w = oldWeights[orgPoints[d]];
if ( w > 0.0 ) { if (w > 0.0) {
newWeights.emplace_back( d, w ); newWeights.emplace_back(d, w);
} }
} }
// if the bone has no weights in the newly created mesh, ignore it // if the bone has no weights in the newly created mesh, ignore it
if ( newWeights.empty() ) { if (newWeights.empty()) {
continue; continue;
} }
// create // create
aiBone* nbone = new aiBone; aiBone *nbone = new aiBone;
newBones.push_back( nbone); newBones.push_back(nbone);
// copy name and matrix // copy name and matrix
nbone->mName.Set( obone.mName); nbone->mName.Set(obone.mName);
nbone->mOffsetMatrix = obone.mOffsetMatrix; nbone->mOffsetMatrix = obone.mOffsetMatrix;
nbone->mNumWeights = (unsigned int)newWeights.size(); nbone->mNumWeights = (unsigned int)newWeights.size();
nbone->mWeights = new aiVertexWeight[nbone->mNumWeights]; nbone->mWeights = new aiVertexWeight[nbone->mNumWeights];
for ( unsigned int d = 0; d < newWeights.size(); ++d ) { for (unsigned int d = 0; d < newWeights.size(); ++d) {
nbone->mWeights[ d ] = newWeights[ d ]; nbone->mWeights[d] = newWeights[d];
} }
} }
// store the bones in the mesh // store the bones in the mesh
mesh->mNumBones = (unsigned int)newBones.size(); mesh->mNumBones = (unsigned int)newBones.size();
if( !newBones.empty()) { if (!newBones.empty()) {
mesh->mBones = new aiBone*[mesh->mNumBones]; mesh->mBones = new aiBone *[mesh->mNumBones];
std::copy( newBones.begin(), newBones.end(), mesh->mBones); std::copy(newBones.begin(), newBones.end(), mesh->mBones);
} }
} }
} }
// reallocate scene mesh array to be large enough // reallocate scene mesh array to be large enough
aiMesh** prevArray = pScene->mMeshes; aiMesh **prevArray = pScene->mMeshes;
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes + meshes.size()]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes + meshes.size()];
if( prevArray) { if (prevArray) {
memcpy( pScene->mMeshes, prevArray, pScene->mNumMeshes * sizeof( aiMesh*)); memcpy(pScene->mMeshes, prevArray, pScene->mNumMeshes * sizeof(aiMesh *));
delete [] prevArray; delete[] prevArray;
} }
// allocate mesh index array in the node // allocate mesh index array in the node
@ -415,7 +416,7 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
// store all meshes in the mesh library of the scene and store their indices in the node // store all meshes in the mesh library of the scene and store their indices in the node
for( unsigned int a = 0; a < meshes.size(); a++) { for (unsigned int a = 0; a < meshes.size(); a++) {
pScene->mMeshes[pScene->mNumMeshes] = meshes[a]; pScene->mMeshes[pScene->mNumMeshes] = meshes[a];
pNode->mMeshes[a] = pScene->mNumMeshes; pNode->mMeshes[a] = pScene->mNumMeshes;
pScene->mNumMeshes++; pScene->mNumMeshes++;
@ -424,35 +425,34 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts the animations from the given imported data and creates them in the scene. // Converts the animations from the given imported data and creates them in the scene.
void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData) { void XFileImporter::CreateAnimations(aiScene *pScene, const XFile::Scene *pData) {
std::vector<aiAnimation*> newAnims; std::vector<aiAnimation *> newAnims;
for( unsigned int a = 0; a < pData->mAnims.size(); ++a ) { for (unsigned int a = 0; a < pData->mAnims.size(); ++a) {
const XFile::Animation* anim = pData->mAnims[a]; const XFile::Animation *anim = pData->mAnims[a];
// some exporters mock me with empty animation tags. // some exporters mock me with empty animation tags.
if ( anim->mAnims.empty() ) { if (anim->mAnims.empty()) {
continue; continue;
} }
// create a new animation to hold the data // create a new animation to hold the data
aiAnimation* nanim = new aiAnimation; aiAnimation *nanim = new aiAnimation;
newAnims.push_back( nanim); newAnims.push_back(nanim);
nanim->mName.Set( anim->mName); nanim->mName.Set(anim->mName);
// duration will be determined by the maximum length // duration will be determined by the maximum length
nanim->mDuration = 0; nanim->mDuration = 0;
nanim->mTicksPerSecond = pData->mAnimTicksPerSecond; nanim->mTicksPerSecond = pData->mAnimTicksPerSecond;
nanim->mNumChannels = (unsigned int)anim->mAnims.size(); nanim->mNumChannels = (unsigned int)anim->mAnims.size();
nanim->mChannels = new aiNodeAnim*[nanim->mNumChannels]; nanim->mChannels = new aiNodeAnim *[nanim->mNumChannels];
for( unsigned int b = 0; b < anim->mAnims.size(); ++b ) { for (unsigned int b = 0; b < anim->mAnims.size(); ++b) {
const XFile::AnimBone* bone = anim->mAnims[b]; const XFile::AnimBone *bone = anim->mAnims[b];
aiNodeAnim* nbone = new aiNodeAnim; aiNodeAnim *nbone = new aiNodeAnim;
nbone->mNodeName.Set( bone->mBoneName); nbone->mNodeName.Set(bone->mBoneName);
nanim->mChannels[b] = nbone; nanim->mChannels[b] = nbone;
// key-frames are given as combined transformation matrix keys // key-frames are given as combined transformation matrix keys
if( !bone->mTrafoKeys.empty() ) if (!bone->mTrafoKeys.empty()) {
{
nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size(); nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys]; nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
nbone->mNumRotationKeys = (unsigned int)bone->mTrafoKeys.size(); nbone->mNumRotationKeys = (unsigned int)bone->mTrafoKeys.size();
@ -460,44 +460,44 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
nbone->mNumScalingKeys = (unsigned int)bone->mTrafoKeys.size(); nbone->mNumScalingKeys = (unsigned int)bone->mTrafoKeys.size();
nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys]; nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
for( unsigned int c = 0; c < bone->mTrafoKeys.size(); ++c) { for (unsigned int c = 0; c < bone->mTrafoKeys.size(); ++c) {
// deconstruct each matrix into separate position, rotation and scaling // deconstruct each matrix into separate position, rotation and scaling
double time = bone->mTrafoKeys[c].mTime; double time = bone->mTrafoKeys[c].mTime;
aiMatrix4x4 trafo = bone->mTrafoKeys[c].mMatrix; aiMatrix4x4 trafo = bone->mTrafoKeys[c].mMatrix;
// extract position // extract position
aiVector3D pos( trafo.a4, trafo.b4, trafo.c4); aiVector3D pos(trafo.a4, trafo.b4, trafo.c4);
nbone->mPositionKeys[c].mTime = time; nbone->mPositionKeys[c].mTime = time;
nbone->mPositionKeys[c].mValue = pos; nbone->mPositionKeys[c].mValue = pos;
// extract scaling // extract scaling
aiVector3D scale; aiVector3D scale;
scale.x = aiVector3D( trafo.a1, trafo.b1, trafo.c1).Length(); scale.x = aiVector3D(trafo.a1, trafo.b1, trafo.c1).Length();
scale.y = aiVector3D( trafo.a2, trafo.b2, trafo.c2).Length(); scale.y = aiVector3D(trafo.a2, trafo.b2, trafo.c2).Length();
scale.z = aiVector3D( trafo.a3, trafo.b3, trafo.c3).Length(); scale.z = aiVector3D(trafo.a3, trafo.b3, trafo.c3).Length();
nbone->mScalingKeys[c].mTime = time; nbone->mScalingKeys[c].mTime = time;
nbone->mScalingKeys[c].mValue = scale; nbone->mScalingKeys[c].mValue = scale;
// reconstruct rotation matrix without scaling // reconstruct rotation matrix without scaling
aiMatrix3x3 rotmat( aiMatrix3x3 rotmat(
trafo.a1 / scale.x, trafo.a2 / scale.y, trafo.a3 / scale.z, trafo.a1 / scale.x, trafo.a2 / scale.y, trafo.a3 / scale.z,
trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z, trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z,
trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z); trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z);
// and convert it into a quaternion // and convert it into a quaternion
nbone->mRotationKeys[c].mTime = time; nbone->mRotationKeys[c].mTime = time;
nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat); nbone->mRotationKeys[c].mValue = aiQuaternion(rotmat);
} }
// longest lasting key sequence determines duration // longest lasting key sequence determines duration
nanim->mDuration = std::max( nanim->mDuration, bone->mTrafoKeys.back().mTime); nanim->mDuration = std::max(nanim->mDuration, bone->mTrafoKeys.back().mTime);
} else { } else {
// separate key sequences for position, rotation, scaling // separate key sequences for position, rotation, scaling
nbone->mNumPositionKeys = (unsigned int)bone->mPosKeys.size(); nbone->mNumPositionKeys = (unsigned int)bone->mPosKeys.size();
if (nbone->mNumPositionKeys != 0) { if (nbone->mNumPositionKeys != 0) {
nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys]; nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
for( unsigned int c = 0; c < nbone->mNumPositionKeys; ++c ) { for (unsigned int c = 0; c < nbone->mNumPositionKeys; ++c) {
aiVector3D pos = bone->mPosKeys[c].mValue; aiVector3D pos = bone->mPosKeys[c].mValue;
nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime; nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime;
@ -509,11 +509,11 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
nbone->mNumRotationKeys = (unsigned int)bone->mRotKeys.size(); nbone->mNumRotationKeys = (unsigned int)bone->mRotKeys.size();
if (nbone->mNumRotationKeys != 0) { if (nbone->mNumRotationKeys != 0) {
nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys]; nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
for( unsigned int c = 0; c < nbone->mNumRotationKeys; ++c ) { for (unsigned int c = 0; c < nbone->mNumRotationKeys; ++c) {
aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix(); aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix();
nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime; nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime;
nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat); nbone->mRotationKeys[c].mValue = aiQuaternion(rotmat);
nbone->mRotationKeys[c].mValue.w *= -1.0f; // needs quat inversion nbone->mRotationKeys[c].mValue.w *= -1.0f; // needs quat inversion
} }
} }
@ -522,153 +522,149 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
nbone->mNumScalingKeys = (unsigned int)bone->mScaleKeys.size(); nbone->mNumScalingKeys = (unsigned int)bone->mScaleKeys.size();
if (nbone->mNumScalingKeys != 0) { if (nbone->mNumScalingKeys != 0) {
nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys]; nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
for( unsigned int c = 0; c < nbone->mNumScalingKeys; c++) for (unsigned int c = 0; c < nbone->mNumScalingKeys; c++)
nbone->mScalingKeys[c] = bone->mScaleKeys[c]; nbone->mScalingKeys[c] = bone->mScaleKeys[c];
} }
// longest lasting key sequence determines duration // longest lasting key sequence determines duration
if( bone->mPosKeys.size() > 0) if (bone->mPosKeys.size() > 0)
nanim->mDuration = std::max( nanim->mDuration, bone->mPosKeys.back().mTime); nanim->mDuration = std::max(nanim->mDuration, bone->mPosKeys.back().mTime);
if( bone->mRotKeys.size() > 0) if (bone->mRotKeys.size() > 0)
nanim->mDuration = std::max( nanim->mDuration, bone->mRotKeys.back().mTime); nanim->mDuration = std::max(nanim->mDuration, bone->mRotKeys.back().mTime);
if( bone->mScaleKeys.size() > 0) if (bone->mScaleKeys.size() > 0)
nanim->mDuration = std::max( nanim->mDuration, bone->mScaleKeys.back().mTime); nanim->mDuration = std::max(nanim->mDuration, bone->mScaleKeys.back().mTime);
} }
} }
} }
// store all converted animations in the scene // store all converted animations in the scene
if( newAnims.size() > 0) if (newAnims.size() > 0) {
{
pScene->mNumAnimations = (unsigned int)newAnims.size(); pScene->mNumAnimations = (unsigned int)newAnims.size();
pScene->mAnimations = new aiAnimation* [pScene->mNumAnimations]; pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations];
for( unsigned int a = 0; a < newAnims.size(); a++) for (unsigned int a = 0; a < newAnims.size(); a++)
pScene->mAnimations[a] = newAnims[a]; pScene->mAnimations[a] = newAnims[a];
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts all materials in the given array and stores them in the scene's material list. // Converts all materials in the given array and stores them in the scene's material list.
void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials) void XFileImporter::ConvertMaterials(aiScene *pScene, std::vector<XFile::Material> &pMaterials) {
{
// count the non-referrer materials in the array // count the non-referrer materials in the array
unsigned int numNewMaterials( 0 ); unsigned int numNewMaterials(0);
for ( unsigned int a = 0; a < pMaterials.size(); ++a ) { for (unsigned int a = 0; a < pMaterials.size(); ++a) {
if ( !pMaterials[ a ].mIsReference ) { if (!pMaterials[a].mIsReference) {
++numNewMaterials; ++numNewMaterials;
} }
} }
// resize the scene's material list to offer enough space for the new materials // resize the scene's material list to offer enough space for the new materials
if( numNewMaterials > 0 ) { if (numNewMaterials > 0) {
aiMaterial** prevMats = pScene->mMaterials; aiMaterial **prevMats = pScene->mMaterials;
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numNewMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials + numNewMaterials];
if( nullptr != prevMats) { if (nullptr != prevMats) {
::memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*)); ::memcpy(pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof(aiMaterial *));
delete [] prevMats; delete[] prevMats;
} }
} }
// convert all the materials given in the array // convert all the materials given in the array
for( unsigned int a = 0; a < pMaterials.size(); ++a ) { for (unsigned int a = 0; a < pMaterials.size(); ++a) {
XFile::Material& oldMat = pMaterials[a]; XFile::Material &oldMat = pMaterials[a];
if( oldMat.mIsReference) { if (oldMat.mIsReference) {
// find the material it refers to by name, and store its index // find the material it refers to by name, and store its index
for( size_t b = 0; b < pScene->mNumMaterials; ++b ) { for (size_t b = 0; b < pScene->mNumMaterials; ++b) {
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 = b; oldMat.sceneIndex = b;
break; break;
} }
} }
if( oldMat.sceneIndex == SIZE_MAX ) { if (oldMat.sceneIndex == SIZE_MAX) {
ASSIMP_LOG_WARN( "Could not resolve global material reference \"", oldMat.mName, "\"" ); ASSIMP_LOG_WARN("Could not resolve global material reference \"", oldMat.mName, "\"");
oldMat.sceneIndex = 0; oldMat.sceneIndex = 0;
} }
continue; continue;
} }
aiMaterial* mat = new aiMaterial; aiMaterial *mat = new aiMaterial;
aiString name; aiString name;
name.Set( oldMat.mName); name.Set(oldMat.mName);
mat->AddProperty( &name, AI_MATKEY_NAME); mat->AddProperty(&name, AI_MATKEY_NAME);
// Shading model: hard-coded to PHONG, there is no such information in an XFile // Shading model: hard-coded to PHONG, there is no such information in an XFile
// FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix // FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix
// for some models in the SDK (e.g. good old tiny.x) // for some models in the SDK (e.g. good old tiny.x)
int shadeMode = (int)oldMat.mSpecularExponent == 0.0f int shadeMode = (int)oldMat.mSpecularExponent == 0.0f ? aiShadingMode_Gouraud : aiShadingMode_Phong;
? aiShadingMode_Gouraud : aiShadingMode_Phong;
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL); mat->AddProperty<int>(&shadeMode, 1, AI_MATKEY_SHADING_MODEL);
// material colours // material colours
// Unclear: there's no ambient colour, but emissive. What to put for ambient? // Unclear: there's no ambient colour, but emissive. What to put for ambient?
// Probably nothing at all, let the user select a suitable default. // Probably nothing at all, let the user select a suitable default.
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); mat->AddProperty(&oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); mat->AddProperty(&oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS); mat->AddProperty(&oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
// texture, if there is one // texture, if there is one
if (1 == oldMat.mTextures.size() ) { if (1 == oldMat.mTextures.size()) {
const XFile::TexEntry& otex = oldMat.mTextures.back(); const XFile::TexEntry &otex = oldMat.mTextures.back();
if (otex.mName.length()) { if (otex.mName.length()) {
// if there is only one texture assume it contains the diffuse color // if there is only one texture assume it contains the diffuse color
aiString tex( otex.mName); aiString tex(otex.mName);
if ( otex.mIsNormalMap ) { if (otex.mIsNormalMap) {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS( 0 ) ); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_NORMALS(0));
} else { } else {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
} }
} else { } else {
// Otherwise ... try to search for typical strings in the // Otherwise ... try to search for typical strings in the
// texture's file name like 'bump' or 'diffuse' // texture's file name like 'bump' or 'diffuse'
unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0; unsigned int iHM = 0, iNM = 0, iDM = 0, iSM = 0, iAM = 0, iEM = 0;
for( unsigned int b = 0; b < oldMat.mTextures.size(); ++b ) { for (unsigned int b = 0; b < oldMat.mTextures.size(); ++b) {
const XFile::TexEntry& otex = oldMat.mTextures[b]; const XFile::TexEntry &otex = oldMat.mTextures[b];
std::string sz = otex.mName; std::string sz = otex.mName;
if ( !sz.length() ) { if (!sz.length()) {
continue; continue;
} }
// find the file name // find the file name
std::string::size_type s = sz.find_last_of("\\/"); std::string::size_type s = sz.find_last_of("\\/");
if ( std::string::npos == s ) { if (std::string::npos == s) {
s = 0; s = 0;
} }
// cut off the file extension // cut off the file extension
std::string::size_type sExt = sz.find_last_of('.'); std::string::size_type sExt = sz.find_last_of('.');
if (std::string::npos != sExt){ if (std::string::npos != sExt) {
sz[sExt] = '\0'; sz[sExt] = '\0';
} }
// convert to lower case for easier comparison // convert to lower case for easier comparison
for ( unsigned int c = 0; c < sz.length(); ++c ) { for (unsigned int c = 0; c < sz.length(); ++c) {
sz[ c ] = (char) tolower( (unsigned char) sz[ c ] ); sz[c] = (char)tolower((unsigned char)sz[c]);
} }
// Place texture filename property under the corresponding name // Place texture filename property under the corresponding name
aiString tex( oldMat.mTextures[b].mName); aiString tex(oldMat.mTextures[b].mName);
// bump map // bump map
if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s)) { if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s)) {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++)); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++));
} else if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s)) { } else if (otex.mIsNormalMap || std::string::npos != sz.find("normal", s) || std::string::npos != sz.find("nm", s)) {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(iNM++)); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_NORMALS(iNM++));
} else if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s)) { } else if (std::string::npos != sz.find("spec", s) || std::string::npos != sz.find("glanz", s)) {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++)); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++));
} else if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s)) { } else if (std::string::npos != sz.find("ambi", s) || std::string::npos != sz.find("env", s)) {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++)); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++));
} else if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s)) { } else if (std::string::npos != sz.find("emissive", s) || std::string::npos != sz.find("self", s)) {
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++)); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++));
} else { } else {
// Assume it is a diffuse texture // Assume it is a diffuse texture
mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++)); mat->AddProperty(&tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++));
} }
} }
} }
@ -679,4 +675,6 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
} }
} }
} // namespace Assimp
#endif // !! ASSIMP_BUILD_NO_X_IMPORTER #endif // !! ASSIMP_BUILD_NO_X_IMPORTER

View File

@ -68,7 +68,7 @@ namespace XFile {
*/ */
class XFileImporter : public BaseImporter { class XFileImporter : public BaseImporter {
public: public:
XFileImporter(); XFileImporter() = default;
~XFileImporter() override = default; ~XFileImporter() override = default;
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team Copyright (c) 2006-2023, assimp team
All rights reserved. All rights reserved.
@ -56,64 +56,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
#include <utility> #include <utility>
//#include <cctype>
//#include <memory>
using namespace Assimp; namespace Assimp {
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp static constexpr uint32_t ErrorId = ~0u;
template <> template <>
const char *LogFunctions<XGLImporter>::Prefix() { const char *LogFunctions<XGLImporter>::Prefix() {
return "XGL: "; return "XGL: ";
} }
} // namespace Assimp static constexpr aiImporterDesc desc = {
"XGL Importer", "", "", "",
static const aiImporterDesc desc = { aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
"XGL Importer", 0, 0, 0, 0, "xgl zgl"};
"",
"",
"",
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
0,
0,
0,
0,
"xgl zgl"
};
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer XGLImporter::XGLImporter() : mXmlParser(nullptr), m_scene(nullptr) {
XGLImporter::XGLImporter() :
mXmlParser(nullptr),
m_scene(nullptr) {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well
XGLImporter::~XGLImporter() { XGLImporter::~XGLImporter() {
delete mXmlParser; clear();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const { bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
static const char *tokens[] = { "<world>", "<World>", "<WORLD>" }; static const char *tokens[] = { "<world>", "<World>", "<WORLD>" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens)); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a list of all file extensions which are handled by this class
const aiImporterDesc *XGLImporter::GetInfo() const { const aiImporterDesc *XGLImporter::GetInfo() const {
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL clear();
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
std::vector<char> uncompressed; std::vector<char> uncompressed;
#endif #endif
@ -159,7 +141,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
std::vector<aiMesh *> &meshes = scope.meshes_linear; std::vector<aiMesh *> &meshes = scope.meshes_linear;
std::vector<aiMaterial *> &materials = scope.materials_linear; std::vector<aiMaterial *> &materials = scope.materials_linear;
if (!meshes.size() || !materials.size()) { if (meshes.empty() || materials.empty()) {
ThrowException("failed to extract data from XGL file, no meshes loaded"); ThrowException("failed to extract data from XGL file, no meshes loaded");
} }
@ -184,6 +166,13 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
scope.dismiss(); scope.dismiss();
} }
// ------------------------------------------------------------------------------------------------
void XGLImporter::clear() {
delete mXmlParser;
mXmlParser = nullptr;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) { void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
for (XmlNode &currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
@ -199,9 +188,10 @@ void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
} }
aiNode *const nd = ReadObject(node, scope); aiNode *const nd = ReadObject(node, scope);
if (!nd) { if (nd == nullptr) {
ThrowException("failure reading <world>"); ThrowException("failure reading <world>");
} }
if (nd->mName.length == 0) { if (nd->mName.length == 0) {
nd->mName.Set("WORLD"); nd->mName.Set("WORLD");
} }
@ -254,15 +244,17 @@ aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope) {
const std::string &s = ai_stdStrToLower(child.name()); const std::string &s = ai_stdStrToLower(child.name());
if (s == "mesh") { if (s == "mesh") {
const size_t prev = scope.meshes_linear.size(); const size_t prev = scope.meshes_linear.size();
bool empty; if (ReadMesh(child, scope)) {
if (ReadMesh(child, scope, empty)) {
const size_t newc = scope.meshes_linear.size(); const size_t newc = scope.meshes_linear.size();
for (size_t i = 0; i < newc - prev; ++i) { for (size_t i = 0; i < newc - prev; ++i) {
meshes.push_back(static_cast<unsigned int>(i + prev)); meshes.push_back(static_cast<unsigned int>(i + prev));
} }
} }
} else if (s == "mat") { } else if (s == "mat") {
ReadMaterial(child, scope); const uint32_t matId = ReadMaterial(child, scope);
if (matId == ErrorId) {
ThrowException("Invalid material id detected.");
}
} else if (s == "object") { } else if (s == "object") {
children.push_back(ReadObject(child, scope)); children.push_back(ReadObject(child, scope));
} else if (s == "objectref") { } else if (s == "objectref") {
@ -438,18 +430,25 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
return mesh.release(); return mesh.release();
} }
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
TempMesh t;
// ------------------------------------------------------------------------------------------------
inline static unsigned int generateMeshId(unsigned int meshId, bool nor, bool uv) {
unsigned int currentMeshId = meshId | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30);
return currentMeshId;
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
TempMesh t;
uint32_t matId = 99999;
bool mesh_created = false;
std::map<unsigned int, TempMaterialMesh> bymat; std::map<unsigned int, TempMaterialMesh> bymat;
const unsigned int mesh_id = ReadIDAttr(node); const unsigned int mesh_id = ReadIDAttr(node);
bool empty_mesh = true;
for (XmlNode &child : node.children()) { for (XmlNode &child : node.children()) {
const std::string &s = ai_stdStrToLower(child.name()); const std::string &s = ai_stdStrToLower(child.name());
if (s == "mat") { if (s == "mat") {
ReadMaterial(child, scope); matId = ReadMaterial(child, scope);
} else if (s == "p") { } else if (s == "p") {
pugi::xml_attribute attr = child.attribute("ID"); pugi::xml_attribute attr = child.attribute("ID");
if (attr.empty()) { if (attr.empty()) {
@ -477,66 +476,41 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
} else if (s == "f" || s == "l" || s == "p") { } else if (s == "f" || s == "l" || s == "p") {
const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1); const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
unsigned int mid = ~0u; unsigned int meshId = ErrorId;
TempFace tf[3]; TempFace tempFace[3] = {};
bool has[3] = { false }; bool has[3] = { false };
for (XmlNode &sub_child : child.children()) { meshId = ReadVertices(child, t, tempFace, has, meshId, scope);
const std::string &scn = ai_stdStrToLower(sub_child.name()); if (meshId == ErrorId) {
if (scn == "fv1" || scn == "lv1" || scn == "pv1") {
ReadFaceVertex(sub_child, t, tf[0]);
has[0] = true;
} else if (scn == "fv2" || scn == "lv2") {
ReadFaceVertex(sub_child, t, tf[1]);
has[1] = true;
} else if (scn == "fv3") {
ReadFaceVertex(sub_child, t, tf[2]);
has[2] = true;
} else if (scn == "mat") {
if (mid != ~0u) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(sub_child, scope);
} else if (scn == "matref") {
if (mid != ~0u) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(sub_child, scope);
}
}
if (has[0] || has[1] || has[2]) {
empty_mesh = false;
}
if (mid == ~0u) {
ThrowException("missing material index"); ThrowException("missing material index");
} }
bool nor = false; bool nor = false, uv = false;
bool uv = false;
for (unsigned int i = 0; i < vcount; ++i) { for (unsigned int i = 0; i < vcount; ++i) {
if (!has[i]) { if (!has[i]) {
ThrowException("missing face vertex data"); ThrowException("missing face vertex data");
} }
nor = nor || tf[i].has_normal; nor = nor || tempFace[i].has_normal;
uv = uv || tf[i].has_uv; uv = uv || tempFace[i].has_uv;
} }
if (mid >= (1 << 30)) { if (meshId >= (1 << 30)) {
LogWarn("material indices exhausted, this may cause errors in the output"); LogWarn("material indices exhausted, this may cause errors in the output");
} }
unsigned int meshId = mid | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30); const unsigned int currentMeshId = generateMeshId(meshId, nor, uv);
TempMaterialMesh &mesh = bymat[meshId]; // Generate the temp mesh
mesh.matid = mid; TempMaterialMesh &mesh = bymat[currentMeshId];
mesh.matid = meshId;
mesh_created = true;
for (unsigned int i = 0; i < vcount; ++i) { for (unsigned int i = 0; i < vcount; ++i) {
mesh.positions.push_back(tf[i].pos); mesh.positions.push_back(tempFace[i].pos);
if (nor) { if (nor) {
mesh.normals.push_back(tf[i].normal); mesh.normals.push_back(tempFace[i].normal);
} }
if (uv) { if (uv) {
mesh.uvs.push_back(tf[i].uv); mesh.uvs.push_back(tempFace[i].uv);
} }
mesh.pflags |= 1 << (vcount - 1); mesh.pflags |= 1 << (vcount - 1);
@ -546,25 +520,59 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
} }
} }
// finally extract output meshes and add them to the scope if (!mesh_created) {
using pairt = std::pair<const unsigned int, TempMaterialMesh>; TempMaterialMesh &mesh = bymat[mesh_id];
for (const pairt &p : bymat) { mesh.matid = matId;
aiMesh *const m = ToOutputMesh(p.second);
scope.meshes_linear.push_back(m);
// if this is a definition, keep it on the stack
if (mesh_id != ~0u) {
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
}
}
if (empty_mesh) {
LogWarn("Mesh is empty, skipping.");
empty = empty_mesh;
return false;
} }
// finally extract output meshes and add them to the scope
AppendOutputMeshes(bymat, scope, mesh_id);
// no id == not a reference, insert this mesh right *here* // no id == not a reference, insert this mesh right *here*
return mesh_id == ~0u; return mesh_id == ErrorId;
}
// ----------------------------------------------------------------------------------------------
void XGLImporter::AppendOutputMeshes(std::map<unsigned int, TempMaterialMesh> bymat, TempScope &scope,
const unsigned int mesh_id) {
using pairt = std::pair<const unsigned int, TempMaterialMesh>;
for (const pairt &p : bymat) {
aiMesh *const m = ToOutputMesh(p.second);
scope.meshes_linear.push_back(m);
// if this is a definition, keep it on the stack
if (mesh_id != ErrorId) {
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
}
}
}
// ----------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadVertices(XmlNode &child, TempMesh t, TempFace *tf, bool *has, unsigned int mid, TempScope &scope) {
for (XmlNode &sub_child : child.children()) {
const std::string &scn = ai_stdStrToLower(sub_child.name());
if (scn == "fv1" || scn == "lv1" || scn == "pv1") {
ReadFaceVertex(sub_child, t, tf[0]);
has[0] = true;
} else if (scn == "fv2" || scn == "lv2") {
ReadFaceVertex(sub_child, t, tf[1]);
has[1] = true;
} else if (scn == "fv3") {
ReadFaceVertex(sub_child, t, tf[2]);
has[2] = true;
} else if (scn == "mat") {
if (mid != ErrorId) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(sub_child, scope);
} else if (scn == "matref") {
if (mid != ErrorId) {
LogWarn("only one material tag allowed per <f>");
}
mid = ResolveMaterialRef(sub_child, scope);
}
}
return mid;
} }
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
@ -598,10 +606,10 @@ unsigned int XGLImporter::ResolveMaterialRef(XmlNode &node, TempScope &scope) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) { unsigned int XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) {
const unsigned int mat_id = ReadIDAttr(node); const unsigned int mat_id = ReadIDAttr(node);
auto *mat(new aiMaterial); auto *mat = new aiMaterial;
for (XmlNode &child : node.children()) { for (XmlNode &child : node.children()) {
const std::string &s = ai_stdStrToLower(child.name()); const std::string &s = ai_stdStrToLower(child.name());
if (s == "amb") { if (s == "amb") {
@ -627,6 +635,8 @@ void XGLImporter::ReadMaterial(XmlNode &node, TempScope &scope) {
scope.materials[mat_id] = mat; scope.materials[mat_id] = mat;
scope.materials_linear.push_back(mat); scope.materials_linear.push_back(mat);
return mat_id;
} }
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
@ -683,7 +693,7 @@ unsigned int XGLImporter::ReadIDAttr(XmlNode &node) {
} }
} }
return ~0u; return ErrorId;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -712,14 +722,14 @@ unsigned int XGLImporter::ReadIndexFromText(XmlNode &node) {
const char *s = v.c_str(); const char *s = v.c_str();
if (!SkipSpaces(&s)) { if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse index element"); LogError("unexpected EOL, failed to parse index element");
return ~0u; return ErrorId;
} }
const char *se; const char *se = nullptr;
const unsigned int t = strtoul10(s, &se); const unsigned int t = strtoul10(s, &se);
if (se == s) { if (se == s) {
LogError("failed to read index"); LogError("failed to read index");
return ~0u; return ErrorId;
} }
return t; return t;
@ -786,4 +796,6 @@ aiColor3D XGLImporter::ReadCol3(XmlNode &node) {
return aiColor3D(v.x, v.y, v.z); return aiColor3D(v.x, v.y, v.z);
} }
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_XGL_IMPORTER #endif // ASSIMP_BUILD_NO_XGL_IMPORTER

View File

@ -69,16 +69,20 @@ namespace Assimp {
*/ */
class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter> { class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter> {
public: public:
/// @brief The class constructor.
XGLImporter(); XGLImporter();
/// @brief The class destructor.
~XGLImporter() override; ~XGLImporter() override;
// ------------------------------------------------------------------- /// @brief Returns whether the class can handle the format of the given file.
/** Returns whether the class can handle the format of the given file. /// @see BaseImporter::CanRead() for details. */
* See BaseImporter::CanRead() for details. */
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const override; bool checkSig) const override;
protected: protected:
void clear();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details */ * See #BaseImporter::GetInfo for the details */
@ -92,10 +96,7 @@ protected:
private: private:
struct TempScope { struct TempScope {
TempScope() : TempScope() : light() {}
light() {
// empty
}
~TempScope() { ~TempScope() {
for (aiMesh *m : meshes_linear) { for (aiMesh *m : meshes_linear) {
@ -145,9 +146,7 @@ private:
}; };
struct TempMaterialMesh { struct TempMaterialMesh {
TempMaterialMesh() : TempMaterialMesh() : pflags(), matid() {
pflags(),
matid() {
// empty // empty
} }
@ -160,9 +159,7 @@ private:
}; };
struct TempFace { struct TempFace {
TempFace() : TempFace() : has_uv(), has_normal() {
has_uv(),
has_normal() {
// empty // empty
} }
@ -175,26 +172,25 @@ private:
private: private:
void Cleanup(); void Cleanup();
std::string GetElementName(); std::string GetElementName();
bool ReadElement(); bool ReadElement();
bool ReadElementUpToClosing(const char *closetag); bool ReadElementUpToClosing(const char *closetag);
bool SkipToText(); bool SkipToText();
unsigned int ReadIDAttr(XmlNode &node); unsigned int ReadIDAttr(XmlNode &node);
void ReadWorld(XmlNode &node, TempScope &scope); void ReadWorld(XmlNode &node, TempScope &scope);
void ReadLighting(XmlNode &node, TempScope &scope); void ReadLighting(XmlNode &node, TempScope &scope);
aiLight *ReadDirectionalLight(XmlNode &node); aiLight *ReadDirectionalLight(XmlNode &node);
aiNode *ReadObject(XmlNode &node, TempScope &scope); aiNode *ReadObject(XmlNode &node, TempScope &scope);
bool ReadMesh(XmlNode &node, TempScope &scope, bool &empty); bool ReadMesh(XmlNode &node, TempScope &scope);
void ReadMaterial(XmlNode &node, TempScope &scope); void AppendOutputMeshes(std::map<unsigned int, TempMaterialMesh> bymat, TempScope &scope, const unsigned int mesh_id);
unsigned int ReadVertices(XmlNode &child, TempMesh t, TempFace *tf, bool *has, unsigned int mid, TempScope &scope);
unsigned int ReadMaterial(XmlNode &node, TempScope &scope);
aiVector2D ReadVec2(XmlNode &node); aiVector2D ReadVec2(XmlNode &node);
aiVector3D ReadVec3(XmlNode &node); aiVector3D ReadVec3(XmlNode &node);
aiColor3D ReadCol3(XmlNode &node); aiColor3D ReadCol3(XmlNode &node);
aiMatrix4x4 ReadTrafo(XmlNode &node); aiMatrix4x4 ReadTrafo(XmlNode &node);
unsigned int ReadIndexFromText(XmlNode &node); unsigned int ReadIndexFromText(XmlNode &node);
float ReadFloat(XmlNode &node); float ReadFloat(XmlNode &node);
aiMesh *ToOutputMesh(const TempMaterialMesh &m); aiMesh *ToOutputMesh(const TempMaterialMesh &m);
void ReadFaceVertex(XmlNode &node, const TempMesh &t, TempFace &out); void ReadFaceVertex(XmlNode &node, const TempMesh &t, TempFace &out);
unsigned int ResolveMaterialRef(XmlNode &node, TempScope &scope); unsigned int ResolveMaterialRef(XmlNode &node, TempScope &scope);

View File

@ -62,11 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
using namespace glTF; using namespace glTF;
// static constexpr aiImporterDesc desc = {
// glTFImporter
//
static const aiImporterDesc desc = {
"glTF Importer", "glTF Importer",
"", "",
"", "",

View File

@ -559,7 +559,11 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
aiString tex; aiString tex;
// Read texcoord (UV map index) // Read texcoord (UV map index)
mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord); // Note: must be an int to be successful.
int tmp = 0;
const auto ok = mat.Get(AI_MATKEY_UVWSRC(tt, slot), tmp);
if (ok == aiReturn_SUCCESS) texCoord = tmp;
if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
std::string path = tex.C_Str(); std::string path = tex.C_Str();

View File

@ -82,7 +82,7 @@ struct Tangent {
// glTF2Importer // glTF2Importer
// //
static const aiImporterDesc desc = { static constexpr aiImporterDesc desc = {
"glTF2 Importer", "glTF2 Importer",
"", "",
"", "",

View File

@ -923,7 +923,7 @@ IF(ASSIMP_HUNTER_ENABLED)
hunter_add_package(utf8) hunter_add_package(utf8)
find_package(utf8cpp CONFIG REQUIRED) find_package(utf8cpp CONFIG REQUIRED)
ELSE() ELSE()
# utf8 is header-only, so Assimp doesn't need to do anything. INCLUDE_DIRECTORIES("../contrib/utf8cpp/source")
ENDIF() ENDIF()
# polyclipping # polyclipping
@ -1380,7 +1380,12 @@ ENDIF()
IF(NOT ASSIMP_HUNTER_ENABLED) IF(NOT ASSIMP_HUNTER_ENABLED)
if (UNZIP_FOUND) if (UNZIP_FOUND)
INCLUDE_DIRECTORIES(${UNZIP_INCLUDE_DIRS}) INCLUDE_DIRECTORIES(${UNZIP_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(assimp ${UNZIP_LIBRARIES}) # TODO if cmake required version has been updated to >3.12.0, collapse this to the second case only
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
TARGET_LINK_LIBRARIES(assimp ${UNZIP_LIBRARIES})
else()
TARGET_LINK_LIBRARIES(assimp ${UNZIP_LINK_LIBRARIES})
endif()
else () else ()
INCLUDE_DIRECTORIES("../") INCLUDE_DIRECTORIES("../")
endif () endif ()

View File

@ -66,6 +66,10 @@ Compression::Compression() :
Compression::~Compression() { Compression::~Compression() {
ai_assert(mImpl != nullptr); ai_assert(mImpl != nullptr);
if (mImpl->mOpen) {
close();
}
delete mImpl; delete mImpl;
} }
@ -124,7 +128,7 @@ static int getFlushMode(Compression::FlushMode flush) {
return z_flush; return z_flush;
} }
constexpr size_t MYBLOCK = 32786; static constexpr size_t MYBLOCK = 32786;
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) { size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
ai_assert(mImpl != nullptr); ai_assert(mImpl != nullptr);

View File

@ -40,6 +40,9 @@
# define crc32 z_crc32 # define crc32 z_crc32
# define crc32_combine z_crc32_combine # define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64 # define crc32_combine64 z_crc32_combine64
# define crc32_combine_gen z_crc32_combine_gen
# define crc32_combine_gen64 z_crc32_combine_gen64
# define crc32_combine_op z_crc32_combine_op
# define crc32_z z_crc32_z # define crc32_z z_crc32_z
# define deflate z_deflate # define deflate z_deflate
# define deflateBound z_deflateBound # define deflateBound z_deflateBound
@ -351,6 +354,9 @@
# ifdef FAR # ifdef FAR
# undef FAR # undef FAR
# endif # endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h> # include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */ /* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
@ -469,11 +475,18 @@ typedef uLong FAR uLongf;
# undef _LARGEFILE64_SOURCE # undef _LARGEFILE64_SOURCE
#endif #endif
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) #ifndef Z_HAVE_UNISTD_H
# define Z_HAVE_UNISTD_H # ifdef __WATCOMC__
# define Z_HAVE_UNISTD_H
# endif
#endif
#ifndef Z_HAVE_UNISTD_H
# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32)
# define Z_HAVE_UNISTD_H
# endif
#endif #endif
#ifndef Z_SOLO #ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) # if defined(Z_HAVE_UNISTD_H)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS # ifdef VMS
# include <unixio.h> /* for off_t */ # include <unixio.h> /* for off_t */

View File

@ -63,6 +63,7 @@ struct aiImporterDesc;
namespace Assimp { namespace Assimp {
// Forward declarations
class Importer; class Importer;
class IOSystem; class IOSystem;
class BaseProcess; class BaseProcess;
@ -73,6 +74,9 @@ class IOStream;
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \ #define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
(string[1] << 16) + (string[2] << 8) + string[3])) (string[1] << 16) + (string[2] << 8) + string[3]))
using UByteBuffer = std::vector<uint8_t>;
using ByteBuffer = std::vector<int8_t>;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface /** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
* for all importer worker classes. * for all importer worker classes.

View File

@ -70,7 +70,6 @@ namespace Assimp {
static const unsigned int BufferSize = 4096; static const unsigned int BufferSize = 4096;
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>
AI_FORCE_INLINE bool IsUpper(char_t in) { AI_FORCE_INLINE bool IsUpper(char_t in) {

View File

@ -151,6 +151,8 @@ public:
typedef aiVector3t<ai_real> aiVector3D; typedef aiVector3t<ai_real> aiVector3D;
typedef aiVector3t<float> aiVector3f;
typedef aiVector3t<double> aiVector3d;
#else #else

View File

@ -19,6 +19,7 @@ INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/include ${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code ${Assimp_SOURCE_DIR}/code
${SAMPLES_SHARED_CODE_DIR} ${SAMPLES_SHARED_CODE_DIR}
${Assimp_SOURCE_DIR}/contrib/utf8cpp/source
) )
LINK_DIRECTORIES( LINK_DIRECTORIES(

View File

@ -23,6 +23,7 @@
#include <dxgi1_2.h> #include <dxgi1_2.h>
#include <DirectXMath.h> #include <DirectXMath.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include <utf8.h>
#include "ModelLoader.h" #include "ModelLoader.h"
#include "SafeRelease.hpp" #include "SafeRelease.hpp"

View File

@ -21,6 +21,7 @@ INCLUDE_DIRECTORIES(
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}
${GLUT_INCLUDE_DIR} ${GLUT_INCLUDE_DIR}
${SAMPLES_SHARED_CODE_DIR} ${SAMPLES_SHARED_CODE_DIR}
${Assimp_SOURCE_DIR}/contrib/utf8cpp/source
) )
LINK_DIRECTORIES( LINK_DIRECTORIES(

View File

@ -17,6 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glu.h> #include <GL/glu.h>
#include <utf8.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable: 4100) // Disable warning 'unreferenced formal parameter' #pragma warning(disable: 4100) // Disable warning 'unreferenced formal parameter'