Merge branch 'master' into kimkulling/fix_invalid_delete_issue-5307
commit
3c18be8747
23
Readme.md
23
Readme.md
|
@ -6,20 +6,14 @@ Open Asset Import Library is a library to load various 3d file formats into a sh
|
||||||
### Current project status ###
|
### Current project status ###
|
||||||
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
|
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
|
||||||
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
|
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
|
||||||
<a href="https://scan.coverity.com/projects/5607">
|
|
||||||
<img alt="Coverity Scan Build Status"
|
|
||||||
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
|
||||||
</a>
|
|
||||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=assimp/assimp&utm_campaign=Badge_Grade)
|
||||||
|
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
|
||||||
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
|
||||||
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||||
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||||
|
|
||||||
### Latest Doc's ###
|
### Latest Doc's ###
|
||||||
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
|
||||||
|
@ -58,20 +52,21 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
|
||||||
|
|
||||||
### Other tools ###
|
### Other tools ###
|
||||||
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
||||||
|
[Assimp-Viewer(]https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
|
||||||
|
|
||||||
#### Repository structure ####
|
#### Repository structure ####
|
||||||
Open Asset Import Library is implemented in C++. The directory structure looks like:
|
Open Asset Import Library is implemented in C++. The directory structure looks like this:
|
||||||
|
|
||||||
/code Source code
|
/code Source code
|
||||||
/contrib Third-party libraries
|
/contrib Third-party libraries
|
||||||
/doc Documentation (doxysource and pre-compiled docs)
|
/doc Documentation (doxysource and pre-compiled docs)
|
||||||
/fuzz Contains the test-code for the Google-Fuzzer project
|
/fuzz Contains the test code for the Google Fuzzer project
|
||||||
/include Public header C and C++ header files
|
/include Public header C and C++ header files
|
||||||
/scripts Scripts used to generate the loading code for some formats
|
/scripts Scripts are used to generate the loading code for some formats
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/test Unit- and regression tests, test suite of models
|
/test Unit- and regression tests, test suite of models
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
/tools Tools (old assimp viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible use-cases for Assimp
|
/samples A small number of samples to illustrate possible use cases for Assimp
|
||||||
|
|
||||||
The source code is organized in the following way:
|
The source code is organized in the following way:
|
||||||
|
|
||||||
|
@ -79,9 +74,9 @@ The source code is organized in the following way:
|
||||||
code/CApi Special implementations which are only used for the C-API
|
code/CApi Special implementations which are only used for the C-API
|
||||||
code/Geometry A collection of geometry tools
|
code/Geometry A collection of geometry tools
|
||||||
code/Material The material system
|
code/Material The material system
|
||||||
code/PBR An exporter for physical based models
|
code/PBR An exporter for physical-based models
|
||||||
code/PostProcessing The post-processing steps
|
code/PostProcessing The post-processing steps
|
||||||
code/AssetLib/<FormatName> Implementation for import and export for the format
|
code/AssetLib/<FormatName> Implementation for import and export of the format
|
||||||
|
|
||||||
### Contributing ###
|
### Contributing ###
|
||||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
|
@ -118,4 +113,4 @@ and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you ma
|
||||||
For the legal details, see the `LICENSE` file.
|
For the legal details, see the `LICENSE` file.
|
||||||
|
|
||||||
### Why this name ###
|
### Why this name ###
|
||||||
Sorry, we're germans :-), no english native speakers ...
|
Sorry, we're germans :-), no English native speakers ...
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 ) {
|
||||||
|
@ -214,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
@ -1391,7 +1389,7 @@ void FBXExporter::WriteObjects ()
|
||||||
aiMaterial* m = mScene->mMaterials[i];
|
aiMaterial* m = mScene->mMaterials[i];
|
||||||
|
|
||||||
// these are used to receive material data
|
// these are used to receive material data
|
||||||
float f; aiColor3D c;
|
ai_real f; aiColor3D c;
|
||||||
|
|
||||||
// start the node record
|
// start the node record
|
||||||
FBX::Node n("Material");
|
FBX::Node n("Material");
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -1372,7 +1372,7 @@ std::vector<IfcVector2> GetContourInPlane2D(const std::shared_ptr<TempMesh>& mes
|
||||||
const std::vector<IfcVector3>& va = mesh->mVerts;
|
const std::vector<IfcVector3>& va = mesh->mVerts;
|
||||||
if(va.size() <= 2) {
|
if(va.size() <= 2) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << "Skipping: Only " << va.size() << " verticies in opening mesh.";
|
msg << "Skipping: Only " << va.size() << " vertices in opening mesh.";
|
||||||
IFCImporter::LogDebug(msg.str().c_str());
|
IFCImporter::LogDebug(msg.str().c_str());
|
||||||
ok = false;
|
ok = false;
|
||||||
return contour;
|
return contour;
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
@ -575,8 +575,8 @@ void SetupMapping(aiMaterial *mat, aiTextureMapping mode, const aiVector3D &axis
|
||||||
m->mSemantic = prop->mSemantic;
|
m->mSemantic = prop->mSemantic;
|
||||||
m->mType = aiPTI_Float;
|
m->mType = aiPTI_Float;
|
||||||
|
|
||||||
m->mDataLength = 12;
|
m->mDataLength = sizeof(aiVector3D);
|
||||||
m->mData = new char[12];
|
m->mData = new char[m->mDataLength];
|
||||||
*((aiVector3D *)m->mData) = axis;
|
*((aiVector3D *)m->mData) = axis;
|
||||||
p.push_back(m);
|
p.push_back(m);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
if (!mCurLayer->mFaces.empty())
|
case AI_LWO_SRFS: // list of tags
|
||||||
ASSIMP_LOG_WARN("LWO: POLS chunk encountered twice");
|
{
|
||||||
else LoadLWOBPolygons(head.length);
|
if (!mTags->empty())
|
||||||
break;
|
ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
|
||||||
}
|
else
|
||||||
// list of tags
|
LoadLWOTags(head.length);
|
||||||
case AI_LWO_SRFS:
|
} break;
|
||||||
{
|
|
||||||
if (!mTags->empty())
|
|
||||||
ASSIMP_LOG_WARN("LWO: SRFS chunk encountered twice");
|
|
||||||
else LoadLWOTags(head.length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// surface chunk
|
case AI_LWO_SURF: // surface chunk
|
||||||
case AI_LWO_SURF:
|
{
|
||||||
{
|
LoadLWOBSurface(head.length);
|
||||||
LoadLWOBSurface(head.length);
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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, ".");
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
|
@ -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 ¤tNode : node.children()) {
|
for (XmlNode ¤tNode : 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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -172,22 +172,6 @@ static void IdentityMatrix4(mat4 &o) {
|
||||||
o[15] = 1;
|
o[15] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsBoneWeightFitted(vec4 &weight) {
|
|
||||||
return weight[0] + weight[1] + weight[2] + weight[3] >= 1.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int FitBoneWeight(vec4 &weight, float value) {
|
|
||||||
int i = 0;
|
|
||||||
for (; i < 4; ++i) {
|
|
||||||
if (weight[i] < value) {
|
|
||||||
weight[i] = value;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void SetAccessorRange(Ref<Accessor> acc, void *data, size_t count,
|
void SetAccessorRange(Ref<Accessor> acc, void *data, size_t count,
|
||||||
unsigned int numCompsIn, unsigned int numCompsOut) {
|
unsigned int numCompsIn, unsigned int numCompsOut) {
|
||||||
|
@ -575,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();
|
||||||
|
@ -1009,23 +997,29 @@ Ref<Node> FindSkeletonRootJoint(Ref<Skin> &skinRef) {
|
||||||
return parentNodeRef;
|
return parentNodeRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct boneIndexWeightPair {
|
||||||
|
unsigned int indexJoint;
|
||||||
|
float weight;
|
||||||
|
bool operator()(boneIndexWeightPair &a, boneIndexWeightPair &b) {
|
||||||
|
return a.weight > b.weight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buffer> &bufferRef, Ref<Skin> &skinRef,
|
void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buffer> &bufferRef, Ref<Skin> &skinRef,
|
||||||
std::vector<aiMatrix4x4> &inverseBindMatricesData) {
|
std::vector<aiMatrix4x4> &inverseBindMatricesData, bool unlimitedBonesPerVertex) {
|
||||||
if (aimesh->mNumBones < 1) {
|
if (aimesh->mNumBones < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the vertex joint and weight data.
|
// Store the vertex joint and weight data.
|
||||||
const size_t NumVerts(aimesh->mNumVertices);
|
const size_t NumVerts(aimesh->mNumVertices);
|
||||||
vec4 *vertexJointData = new vec4[NumVerts];
|
|
||||||
vec4 *vertexWeightData = new vec4[NumVerts];
|
|
||||||
int *jointsPerVertex = new int[NumVerts];
|
int *jointsPerVertex = new int[NumVerts];
|
||||||
|
std::vector<std::vector<boneIndexWeightPair>> allVerticesPairs;
|
||||||
|
int maxJointsPerVertex = 0;
|
||||||
for (size_t i = 0; i < NumVerts; ++i) {
|
for (size_t i = 0; i < NumVerts; ++i) {
|
||||||
jointsPerVertex[i] = 0;
|
jointsPerVertex[i] = 0;
|
||||||
for (size_t j = 0; j < 4; ++j) {
|
std::vector<boneIndexWeightPair> vertexPair;
|
||||||
vertexJointData[i][j] = 0;
|
allVerticesPairs.push_back(vertexPair);
|
||||||
vertexWeightData[i][j] = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) {
|
for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) {
|
||||||
|
@ -1055,61 +1049,88 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
|
||||||
jointNamesIndex = static_cast<unsigned int>(inverseBindMatricesData.size() - 1);
|
jointNamesIndex = static_cast<unsigned int>(inverseBindMatricesData.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// aib->mWeights =====> vertexWeightData
|
// aib->mWeights =====> temp pairs data
|
||||||
for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) {
|
for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights;
|
||||||
|
++idx_weights) {
|
||||||
unsigned int vertexId = aib->mWeights[idx_weights].mVertexId;
|
unsigned int vertexId = aib->mWeights[idx_weights].mVertexId;
|
||||||
float vertWeight = aib->mWeights[idx_weights].mWeight;
|
float vertWeight = aib->mWeights[idx_weights].mWeight;
|
||||||
|
allVerticesPairs[vertexId].push_back({jointNamesIndex, vertWeight});
|
||||||
// A vertex can only have at most four joint weights, which ideally sum up to 1
|
jointsPerVertex[vertexId] += 1;
|
||||||
if (IsBoneWeightFitted(vertexWeightData[vertexId])) {
|
maxJointsPerVertex =
|
||||||
continue;
|
std::max(maxJointsPerVertex, jointsPerVertex[vertexId]);
|
||||||
}
|
|
||||||
if (jointsPerVertex[vertexId] > 3) {
|
|
||||||
int boneIndexFitted = FitBoneWeight(vertexWeightData[vertexId], vertWeight);
|
|
||||||
if (boneIndexFitted != -1) {
|
|
||||||
vertexJointData[vertexId][boneIndexFitted] = static_cast<float>(jointNamesIndex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
|
|
||||||
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
|
|
||||||
|
|
||||||
jointsPerVertex[vertexId] += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End: for-loop mNumMeshes
|
} // End: for-loop mNumMeshes
|
||||||
|
|
||||||
Mesh::Primitive &p = meshRef->primitives.back();
|
if (!unlimitedBonesPerVertex){
|
||||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
|
// skinning limited only for 4 bones per vertex, default
|
||||||
vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
maxJointsPerVertex = 4;
|
||||||
if (vertexJointAccessor) {
|
|
||||||
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
|
||||||
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
|
||||||
unsigned int s_bytesPerComp = ComponentTypeSize(ComponentType_UNSIGNED_SHORT);
|
|
||||||
unsigned int bytesPerComp = ComponentTypeSize(vertexJointAccessor->componentType);
|
|
||||||
size_t s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp;
|
|
||||||
Ref<Buffer> buf = vertexJointAccessor->bufferView->buffer;
|
|
||||||
uint8_t *arrys = new uint8_t[bytesLen];
|
|
||||||
unsigned int i = 0;
|
|
||||||
for (unsigned int j = 0; j < bytesLen; j += bytesPerComp) {
|
|
||||||
size_t len_p = offset + j;
|
|
||||||
float f_value = *(float *)&buf->GetPointer()[len_p];
|
|
||||||
unsigned short c = static_cast<unsigned short>(f_value);
|
|
||||||
memcpy(&arrys[i * s_bytesPerComp], &c, s_bytesPerComp);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
buf->ReplaceData_joint(offset, bytesLen, arrys, bytesLen);
|
|
||||||
vertexJointAccessor->componentType = ComponentType_UNSIGNED_SHORT;
|
|
||||||
vertexJointAccessor->bufferView->byteLength = s_bytesLen;
|
|
||||||
|
|
||||||
p.attributes.joint.push_back(vertexJointAccessor);
|
|
||||||
delete[] arrys;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
|
// temp pairs data =====> vertexWeightData
|
||||||
vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
size_t numGroups = (maxJointsPerVertex - 1) / 4 + 1;
|
||||||
if (vertexWeightAccessor) {
|
vec4 *vertexJointData = new vec4[NumVerts * numGroups];
|
||||||
p.attributes.weight.push_back(vertexWeightAccessor);
|
vec4 *vertexWeightData = new vec4[NumVerts * numGroups];
|
||||||
|
for (size_t indexVertex = 0; indexVertex < NumVerts; ++indexVertex) {
|
||||||
|
// order pairs by weight for each vertex
|
||||||
|
std::sort(allVerticesPairs[indexVertex].begin(),
|
||||||
|
allVerticesPairs[indexVertex].end(),
|
||||||
|
boneIndexWeightPair());
|
||||||
|
for (size_t indexGroup = 0; indexGroup < numGroups; ++indexGroup) {
|
||||||
|
for (size_t indexJoint = 0; indexJoint < 4; ++indexJoint) {
|
||||||
|
size_t indexBone = indexGroup * 4 + indexJoint;
|
||||||
|
size_t indexData = indexVertex + NumVerts * indexGroup;
|
||||||
|
if (indexBone >= allVerticesPairs[indexVertex].size()) {
|
||||||
|
vertexJointData[indexData][indexJoint] = 0.f;
|
||||||
|
vertexWeightData[indexData][indexJoint] = 0.f;
|
||||||
|
} else {
|
||||||
|
vertexJointData[indexData][indexJoint] =
|
||||||
|
static_cast<float>(
|
||||||
|
allVerticesPairs[indexVertex][indexBone].indexJoint);
|
||||||
|
vertexWeightData[indexData][indexJoint] =
|
||||||
|
allVerticesPairs[indexVertex][indexBone].weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t idx_group = 0; idx_group < numGroups; ++idx_group) {
|
||||||
|
Mesh::Primitive &p = meshRef->primitives.back();
|
||||||
|
Ref<Accessor> vertexJointAccessor = ExportData(
|
||||||
|
mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
|
||||||
|
vertexJointData + idx_group * NumVerts,
|
||||||
|
AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
|
if (vertexJointAccessor) {
|
||||||
|
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
||||||
|
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||||
|
unsigned int s_bytesPerComp =
|
||||||
|
ComponentTypeSize(ComponentType_UNSIGNED_SHORT);
|
||||||
|
unsigned int bytesPerComp =
|
||||||
|
ComponentTypeSize(vertexJointAccessor->componentType);
|
||||||
|
size_t s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp;
|
||||||
|
Ref<Buffer> buf = vertexJointAccessor->bufferView->buffer;
|
||||||
|
uint8_t *arrys = new uint8_t[bytesLen];
|
||||||
|
unsigned int i = 0;
|
||||||
|
for (unsigned int j = 0; j < bytesLen; j += bytesPerComp) {
|
||||||
|
size_t len_p = offset + j;
|
||||||
|
float f_value = *(float *)&buf->GetPointer()[len_p];
|
||||||
|
unsigned short c = static_cast<unsigned short>(f_value);
|
||||||
|
memcpy(&arrys[i * s_bytesPerComp], &c, s_bytesPerComp);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
buf->ReplaceData_joint(offset, bytesLen, arrys, bytesLen);
|
||||||
|
vertexJointAccessor->componentType = ComponentType_UNSIGNED_SHORT;
|
||||||
|
vertexJointAccessor->bufferView->byteLength = s_bytesLen;
|
||||||
|
|
||||||
|
p.attributes.joint.push_back(vertexJointAccessor);
|
||||||
|
delete[] arrys;
|
||||||
|
}
|
||||||
|
Ref<Accessor> vertexWeightAccessor = ExportData(
|
||||||
|
mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
|
||||||
|
vertexWeightData + idx_group * NumVerts,
|
||||||
|
AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
|
if (vertexWeightAccessor) {
|
||||||
|
p.attributes.weight.push_back(vertexWeightAccessor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete[] jointsPerVertex;
|
delete[] jointsPerVertex;
|
||||||
delete[] vertexWeightData;
|
delete[] vertexWeightData;
|
||||||
|
@ -1247,9 +1268,19 @@ void glTF2Exporter::ExportMeshes() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// /*************** Skins ****************/
|
||||||
|
// if (aim->HasBones()) {
|
||||||
|
// ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
|
||||||
|
// }
|
||||||
/*************** Skins ****************/
|
/*************** Skins ****************/
|
||||||
if (aim->HasBones()) {
|
if (aim->HasBones()) {
|
||||||
ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
|
bool unlimitedBonesPerVertex =
|
||||||
|
this->mProperties->HasPropertyBool(
|
||||||
|
AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX) &&
|
||||||
|
this->mProperties->GetPropertyBool(
|
||||||
|
AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX);
|
||||||
|
ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData,
|
||||||
|
unlimitedBonesPerVertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************** Targets for blendshapes ****************/
|
/*************** Targets for blendshapes ****************/
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct Tangent {
|
||||||
// glTF2Importer
|
// glTF2Importer
|
||||||
//
|
//
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static constexpr aiImporterDesc desc = {
|
||||||
"glTF2 Importer",
|
"glTF2 Importer",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
|
|
|
@ -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 ()
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -3,9 +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.
|
||||||
|
|
||||||
|
@ -59,31 +57,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
using namespace Assimp;
|
namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess()
|
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() :
|
||||||
: mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
|
mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const {
|
bool ImproveCacheLocalityProcess::IsActive(unsigned int pFlags) const {
|
||||||
return (pFlags & aiProcess_ImproveCacheLocality) != 0;
|
return (pFlags & aiProcess_ImproveCacheLocality) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup configuration
|
// Setup configuration
|
||||||
void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp) {
|
void ImproveCacheLocalityProcess::SetupProperties(const Importer *pImp) {
|
||||||
// AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
|
// AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
|
||||||
mConfigCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
|
mConfigCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE, PP_ICL_PTCACHE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void ImproveCacheLocalityProcess::Execute( aiScene* pScene) {
|
void ImproveCacheLocalityProcess::Execute(aiScene *pScene) {
|
||||||
if (!pScene->mNumMeshes) {
|
if (!pScene->mNumMeshes) {
|
||||||
ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes");
|
ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess skipped; there are no meshes");
|
||||||
return;
|
return;
|
||||||
|
@ -93,11 +91,11 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene) {
|
||||||
|
|
||||||
float out = 0.f;
|
float out = 0.f;
|
||||||
unsigned int numf = 0, numm = 0;
|
unsigned int numf = 0, numm = 0;
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a ){
|
for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
|
||||||
const float res = ProcessMesh( pScene->mMeshes[a],a);
|
const float res = ProcessMesh(pScene->mMeshes[a], a);
|
||||||
if (res) {
|
if (res) {
|
||||||
numf += pScene->mMeshes[a]->mNumFaces;
|
numf += pScene->mMeshes[a]->mNumFaces;
|
||||||
out += res;
|
out += res;
|
||||||
++numm;
|
++numm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,9 +107,54 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
static ai_real calculateInputACMR(aiMesh *pMesh, const aiFace *const pcEnd,
|
||||||
|
unsigned int configCacheDepth, unsigned int meshNum) {
|
||||||
|
ai_real fACMR = 0.0f;
|
||||||
|
unsigned int *piFIFOStack = new unsigned int[configCacheDepth];
|
||||||
|
memset(piFIFOStack, 0xff, configCacheDepth * sizeof(unsigned int));
|
||||||
|
unsigned int *piCur = piFIFOStack;
|
||||||
|
const unsigned int *const piCurEnd = piFIFOStack + configCacheDepth;
|
||||||
|
|
||||||
|
// count the number of cache misses
|
||||||
|
unsigned int iCacheMisses = 0;
|
||||||
|
for (const aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
|
||||||
|
for (unsigned int qq = 0; qq < 3; ++qq) {
|
||||||
|
bool bInCache = false;
|
||||||
|
for (unsigned int *pp = piFIFOStack; pp < piCurEnd; ++pp) {
|
||||||
|
if (*pp == pcFace->mIndices[qq]) {
|
||||||
|
// the vertex is in cache
|
||||||
|
bInCache = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bInCache) {
|
||||||
|
++iCacheMisses;
|
||||||
|
if (piCurEnd == piCur) {
|
||||||
|
piCur = piFIFOStack;
|
||||||
|
}
|
||||||
|
*piCur++ = pcFace->mIndices[qq];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] piFIFOStack;
|
||||||
|
fACMR = (ai_real)iCacheMisses / pMesh->mNumFaces;
|
||||||
|
if (3.0 == fACMR) {
|
||||||
|
char szBuff[128]; // should be sufficiently large in every case
|
||||||
|
|
||||||
|
// the JoinIdenticalVertices process has not been executed on this
|
||||||
|
// mesh, otherwise this value would normally be at least minimally
|
||||||
|
// smaller than 3.0 ...
|
||||||
|
ai_snprintf(szBuff, 128, "Mesh %u: Not suitable for vcache optimization", meshNum);
|
||||||
|
ASSIMP_LOG_WARN(szBuff);
|
||||||
|
return static_cast<ai_real>(0.f);
|
||||||
|
}
|
||||||
|
return fACMR;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Improves the cache coherency of a specific mesh
|
// Improves the cache coherency of a specific mesh
|
||||||
ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum) {
|
ai_real ImproveCacheLocalityProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshNum) {
|
||||||
// TODO: rewrite this to use std::vector or boost::shared_array
|
// TODO: rewrite this to use std::vector or boost::shared_array
|
||||||
ai_assert(nullptr != pMesh);
|
ai_assert(nullptr != pMesh);
|
||||||
|
|
||||||
|
@ -126,91 +169,57 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
return static_cast<ai_real>(0.f);
|
return static_cast<ai_real>(0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pMesh->mNumVertices <= mConfigCacheDepth) {
|
if (pMesh->mNumVertices <= mConfigCacheDepth) {
|
||||||
return static_cast<ai_real>(0.f);
|
return static_cast<ai_real>(0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
ai_real fACMR = 3.f;
|
ai_real fACMR = 3.f;
|
||||||
const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces;
|
const aiFace *const pcEnd = pMesh->mFaces + pMesh->mNumFaces;
|
||||||
|
|
||||||
// Input ACMR is for logging purposes only
|
// Input ACMR is for logging purposes only
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
|
fACMR = calculateInputACMR(pMesh, pcEnd, mConfigCacheDepth, meshNum);
|
||||||
unsigned int* piFIFOStack = new unsigned int[mConfigCacheDepth];
|
|
||||||
memset(piFIFOStack,0xff,mConfigCacheDepth*sizeof(unsigned int));
|
|
||||||
unsigned int* piCur = piFIFOStack;
|
|
||||||
const unsigned int* const piCurEnd = piFIFOStack + mConfigCacheDepth;
|
|
||||||
|
|
||||||
// count the number of cache misses
|
|
||||||
unsigned int iCacheMisses = 0;
|
|
||||||
for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace) {
|
|
||||||
for (unsigned int qq = 0; qq < 3;++qq) {
|
|
||||||
bool bInCache = false;
|
|
||||||
for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp) {
|
|
||||||
if (*pp == pcFace->mIndices[qq]) {
|
|
||||||
// the vertex is in cache
|
|
||||||
bInCache = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!bInCache) {
|
|
||||||
++iCacheMisses;
|
|
||||||
if (piCurEnd == piCur) {
|
|
||||||
piCur = piFIFOStack;
|
|
||||||
}
|
|
||||||
*piCur++ = pcFace->mIndices[qq];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] piFIFOStack;
|
|
||||||
fACMR = (ai_real) iCacheMisses / pMesh->mNumFaces;
|
|
||||||
if (3.0 == fACMR) {
|
|
||||||
char szBuff[128]; // should be sufficiently large in every case
|
|
||||||
|
|
||||||
// the JoinIdenticalVertices process has not been executed on this
|
|
||||||
// mesh, otherwise this value would normally be at least minimally
|
|
||||||
// smaller than 3.0 ...
|
|
||||||
ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum);
|
|
||||||
ASSIMP_LOG_WARN(szBuff);
|
|
||||||
return static_cast<ai_real>(0.f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// first we need to build a vertex-triangle adjacency list
|
// first we need to build a vertex-triangle adjacency list
|
||||||
VertexTriangleAdjacency adj(pMesh->mFaces,pMesh->mNumFaces, pMesh->mNumVertices,true);
|
VertexTriangleAdjacency adj(pMesh->mFaces, pMesh->mNumFaces, pMesh->mNumVertices, true);
|
||||||
|
|
||||||
// build a list to store per-vertex caching time stamps
|
// build a list to store per-vertex caching time stamps
|
||||||
unsigned int* const piCachingStamps = new unsigned int[pMesh->mNumVertices];
|
std::vector<unsigned int> piCachingStamps;
|
||||||
memset(piCachingStamps,0x0,pMesh->mNumVertices*sizeof(unsigned int));
|
piCachingStamps.resize(pMesh->mNumVertices);
|
||||||
|
memset(&piCachingStamps[0], 0x0, pMesh->mNumVertices * sizeof(unsigned int));
|
||||||
|
|
||||||
// allocate an empty output index buffer. We store the output indices in one large array.
|
// allocate an empty output index buffer. We store the output indices in one large array.
|
||||||
// Since the number of triangles won't change the input faces can be reused. This is how
|
// Since the number of triangles won't change the input faces can be reused. This is how
|
||||||
// we save thousands of redundant mini allocations for aiFace::mIndices
|
// we save thousands of redundant mini allocations for aiFace::mIndices
|
||||||
const unsigned int iIdxCnt = pMesh->mNumFaces*3;
|
const unsigned int iIdxCnt = pMesh->mNumFaces * 3;
|
||||||
unsigned int* const piIBOutput = new unsigned int[iIdxCnt];
|
std::vector<unsigned int> piIBOutput;
|
||||||
unsigned int* piCSIter = piIBOutput;
|
piIBOutput.resize(iIdxCnt);
|
||||||
|
std::vector<unsigned int>::iterator piCSIter = piIBOutput.begin();
|
||||||
|
|
||||||
// allocate the flag array to hold the information
|
// allocate the flag array to hold the information
|
||||||
// whether a face has already been emitted or not
|
// whether a face has already been emitted or not
|
||||||
std::vector<bool> abEmitted(pMesh->mNumFaces,false);
|
std::vector<bool> abEmitted(pMesh->mNumFaces, false);
|
||||||
|
|
||||||
// dead-end vertex index stack
|
// dead-end vertex index stack
|
||||||
std::stack<unsigned int, std::vector<unsigned int> > sDeadEndVStack;
|
std::stack<unsigned int, std::vector<unsigned int>> sDeadEndVStack;
|
||||||
|
|
||||||
// create a copy of the piNumTriPtr buffer
|
// create a copy of the piNumTriPtr buffer
|
||||||
unsigned int* const piNumTriPtr = adj.mLiveTriangles;
|
unsigned int *const piNumTriPtr = adj.mLiveTriangles;
|
||||||
const std::vector<unsigned int> piNumTriPtrNoModify(piNumTriPtr, piNumTriPtr + pMesh->mNumVertices);
|
const std::vector<unsigned int> piNumTriPtrNoModify(piNumTriPtr, piNumTriPtr + pMesh->mNumVertices);
|
||||||
|
|
||||||
// get the largest number of referenced triangles and allocate the "candidate buffer"
|
// get the largest number of referenced triangles and allocate the "candidate buffer"
|
||||||
unsigned int iMaxRefTris = 0; {
|
unsigned int iMaxRefTris = 0;
|
||||||
const unsigned int* piCur = adj.mLiveTriangles;
|
{
|
||||||
const unsigned int* const piCurEnd = adj.mLiveTriangles+pMesh->mNumVertices;
|
const unsigned int *piCur = adj.mLiveTriangles;
|
||||||
for (;piCur != piCurEnd;++piCur) {
|
const unsigned int *const piCurEnd = adj.mLiveTriangles + pMesh->mNumVertices;
|
||||||
iMaxRefTris = std::max(iMaxRefTris,*piCur);
|
for (; piCur != piCurEnd; ++piCur) {
|
||||||
|
iMaxRefTris = std::max(iMaxRefTris, *piCur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ai_assert(iMaxRefTris > 0);
|
ai_assert(iMaxRefTris > 0);
|
||||||
unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
|
std::vector<unsigned int> piCandidates;
|
||||||
|
piCandidates.resize(iMaxRefTris * 3);
|
||||||
unsigned int iCacheMisses = 0;
|
unsigned int iCacheMisses = 0;
|
||||||
|
|
||||||
// ...................................................................................
|
// ...................................................................................
|
||||||
|
@ -245,23 +254,23 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
|
|
||||||
int ivdx = 0;
|
int ivdx = 0;
|
||||||
int ics = 1;
|
int ics = 1;
|
||||||
int iStampCnt = mConfigCacheDepth+1;
|
int iStampCnt = mConfigCacheDepth + 1;
|
||||||
while (ivdx >= 0) {
|
while (ivdx >= 0) {
|
||||||
|
|
||||||
unsigned int icnt = piNumTriPtrNoModify[ivdx];
|
unsigned int icnt = piNumTriPtrNoModify[ivdx];
|
||||||
unsigned int* piList = adj.GetAdjacentTriangles(ivdx);
|
unsigned int *piList = adj.GetAdjacentTriangles(ivdx);
|
||||||
unsigned int* piCurCandidate = piCandidates;
|
std::vector<unsigned int>::iterator piCurCandidate = piCandidates.begin();
|
||||||
|
|
||||||
// get all triangles in the neighborhood
|
// get all triangles in the neighborhood
|
||||||
for (unsigned int tri = 0; tri < icnt;++tri) {
|
for (unsigned int tri = 0; tri < icnt; ++tri) {
|
||||||
|
|
||||||
// if they have not yet been emitted, add them to the output IB
|
// if they have not yet been emitted, add them to the output IB
|
||||||
const unsigned int fidx = *piList++;
|
const unsigned int fidx = *piList++;
|
||||||
if (!abEmitted[fidx]) {
|
if (!abEmitted[fidx]) {
|
||||||
|
|
||||||
// so iterate through all vertices of the current triangle
|
// so iterate through all vertices of the current triangle
|
||||||
const aiFace* pcFace = &pMesh->mFaces[ fidx ];
|
const aiFace *pcFace = &pMesh->mFaces[fidx];
|
||||||
unsigned nind = pcFace->mNumIndices;
|
const unsigned nind = pcFace->mNumIndices;
|
||||||
for (unsigned ind = 0; ind < nind; ind++) {
|
for (unsigned ind = 0; ind < nind; ind++) {
|
||||||
unsigned dp = pcFace->mIndices[ind];
|
unsigned dp = pcFace->mIndices[ind];
|
||||||
|
|
||||||
|
@ -281,7 +290,7 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
*piCSIter++ = dp;
|
*piCSIter++ = dp;
|
||||||
|
|
||||||
// if the vertex is not yet in cache, set its cache count
|
// if the vertex is not yet in cache, set its cache count
|
||||||
if (iStampCnt-piCachingStamps[dp] > mConfigCacheDepth) {
|
if (iStampCnt - piCachingStamps[dp] > mConfigCacheDepth) {
|
||||||
piCachingStamps[dp] = iStampCnt++;
|
piCachingStamps[dp] = iStampCnt++;
|
||||||
++iCacheMisses;
|
++iCacheMisses;
|
||||||
}
|
}
|
||||||
|
@ -297,16 +306,16 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
// get next fanning vertex
|
// get next fanning vertex
|
||||||
ivdx = -1;
|
ivdx = -1;
|
||||||
int max_priority = -1;
|
int max_priority = -1;
|
||||||
for (unsigned int* piCur = piCandidates;piCur != piCurCandidate;++piCur) {
|
for (std::vector<unsigned int>::iterator piCur = piCandidates.begin(); piCur != piCurCandidate; ++piCur) {
|
||||||
const unsigned int dp = *piCur;
|
const unsigned int dp = *piCur;
|
||||||
|
|
||||||
// must have live triangles
|
// must have live triangles
|
||||||
if (piNumTriPtr[dp] > 0) {
|
if (piNumTriPtr[dp] > 0) {
|
||||||
int priority = 0;
|
int priority = 0;
|
||||||
|
|
||||||
// will the vertex be in cache, even after fanning occurs?
|
// will the vertex be in cache, even after fanning occurs?
|
||||||
unsigned int tmp;
|
unsigned int tmp;
|
||||||
if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= mConfigCacheDepth) {
|
if ((tmp = iStampCnt - piCachingStamps[dp]) + 2 * piNumTriPtr[dp] <= mConfigCacheDepth) {
|
||||||
priority = tmp;
|
priority = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +333,7 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
while (!sDeadEndVStack.empty()) {
|
while (!sDeadEndVStack.empty()) {
|
||||||
unsigned int iCachedIdx = sDeadEndVStack.top();
|
unsigned int iCachedIdx = sDeadEndVStack.top();
|
||||||
sDeadEndVStack.pop();
|
sDeadEndVStack.pop();
|
||||||
if (piNumTriPtr[ iCachedIdx ] > 0) {
|
if (piNumTriPtr[iCachedIdx] > 0) {
|
||||||
ivdx = iCachedIdx;
|
ivdx = iCachedIdx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -333,9 +342,9 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
if (-1 == ivdx) {
|
if (-1 == ivdx) {
|
||||||
// well, there isn't such a vertex. Simply get the next vertex in input order and
|
// well, there isn't such a vertex. Simply get the next vertex in input order and
|
||||||
// hope it is not too bad ...
|
// hope it is not too bad ...
|
||||||
while (ics < (int)pMesh->mNumVertices) {
|
while (ics < (int)pMesh->mNumVertices) {
|
||||||
++ics;
|
++ics;
|
||||||
if (piNumTriPtr[ics] > 0) {
|
if (piNumTriPtr[ics] > 0) {
|
||||||
ivdx = ics;
|
ivdx = ics;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -345,29 +354,29 @@ ai_real ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int me
|
||||||
}
|
}
|
||||||
ai_real fACMR2 = 0.0f;
|
ai_real fACMR2 = 0.0f;
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
fACMR2 = (float)iCacheMisses / pMesh->mNumFaces;
|
fACMR2 = static_cast<ai_real>(iCacheMisses / pMesh->mNumFaces);
|
||||||
|
const ai_real averageACMR = ((fACMR - fACMR2) / fACMR) * 100.f;
|
||||||
// very intense verbose logging ... prepare for much text if there are many meshes
|
// very intense verbose logging ... prepare for much text if there are many meshes
|
||||||
if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
|
if (DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
|
||||||
ASSIMP_LOG_VERBOSE_DEBUG("Mesh %u | ACMR in: ", meshNum, " out: ", fACMR, " | ~", fACMR2, ((fACMR - fACMR2) / fACMR) * 100.f);
|
ASSIMP_LOG_VERBOSE_DEBUG("Mesh ", meshNum, "| ACMR in: ", fACMR, " out: ", fACMR2, " | average ACMR ", averageACMR);
|
||||||
}
|
}
|
||||||
|
|
||||||
fACMR2 *= pMesh->mNumFaces;
|
fACMR2 *= pMesh->mNumFaces;
|
||||||
}
|
}
|
||||||
// sort the output index buffer back to the input array
|
|
||||||
piCSIter = piIBOutput;
|
|
||||||
for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace) {
|
|
||||||
unsigned nind = pcFace->mNumIndices;
|
|
||||||
unsigned * ind = pcFace->mIndices;
|
|
||||||
if (nind > 0) ind[0] = *piCSIter++;
|
|
||||||
if (nind > 1) ind[1] = *piCSIter++;
|
|
||||||
if (nind > 2) ind[2] = *piCSIter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete temporary storage
|
// sort the output index buffer back to the input array
|
||||||
delete[] piCachingStamps;
|
piCSIter = piIBOutput.begin();
|
||||||
delete[] piIBOutput;
|
for (aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
|
||||||
delete[] piCandidates;
|
unsigned nind = pcFace->mNumIndices;
|
||||||
|
unsigned *ind = pcFace->mIndices;
|
||||||
|
if (nind > 0)
|
||||||
|
ind[0] = *piCSIter++;
|
||||||
|
if (nind > 1)
|
||||||
|
ind[1] = *piCSIter++;
|
||||||
|
if (nind > 2)
|
||||||
|
ind[2] = *piCSIter++;
|
||||||
|
}
|
||||||
|
|
||||||
return fACMR2;
|
return fACMR2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace Assimp
|
||||||
|
|
|
@ -290,12 +290,6 @@ void PretransformVertices::ComputeAbsoluteTransform(aiNode *pcNode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut, size_t numVectors) {
|
|
||||||
for (size_t i=0; i<numVectors; ++i) {
|
|
||||||
vectorArrayOut[i] = vectorArrayIn[i].Normalize();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Apply the node transformation to a mesh
|
// Apply the node transformation to a mesh
|
||||||
void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat) const {
|
void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat) const {
|
||||||
|
@ -322,8 +316,11 @@ void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat)
|
||||||
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
|
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
|
||||||
|
|
||||||
if (mesh->HasNormals()) {
|
if (mesh->HasNormals()) {
|
||||||
normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
|
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->HasTangentsAndBitangents()) {
|
if (mesh->HasTangentsAndBitangents()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
|
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -1085,6 +1085,19 @@ enum aiComponent
|
||||||
*/
|
*/
|
||||||
#define AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS "USE_GLTF_PBR_SPECULAR_GLOSSINESS"
|
#define AI_CONFIG_USE_GLTF_PBR_SPECULAR_GLOSSINESS "USE_GLTF_PBR_SPECULAR_GLOSSINESS"
|
||||||
|
|
||||||
|
/** @brief Specifies whether to apply a limit on the number of four bones per vertex in skinning
|
||||||
|
*
|
||||||
|
* When this flag is not defined, all bone weights and indices are limited to a
|
||||||
|
* maximum of four bones for each vertex (attributes JOINT_0 and WEIGHT_0 only).
|
||||||
|
* By enabling this flag, the number of bones per vertex is unlimited.
|
||||||
|
* In both cases, indices and bone weights are sorted by weight in descending order.
|
||||||
|
* In the case of the limit of up to four bones, a maximum of the four largest values are exported.
|
||||||
|
* Weights are not normalized.
|
||||||
|
* Property type: Bool. Default value: false.
|
||||||
|
*/
|
||||||
|
#define AI_CONFIG_EXPORT_GLTF_UNLIMITED_SKINNING_BONES_PER_VERTEX \
|
||||||
|
"USE_UNLIMITED_BONES_PER VERTEX"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Specifies the blob name, assimp uses for exporting.
|
* @brief Specifies the blob name, assimp uses for exporting.
|
||||||
*
|
*
|
||||||
|
|
|
@ -59,6 +59,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -872,11 +874,15 @@ struct aiMesh {
|
||||||
|
|
||||||
// DO NOT REMOVE THIS ADDITIONAL CHECK
|
// DO NOT REMOVE THIS ADDITIONAL CHECK
|
||||||
if (mNumBones && mBones) {
|
if (mNumBones && mBones) {
|
||||||
|
std::unordered_set<const aiBone *> bones;
|
||||||
for (unsigned int a = 0; a < mNumBones; a++) {
|
for (unsigned int a = 0; a < mNumBones; a++) {
|
||||||
if (mBones[a]) {
|
if (mBones[a]) {
|
||||||
delete mBones[a];
|
bones.insert(mBones[a]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (const aiBone *bone: bones) {
|
||||||
|
delete bone;
|
||||||
|
}
|
||||||
delete[] mBones;
|
delete[] mBones;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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'
|
||||||
|
|
Binary file not shown.
|
@ -48,6 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
class BlendImportAreaLight : public ::testing::Test {
|
class BlendImportAreaLight : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
|
BlendImportAreaLight() :
|
||||||
|
im(nullptr) {}
|
||||||
|
~BlendImportAreaLight() override = default;
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
im = new Assimp::Importer();
|
im = new Assimp::Importer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,14 @@ using namespace ::Assimp;
|
||||||
|
|
||||||
class BlenderWorkTest : public ::testing::Test {
|
class BlenderWorkTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
virtual void SetUp() {
|
BlenderWorkTest() : im(nullptr) {}
|
||||||
|
~BlenderWorkTest() override = default;
|
||||||
|
|
||||||
|
void SetUp() override {
|
||||||
im = new Assimp::Importer();
|
im = new Assimp::Importer();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void TearDown() {
|
void TearDown() override {
|
||||||
delete im;
|
delete im;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue