Merge branch 'master' into patch-1

pull/3289/head
Kim Kulling 2020-07-12 18:54:34 +02:00 committed by GitHub
commit 78d0b81b6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
181 changed files with 9961 additions and 10684 deletions

107
Readme.md
View File

@ -25,107 +25,12 @@ Additionally, assimp features various __mesh post processing tools__: normals an
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases). This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
Monthly donations via Patreon:
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
<br>
One-off donations via PayPal:
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
<br>
Please check our Wiki as well: https://github.com/assimp/assimp/wiki Please check our Wiki as well: https://github.com/assimp/assimp/wiki
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
#### Supported file formats #### #### Supported file formats ####
You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
__Importers__:
- 3D
- [3DS](https://en.wikipedia.org/wiki/.3ds)
- [3MF](https://en.wikipedia.org/wiki/3D_Manufacturing_Format)
- AC
- [AC3D](https://en.wikipedia.org/wiki/AC3D)
- ACC
- AMJ
- ASE
- ASK
- B3D
- [BLEND](https://en.wikipedia.org/wiki/.blend_(file_format))
- [BVH](https://en.wikipedia.org/wiki/Biovision_Hierarchy)
- CMS
- COB
- [DAE/Collada](https://en.wikipedia.org/wiki/COLLADA)
- [DXF](https://en.wikipedia.org/wiki/AutoCAD_DXF)
- ENFF
- [FBX](https://en.wikipedia.org/wiki/FBX)
- [glTF 1.0](https://en.wikipedia.org/wiki/GlTF#glTF_1.0) + GLB
- [glTF 2.0](https://en.wikipedia.org/wiki/GlTF#glTF_2.0):
At the moment for glTF2.0 the following extensions are supported:
+ KHR_lights_punctual ( 5.0 )
+ KHR_materials_pbrSpecularGlossiness ( 5.0 )
+ KHR_materials_unlit ( 5.0 )
+ KHR_texture_transform ( 5.1 under test )
- HMB
- IFC-STEP
- IRR / IRRMESH
- [LWO](https://en.wikipedia.org/wiki/LightWave_3D)
- LWS
- LXO
- [M3D](https://bztsrc.gitlab.io/model3d)
- MD2
- MD3
- MD5
- MDC
- MDL
- MESH / MESH.XML
- MOT
- MS3D
- NDO
- NFF
- [OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file)
- [OFF](https://en.wikipedia.org/wiki/OFF_(file_format))
- [OGEX](https://en.wikipedia.org/wiki/Open_Game_Engine_Exchange)
- [PLY](https://en.wikipedia.org/wiki/PLY_(file_format))
- PMX
- PRJ
- Q3O
- Q3S
- RAW
- SCN
- SIB
- SMD
- [STP](https://en.wikipedia.org/wiki/ISO_10303-21)
- [STL](https://en.wikipedia.org/wiki/STL_(file_format))
- TER
- UC
- VTA
- X
- [X3D](https://en.wikipedia.org/wiki/X3D)
- XGL
- ZGL
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
- [C4D](https://en.wikipedia.org/wiki/Cinema_4D) (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange) IMporting geometry + node hierarchy are currently supported
__Exporters__:
- DAE (Collada)
- STL
- OBJ
- PLY
- X
- 3DS
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
- ASSBIN
- STEP
- glTF 1.0 (partial)
- glTF 2.0 (partial)
- 3MF ( experimental )
- FBX ( experimental )
### Building ### ### Building ###
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do. Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
@ -196,6 +101,16 @@ Become a financial contributor and help us sustain our community. [[Contribute](
<a href="https://opencollective.com/assimp"><img src="https://opencollective.com/assimp/individuals.svg?width=890"></a> <a href="https://opencollective.com/assimp"><img src="https://opencollective.com/assimp/individuals.svg?width=890"></a>
Monthly donations via Patreon:
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
<br>
One-off donations via PayPal:
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
<br>
#### Organizations #### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)] Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]

View File

@ -367,7 +367,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial &mat, aiTextureType type
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
}; };
ai_real blend = 1.0; ai_real blend = 1.0;
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) { if (mat.GetTexture(type, 0, &path, nullptr, nullptr, &blend, nullptr, map_mode) != AI_SUCCESS || !path.length) {
return; return;
} }

View File

@ -321,7 +321,7 @@ public:
struct Face : public FaceWithSmoothingGroup { struct Face : public FaceWithSmoothingGroup {
}; };
#ifdef _WIN32 #if _MSC_VER > 1920
#pragma warning(disable : 4315) #pragma warning(disable : 4315)
#endif #endif
@ -462,30 +462,28 @@ struct Material {
sTexAmbient(other.sTexAmbient), sTexAmbient(other.sTexAmbient),
mTwoSided(other.mTwoSided) { mTwoSided(other.mTwoSided) {
// empty // empty
} }
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT : Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
mName(std::move(other.mName)), mDiffuse(std::move(other.mDiffuse)),
mDiffuse(std::move(other.mDiffuse)), mSpecularExponent(std::move(other.mSpecularExponent)),
mSpecularExponent(std::move(other.mSpecularExponent)), mShininessStrength(std::move(other.mShininessStrength)),
mShininessStrength(std::move(other.mShininessStrength)), mSpecular(std::move(other.mSpecular)),
mSpecular(std::move(other.mSpecular)), mAmbient(std::move(other.mAmbient)),
mAmbient(std::move(other.mAmbient)), mShading(std::move(other.mShading)),
mShading(std::move(other.mShading)), mTransparency(std::move(other.mTransparency)),
mTransparency(std::move(other.mTransparency)), sTexDiffuse(std::move(other.sTexDiffuse)),
sTexDiffuse(std::move(other.sTexDiffuse)), sTexOpacity(std::move(other.sTexOpacity)),
sTexOpacity(std::move(other.sTexOpacity)), sTexSpecular(std::move(other.sTexSpecular)),
sTexSpecular(std::move(other.sTexSpecular)), sTexReflective(std::move(other.sTexReflective)),
sTexReflective(std::move(other.sTexReflective)), sTexBump(std::move(other.sTexBump)),
sTexBump(std::move(other.sTexBump)), sTexEmissive(std::move(other.sTexEmissive)),
sTexEmissive(std::move(other.sTexEmissive)), sTexShininess(std::move(other.sTexShininess)),
sTexShininess(std::move(other.sTexShininess)), mBumpHeight(std::move(other.mBumpHeight)),
mBumpHeight(std::move(other.mBumpHeight)), mEmissive(std::move(other.mEmissive)),
mEmissive(std::move(other.mEmissive)), sTexAmbient(std::move(other.sTexAmbient)),
sTexAmbient(std::move(other.sTexAmbient)), mTwoSided(std::move(other.mTwoSided)) {
mTwoSided(std::move(other.mTwoSided)) {
// empty // empty
} }
@ -615,7 +613,12 @@ struct Node {
Node() = delete; Node() = delete;
explicit Node(const std::string &name) : explicit Node(const std::string &name) :
mParent(NULL), mName(name), mInstanceNumber(0), mHierarchyPos(0), mHierarchyIndex(0), mInstanceCount(1) { mParent(nullptr),
mName(name),
mInstanceNumber(0),
mHierarchyPos(0),
mHierarchyIndex(0),
mInstanceCount(1) {
aRotationKeys.reserve(20); aRotationKeys.reserve(20);
aPositionKeys.reserve(20); aPositionKeys.reserve(20);
aScalingKeys.reserve(20); aScalingKeys.reserve(20);

View File

@ -314,19 +314,19 @@ private:
++buf; ++buf;
comp[1] = *buf; comp[1] = *buf;
++buf; ++buf;
diffuse.r = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0); diffuse.r = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
comp[0] = *buf; comp[0] = *buf;
++buf; ++buf;
comp[1] = *buf; comp[1] = *buf;
++buf; ++buf;
diffuse.g = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0); diffuse.g = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
comp[0] = *buf; comp[0] = *buf;
++buf; ++buf;
comp[1] = *buf; comp[1] = *buf;
++buf; ++buf;
diffuse.b = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0); diffuse.b = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
if (7 == len) if (7 == len)
return true; return true;
@ -334,7 +334,7 @@ private:
++buf; ++buf;
comp[1] = *buf; comp[1] = *buf;
++buf; ++buf;
diffuse.a = static_cast<ai_real>(strtol(comp, NULL, 16)) / ai_real(255.0); diffuse.a = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
return true; return true;
} }

View File

@ -45,19 +45,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFOpcPackage.h" #include "D3MFOpcPackage.h"
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/ai_assert.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <cstdlib> #include "3MFXmlTags.h"
#include <memory>
#include <vector>
#include <map>
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
#include "3MFXmlTags.h" #include <cstdlib>
#include <map>
#include <memory>
#include <vector>
namespace Assimp { namespace Assimp {
@ -68,49 +68,45 @@ typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
class OpcPackageRelationshipReader { class OpcPackageRelationshipReader {
public: public:
OpcPackageRelationshipReader(XmlReader* xmlReader) { OpcPackageRelationshipReader(XmlReader *xmlReader) {
while(xmlReader->read()) { while (xmlReader->read()) {
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT && if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER) xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER) {
{
ParseRootNode(xmlReader); ParseRootNode(xmlReader);
} }
} }
} }
void ParseRootNode(XmlReader* xmlReader) void ParseRootNode(XmlReader *xmlReader) {
{
ParseAttributes(xmlReader); ParseAttributes(xmlReader);
while(xmlReader->read()) while (xmlReader->read()) {
{ if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT && xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE) {
xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
{
ParseChildNode(xmlReader); ParseChildNode(xmlReader);
} }
} }
} }
void ParseAttributes(XmlReader*) { void ParseAttributes(XmlReader *) {
// empty // empty
} }
bool validateRels( OpcPackageRelationshipPtr &relPtr ) { bool validateRels(OpcPackageRelationshipPtr &relPtr) {
if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) { if (relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty()) {
return false; return false;
} }
return true; return true;
} }
void ParseChildNode(XmlReader* xmlReader) { void ParseChildNode(XmlReader *xmlReader) {
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship()); OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str()); relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str());
relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str()); relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str());
relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str()); relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str());
if ( validateRels( relPtr ) ) { if (validateRels(relPtr)) {
m_relationShips.push_back( relPtr ); m_relationShips.push_back(relPtr);
} }
} }
@ -118,32 +114,34 @@ public:
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile) D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
: mRootStream(nullptr) mRootStream(nullptr), mZipArchive() {
, mZipArchive() { mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
mZipArchive.reset( new ZipArchiveIOSystem( pIOHandler, rFile ) ); if (!mZipArchive->isOpen()) {
if(!mZipArchive->isOpen()) { throw DeadlyImportError("Failed to open file " + rFile + ".");
throw DeadlyImportError("Failed to open file " + rFile+ ".");
} }
std::vector<std::string> fileList; std::vector<std::string> fileList;
mZipArchive->getFileList(fileList); mZipArchive->getFileList(fileList);
for (auto& file: fileList) { for (auto &file : fileList) {
if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) { if (file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
//PkgRelationshipReader pkgRelReader(file, archive); if (!mZipArchive->Exists(file.c_str())) {
ai_assert(mZipArchive->Exists(file.c_str())); continue;
}
IOStream *fileStream = mZipArchive->Open(file.c_str()); IOStream *fileStream = mZipArchive->Open(file.c_str());
if (nullptr == fileStream) {
ai_assert(fileStream != nullptr); ai_assert(fileStream != nullptr);
continue;
}
std::string rootFile = ReadPackageRootRelationship(fileStream); std::string rootFile = ReadPackageRootRelationship(fileStream);
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) { if (rootFile.size() > 0 && rootFile[0] == '/') {
rootFile = rootFile.substr( 1 ); rootFile = rootFile.substr(1);
if ( rootFile[ 0 ] == '/' ) { if (rootFile[0] == '/') {
// deal with zip-bug // deal with zip-bug
rootFile = rootFile.substr( 1 ); rootFile = rootFile.substr(1);
} }
} }
@ -152,17 +150,16 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
mZipArchive->Close(fileStream); mZipArchive->Close(fileStream);
mRootStream = mZipArchive->Open(rootFile.c_str()); mRootStream = mZipArchive->Open(rootFile.c_str());
ai_assert( mRootStream != nullptr ); ai_assert(mRootStream != nullptr);
if ( nullptr == mRootStream ) { if (nullptr == mRootStream) {
throw DeadlyExportError( "Cannot open root-file in archive : " + rootFile ); throw DeadlyExportError("Cannot open root-file in archive : " + rootFile);
} }
} else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) { } else if (file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES",file); ASSIMP_LOG_WARN_F("Ignored file of unsupported type CONTENT_TYPES_ARCHIVES", file);
} else { } else {
ASSIMP_LOG_WARN_F("Ignored file of unknown type: ",file); ASSIMP_LOG_WARN_F("Ignored file of unknown type: ", file);
} }
} }
} }
@ -170,32 +167,32 @@ D3MFOpcPackage::~D3MFOpcPackage() {
mZipArchive->Close(mRootStream); mZipArchive->Close(mRootStream);
} }
IOStream* D3MFOpcPackage::RootStream() const { IOStream *D3MFOpcPackage::RootStream() const {
return mRootStream; return mRootStream;
} }
static const std::string ModelRef = "3D/3dmodel.model"; static const std::string ModelRef = "3D/3dmodel.model";
bool D3MFOpcPackage::validate() { bool D3MFOpcPackage::validate() {
if ( nullptr == mRootStream || nullptr == mZipArchive ) { if (nullptr == mRootStream || nullptr == mZipArchive) {
return false; return false;
} }
return mZipArchive->Exists( ModelRef.c_str() ); return mZipArchive->Exists(ModelRef.c_str());
} }
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) { std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream)); std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get())); std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
OpcPackageRelationshipReader reader(xml.get()); OpcPackageRelationshipReader reader(xml.get());
auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){ auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.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.m_relationShips.end()) {
throw DeadlyImportError( "Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE ); throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
} }
return (*itr)->target; return (*itr)->target;

View File

@ -627,7 +627,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE)); std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name); ASSIMP_LOG_INFO("AC3D: Evaluating subdivision surface: " + object.name);
std::vector<aiMesh *> cpy(meshes.size() - oldm, NULL); std::vector<aiMesh *> cpy(meshes.size() - oldm, nullptr);
div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true); div->Subdivide(&meshes[oldm], cpy.size(), &cpy.front(), object.subDiv, true);
std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm); std::copy(cpy.begin(), cpy.end(), meshes.begin() + oldm);

View File

@ -366,7 +366,9 @@ void AMFImporter::ParseFile(const std::string &pFile, 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.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + "."); if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
}
// generate a XML reader for it // generate a XML reader for it
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get())); std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));

View File

@ -925,7 +925,7 @@ void Parser::ParseLV2AnimationBlock(ASE::BaseNode &mesh) {
ASSIMP_LOG_ERROR("ASE: Found target animation channel " ASSIMP_LOG_ERROR("ASE: Found target animation channel "
"but the node is neither a camera nor a spot light"); "but the node is neither a camera nor a spot light");
anim = NULL; anim = nullptr;
} else } else
anim = &mesh.mTargetAnim; anim = &mesh.mTargetAnim;
} }
@ -1797,14 +1797,14 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLongTriple(unsigned int *apOut) { void Parser::ParseLV4MeshLongTriple(unsigned int *apOut) {
ai_assert(NULL != apOut); ai_assert(nullptr != apOut);
for (unsigned int i = 0; i < 3; ++i) for (unsigned int i = 0; i < 3; ++i)
ParseLV4MeshLong(apOut[i]); ParseLV4MeshLong(apOut[i]);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut) { void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut) {
ai_assert(NULL != apOut); ai_assert(nullptr != apOut);
// parse the index // parse the index
ParseLV4MeshLong(rIndexOut); ParseLV4MeshLong(rIndexOut);
@ -1814,7 +1814,7 @@ void Parser::ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) { void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
ai_assert(NULL != apOut); ai_assert(nullptr != apOut);
// parse the index // parse the index
ParseLV4MeshLong(rIndexOut); ParseLV4MeshLong(rIndexOut);
@ -1824,7 +1824,7 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) { void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
ai_assert(NULL != apOut); ai_assert(nullptr != apOut);
for (unsigned int i = 0; i < 3; ++i) for (unsigned int i = 0; i < 3; ++i)
ParseLV4MeshFloat(apOut[i]); ParseLV4MeshFloat(apOut[i]);

View File

@ -40,15 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines the helper data structures for importing ASE files */ /** @file Defines the helper data structures for importing ASE files */
#ifndef AI_ASEFILEHELPER_H_INC #ifndef AI_ASEFILEHELPER_H_INC
#define AI_ASEFILEHELPER_H_INC #define AI_ASEFILEHELPER_H_INC
// public ASSIMP headers // public ASSIMP headers
#include <assimp/types.h>
#include <assimp/mesh.h>
#include <assimp/anim.h> #include <assimp/anim.h>
#include <assimp/mesh.h>
#include <assimp/types.h>
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
@ -59,27 +58,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ASE is quite similar to 3ds. We can reuse some structures // ASE is quite similar to 3ds. We can reuse some structures
#include "AssetLib/3DS/3DSLoader.h" #include "AssetLib/3DS/3DSLoader.h"
namespace Assimp { namespace Assimp {
namespace ASE { namespace ASE {
using namespace D3DS; using namespace D3DS;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure representing an ASE material */ /** Helper structure representing an ASE material */
struct Material : public D3DS::Material struct Material : public D3DS::Material {
{
//! Default constructor has been deleted //! Default constructor has been deleted
Material() = delete; Material() = delete;
//! Constructor with explicit name //! Constructor with explicit name
explicit Material(const std::string &name) explicit Material(const std::string &name) :
: D3DS::Material(name) D3DS::Material(name),
, pcInstance(NULL) pcInstance(nullptr),
, bNeed (false) { bNeed(false) {
// empty // empty
} }
Material(const Material &other) = default; Material(const Material &other) = default;
Material &operator=(const Material &other) { Material &operator=(const Material &other) {
if (this == &other) { if (this == &other) {
@ -93,19 +91,16 @@ struct Material : public D3DS::Material
return *this; return *this;
} }
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT Material(Material &&other) AI_NO_EXCEPT
: D3DS::Material(std::move(other)) : D3DS::Material(std::move(other)),
, avSubMaterials(std::move(other.avSubMaterials)) avSubMaterials(std::move(other.avSubMaterials)),
, pcInstance(std::move(other.pcInstance)) pcInstance(std::move(other.pcInstance)),
, bNeed(std::move(other.bNeed)) bNeed(std::move(other.bNeed)) {
{
other.pcInstance = nullptr; other.pcInstance = nullptr;
} }
Material &operator=(Material &&other) AI_NO_EXCEPT {
Material &operator=( Material &&other) AI_NO_EXCEPT {
if (this == &other) { if (this == &other) {
return *this; return *this;
} }
@ -121,15 +116,13 @@ struct Material : public D3DS::Material
return *this; return *this;
} }
~Material() {} ~Material() {}
//! Contains all sub materials of this material //! Contains all sub materials of this material
std::vector<Material> avSubMaterials; std::vector<Material> avSubMaterials;
//! aiMaterial object //! aiMaterial object
aiMaterial* pcInstance; aiMaterial *pcInstance;
//! Can we remove this material? //! Can we remove this material?
bool bNeed; bool bNeed;
@ -140,8 +133,8 @@ struct Material : public D3DS::Material
struct Face : public FaceWithSmoothingGroup { struct Face : public FaceWithSmoothingGroup {
//! Default constructor. Initializes everything with 0 //! Default constructor. Initializes everything with 0
Face() AI_NO_EXCEPT Face() AI_NO_EXCEPT
: iMaterial(DEFAULT_MATINDEX) : iMaterial(DEFAULT_MATINDEX),
, iFace(0) { iFace(0) {
// empty // empty
} }
@ -172,8 +165,8 @@ struct Bone {
Bone() = delete; Bone() = delete;
//! Construction from an existing name //! Construction from an existing name
explicit Bone( const std::string& name) explicit Bone(const std::string &name) :
: mName(name) { mName(name) {
// empty // empty
} }
@ -186,33 +179,34 @@ struct Bone {
struct BoneVertex { struct BoneVertex {
//! Bone and corresponding vertex weight. //! Bone and corresponding vertex weight.
//! -1 for unrequired bones .... //! -1 for unrequired bones ....
std::vector<std::pair<int,float> > mBoneWeights; std::vector<std::pair<int, float>> mBoneWeights;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file animation */ /** Helper structure to represent an ASE file animation */
struct Animation { struct Animation {
enum Type { enum Type {
TRACK = 0x0, TRACK = 0x0,
BEZIER = 0x1, BEZIER = 0x1,
TCB = 0x2 TCB = 0x2
} mRotationType, mScalingType, mPositionType; } mRotationType,
mScalingType, mPositionType;
Animation() AI_NO_EXCEPT Animation() AI_NO_EXCEPT
: mRotationType (TRACK) : mRotationType(TRACK),
, mScalingType (TRACK) mScalingType(TRACK),
, mPositionType (TRACK) { mPositionType(TRACK) {
// empty // empty
} }
//! List of track rotation keyframes //! List of track rotation keyframes
std::vector< aiQuatKey > akeyRotations; std::vector<aiQuatKey> akeyRotations;
//! List of track position keyframes //! List of track position keyframes
std::vector< aiVectorKey > akeyPositions; std::vector<aiVectorKey> akeyPositions;
//! List of track scaling keyframes //! List of track scaling keyframes
std::vector< aiVectorKey > akeyScaling; std::vector<aiVectorKey> akeyScaling;
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -220,7 +214,7 @@ struct Animation {
struct InheritanceInfo { struct InheritanceInfo {
//! Default constructor //! Default constructor
InheritanceInfo() AI_NO_EXCEPT { InheritanceInfo() AI_NO_EXCEPT {
for ( size_t i=0; i<3; ++i ) { for (size_t i = 0; i < 3; ++i) {
abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true; abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
} }
} }
@ -239,17 +233,15 @@ struct InheritanceInfo {
/** Represents an ASE file node. Base class for mesh, light and cameras */ /** Represents an ASE file node. Base class for mesh, light and cameras */
struct BaseNode { struct BaseNode {
enum Type { enum Type {
Light, Light,
Camera, Camera,
Mesh, Mesh,
Dummy Dummy
} mType; } mType;
//! Construction from an existing name //! Construction from an existing name
BaseNode(Type _mType, const std::string &name) BaseNode(Type _mType, const std::string &name) :
: mType (_mType) mType(_mType), mName(name), mProcessed(false) {
, mName (name)
, mProcessed (false) {
// Set mTargetPosition to qnan // Set mTargetPosition to qnan
const ai_real qnan = get_qnan(); const ai_real qnan = get_qnan();
mTargetPosition.x = qnan; mTargetPosition.x = qnan;
@ -289,14 +281,9 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
Mesh() = delete; Mesh() = delete;
//! Construction from an existing name //! Construction from an existing name
explicit Mesh(const std::string &name) explicit Mesh(const std::string &name) :
: BaseNode( BaseNode::Mesh, name ) BaseNode(BaseNode::Mesh, name), mVertexColors(), mBoneVertices(), mBones(), iMaterialIndex(Face::DEFAULT_MATINDEX), bSkip(false) {
, mVertexColors() for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c) {
, mBoneVertices()
, mBones()
, iMaterialIndex(Face::DEFAULT_MATINDEX)
, bSkip (false) {
for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
this->mNumUVComponents[c] = 2; this->mNumUVComponents[c] = 2;
} }
} }
@ -325,10 +312,8 @@ struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE light source */ /** Helper structure to represent an ASE light source */
struct Light : public BaseNode struct Light : public BaseNode {
{ enum LightType {
enum LightType
{
OMNI, OMNI,
TARGET, TARGET,
FREE, FREE,
@ -339,17 +324,13 @@ struct Light : public BaseNode
Light() = delete; Light() = delete;
//! Construction from an existing name //! Construction from an existing name
explicit Light(const std::string &name) explicit Light(const std::string &name) :
: BaseNode (BaseNode::Light, name) BaseNode(BaseNode::Light, name), mLightType(OMNI), mColor(1.f, 1.f, 1.f), mIntensity(1.f) // light is white by default
, mLightType (OMNI) ,
, mColor (1.f,1.f,1.f) mAngle(45.f),
, mIntensity (1.f) // light is white by default mFalloff(0.f) {
, mAngle (45.f)
, mFalloff (0.f)
{
} }
LightType mLightType; LightType mLightType;
aiColor3D mColor; aiColor3D mColor;
ai_real mIntensity; ai_real mIntensity;
@ -359,10 +340,8 @@ struct Light : public BaseNode
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper structure to represent an ASE camera */ /** Helper structure to represent an ASE camera */
struct Camera : public BaseNode struct Camera : public BaseNode {
{ enum CameraType {
enum CameraType
{
FREE, FREE,
TARGET TARGET
}; };
@ -370,18 +349,16 @@ struct Camera : public BaseNode
//! Default constructor has been deleted //! Default constructor has been deleted
Camera() = delete; Camera() = delete;
//! Construction from an existing name //! Construction from an existing name
explicit Camera(const std::string &name) explicit Camera(const std::string &name) :
: BaseNode (BaseNode::Camera, name) BaseNode(BaseNode::Camera, name), mFOV(0.75f) // in radians
, mFOV (0.75f) // in radians ,
, mNear (0.1f) mNear(0.1f),
, mFar (1000.f) // could be zero mFar(1000.f) // could be zero
, mCameraType (FREE) ,
{ mCameraType(FREE) {
} }
ai_real mFOV, mNear, mFar; ai_real mFOV, mNear, mFar;
CameraType mCameraType; CameraType mCameraType;
}; };
@ -391,7 +368,7 @@ struct Camera : public BaseNode
struct Dummy : public BaseNode { struct Dummy : public BaseNode {
//! Constructor //! Constructor
Dummy() AI_NO_EXCEPT Dummy() AI_NO_EXCEPT
: BaseNode (BaseNode::Dummy, "DUMMY") { : BaseNode(BaseNode::Dummy, "DUMMY") {
// empty // empty
} }
}; };
@ -414,7 +391,6 @@ private:
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Construct a parser from a given input file which is //! Construct a parser from a given input file which is
//! guaranteed to be terminated with zero. //! guaranteed to be terminated with zero.
@ -422,15 +398,13 @@ public:
//! @param fileFormatDefault Assumed file format version. If the //! @param fileFormatDefault Assumed file format version. If the
//! file format is specified in the file the new value replaces //! file format is specified in the file the new value replaces
//! the default value. //! the default value.
Parser (const char* szFile, unsigned int fileFormatDefault); Parser(const char *szFile, unsigned int fileFormatDefault);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parses the file into the parsers internal representation //! Parses the file into the parsers internal representation
void Parse(); void Parse();
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse the *SCENE block in a file //! Parse the *SCENE block in a file
void ParseLV1SceneBlock(); void ParseLV1SceneBlock();
@ -446,45 +420,45 @@ private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *<xxx>OBJECT block in a file //! Parse a *<xxx>OBJECT block in a file
//! \param mesh Node to be filled //! \param mesh Node to be filled
void ParseLV1ObjectBlock(BaseNode& mesh); void ParseLV1ObjectBlock(BaseNode &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MATERIAL blocks in a material list //! Parse a *MATERIAL blocks in a material list
//! \param mat Material structure to be filled //! \param mat Material structure to be filled
void ParseLV2MaterialBlock(Material& mat); void ParseLV2MaterialBlock(Material &mat);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *NODE_TM block in a file //! Parse a *NODE_TM block in a file
//! \param mesh Node (!) object to be filled //! \param mesh Node (!) object to be filled
void ParseLV2NodeTransformBlock(BaseNode& mesh); void ParseLV2NodeTransformBlock(BaseNode &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *TM_ANIMATION block in a file //! Parse a *TM_ANIMATION block in a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV2AnimationBlock(BaseNode& mesh); void ParseLV2AnimationBlock(BaseNode &mesh);
void ParseLV3PosAnimationBlock(ASE::Animation& anim); void ParseLV3PosAnimationBlock(ASE::Animation &anim);
void ParseLV3ScaleAnimationBlock(ASE::Animation& anim); void ParseLV3ScaleAnimationBlock(ASE::Animation &anim);
void ParseLV3RotAnimationBlock(ASE::Animation& anim); void ParseLV3RotAnimationBlock(ASE::Animation &anim);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH block in a file //! Parse a *MESH block in a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV2MeshBlock(Mesh& mesh); void ParseLV2MeshBlock(Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *LIGHT_SETTINGS block in a file //! Parse a *LIGHT_SETTINGS block in a file
//! \param light Light object to be filled //! \param light Light object to be filled
void ParseLV2LightSettingsBlock(Light& light); void ParseLV2LightSettingsBlock(Light &light);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *CAMERA_SETTINGS block in a file //! Parse a *CAMERA_SETTINGS block in a file
//! \param cam Camera object to be filled //! \param cam Camera object to be filled
void ParseLV2CameraSettingsBlock(Camera& cam); void ParseLV2CameraSettingsBlock(Camera &cam);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse the *MAP_XXXXXX blocks in a material //! Parse the *MAP_XXXXXX blocks in a material
//! \param map Texture structure to be filled //! \param map Texture structure to be filled
void ParseLV3MapBlock(Texture& map); void ParseLV3MapBlock(Texture &map);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_VERTEX_LIST block in a file //! Parse a *MESH_VERTEX_LIST block in a file
@ -493,7 +467,7 @@ private:
//! A warning is sent to the logger if the validations fails. //! A warning is sent to the logger if the validations fails.
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MeshVertexListBlock( void ParseLV3MeshVertexListBlock(
unsigned int iNumVertices,Mesh& mesh); unsigned int iNumVertices, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_FACE_LIST block in a file //! Parse a *MESH_FACE_LIST block in a file
@ -502,7 +476,7 @@ private:
//! A warning is sent to the logger if the validations fails. //! A warning is sent to the logger if the validations fails.
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MeshFaceListBlock( void ParseLV3MeshFaceListBlock(
unsigned int iNumFaces,Mesh& mesh); unsigned int iNumFaces, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_TVERT_LIST block in a file //! Parse a *MESH_TVERT_LIST block in a file
@ -512,7 +486,7 @@ private:
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
//! \param iChannel Output UVW channel //! \param iChannel Output UVW channel
void ParseLV3MeshTListBlock( void ParseLV3MeshTListBlock(
unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0); unsigned int iNumVertices, Mesh &mesh, unsigned int iChannel = 0);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_TFACELIST block in a file //! Parse a *MESH_TFACELIST block in a file
@ -522,7 +496,7 @@ private:
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
//! \param iChannel Output UVW channel //! \param iChannel Output UVW channel
void ParseLV3MeshTFaceListBlock( void ParseLV3MeshTFaceListBlock(
unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0); unsigned int iNumFaces, Mesh &mesh, unsigned int iChannel = 0);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse an additional mapping channel //! Parse an additional mapping channel
@ -530,7 +504,7 @@ private:
//! \param iChannel Channel index to be filled //! \param iChannel Channel index to be filled
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MappingChannel( void ParseLV3MappingChannel(
unsigned int iChannel, Mesh& mesh); unsigned int iChannel, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_CVERTLIST block in a file //! Parse a *MESH_CVERTLIST block in a file
@ -539,7 +513,7 @@ private:
//! A warning is sent to the logger if the validations fails. //! A warning is sent to the logger if the validations fails.
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MeshCListBlock( void ParseLV3MeshCListBlock(
unsigned int iNumVertices, Mesh& mesh); unsigned int iNumVertices, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_CFACELIST block in a file //! Parse a *MESH_CFACELIST block in a file
@ -548,70 +522,70 @@ private:
//! A warning is sent to the logger if the validations fails. //! A warning is sent to the logger if the validations fails.
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MeshCFaceListBlock( void ParseLV3MeshCFaceListBlock(
unsigned int iNumFaces, Mesh& mesh); unsigned int iNumFaces, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_NORMALS block in a file //! Parse a *MESH_NORMALS block in a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MeshNormalListBlock(Mesh& mesh); void ParseLV3MeshNormalListBlock(Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_WEIGHTSblock in a file //! Parse a *MESH_WEIGHTSblock in a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
void ParseLV3MeshWeightsBlock(Mesh& mesh); void ParseLV3MeshWeightsBlock(Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse the bone list of a file //! Parse the bone list of a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
//! \param iNumBones Number of bones in the mesh //! \param iNumBones Number of bones in the mesh
void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh); void ParseLV4MeshBones(unsigned int iNumBones, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse the bone vertices list of a file //! Parse the bone vertices list of a file
//! \param mesh Mesh object to be filled //! \param mesh Mesh object to be filled
//! \param iNumVertices Number of vertices to be parsed //! \param iNumVertices Number of vertices to be parsed
void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh); void ParseLV4MeshBonesVertices(unsigned int iNumVertices, Mesh &mesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_FACE block in a file //! Parse a *MESH_FACE block in a file
//! \param out receive the face data //! \param out receive the face data
void ParseLV4MeshFace(ASE::Face& out); void ParseLV4MeshFace(ASE::Face &out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_VERT block in a file //! Parse a *MESH_VERT block in a file
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...) //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
//! \param apOut Output buffer (3 floats) //! \param apOut Output buffer (3 floats)
//! \param rIndexOut Output index //! \param rIndexOut Output index
void ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut); void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_VERT block in a file //! Parse a *MESH_VERT block in a file
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...) //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
//! \param apOut Output buffer (3 floats) //! \param apOut Output buffer (3 floats)
void ParseLV4MeshFloatTriple(ai_real* apOut); void ParseLV4MeshFloatTriple(ai_real *apOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_TFACE block in a file //! Parse a *MESH_TFACE block in a file
//! (also works for MESH_CFACE) //! (also works for MESH_CFACE)
//! \param apOut Output buffer (3 ints) //! \param apOut Output buffer (3 ints)
//! \param rIndexOut Output index //! \param rIndexOut Output index
void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut); void ParseLV4MeshLongTriple(unsigned int *apOut, unsigned int &rIndexOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a *MESH_TFACE block in a file //! Parse a *MESH_TFACE block in a file
//! (also works for MESH_CFACE) //! (also works for MESH_CFACE)
//! \param apOut Output buffer (3 ints) //! \param apOut Output buffer (3 ints)
void ParseLV4MeshLongTriple(unsigned int* apOut); void ParseLV4MeshLongTriple(unsigned int *apOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a single float element //! Parse a single float element
//! \param fOut Output float //! \param fOut Output float
void ParseLV4MeshFloat(ai_real& fOut); void ParseLV4MeshFloat(ai_real &fOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a single int element //! Parse a single int element
//! \param iOut Output integer //! \param iOut Output integer
void ParseLV4MeshLong(unsigned int& iOut); void ParseLV4MeshLong(unsigned int &iOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Skip everything to the next: '*' or '\0' //! Skip everything to the next: '*' or '\0'
@ -625,17 +599,17 @@ private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Output a warning to the logger //! Output a warning to the logger
//! \param szWarn Warn message //! \param szWarn Warn message
void LogWarning(const char* szWarn); void LogWarning(const char *szWarn);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Output a message to the logger //! Output a message to the logger
//! \param szWarn Message //! \param szWarn Message
void LogInfo(const char* szWarn); void LogInfo(const char *szWarn);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Output an error to the logger //! Output an error to the logger
//! \param szWarn Error message //! \param szWarn Error message
AI_WONT_RETURN void LogError(const char* szWarn) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void LogError(const char *szWarn) AI_WONT_RETURN_SUFFIX;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
//! Parse a string, enclosed in double quotation marks //! Parse a string, enclosed in double quotation marks
@ -643,12 +617,11 @@ private:
//! \param szName Name of the enclosing element -> used in error //! \param szName Name of the enclosing element -> used in error
//! messages. //! messages.
//! \return false if an error occurred //! \return false if an error occurred
bool ParseString(std::string& out,const char* szName); bool ParseString(std::string &out, const char *szName);
public: public:
//! Pointer to current data //! Pointer to current data
const char* filePtr; const char *filePtr;
//! background color to be passed to the viewer //! background color to be passed to the viewer
//! QNAN if none was found //! QNAN if none was found
@ -695,9 +668,8 @@ public:
unsigned int iFileFormat; unsigned int iFileFormat;
}; };
} // Namespace ASE } // Namespace ASE
} // Namespace ASSIMP } // namespace Assimp
#endif // ASSIMP_BUILD_NO_3DS_IMPORTER #endif // ASSIMP_BUILD_NO_3DS_IMPORTER

View File

@ -336,7 +336,7 @@ protected:
void WriteBinaryNode(IOStream *container, const aiNode *node) { void WriteBinaryNode(IOStream *container, const aiNode *node) {
AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE); AssbinChunkWriter chunk(container, ASSBIN_CHUNK_AINODE);
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0); unsigned int nb_metadata = (node->mMetaData != nullptr ? node->mMetaData->mNumProperties : 0);
Write<aiString>(&chunk, node->mName); Write<aiString>(&chunk, node->mName);
Write<aiMatrix4x4>(&chunk, node->mTransformation); Write<aiMatrix4x4>(&chunk, node->mTransformation);
@ -744,7 +744,7 @@ public:
}; };
try { try {
time_t tt = time(NULL); time_t tt = time(nullptr);
#if _WIN32 #if _WIN32
tm *p = gmtime(&tt); tm *p = gmtime(&tt);
#else #else
@ -790,7 +790,7 @@ public:
// Up to here the data is uncompressed. For compressed files, the rest // Up to here the data is uncompressed. For compressed files, the rest
// is compressed using standard DEFLATE from zlib. // is compressed using standard DEFLATE from zlib.
if (compressed) { if (compressed) {
AssbinChunkWriter uncompressedStream(NULL, 0); AssbinChunkWriter uncompressedStream(nullptr, 0);
WriteBinaryScene(&uncompressedStream, pScene); WriteBinaryScene(&uncompressedStream, pScene);
uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell()); uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());

View File

@ -604,7 +604,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) {
// Read node graph // Read node graph
//scene->mRootNode = new aiNode[1]; //scene->mRootNode = new aiNode[1];
ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)NULL); ReadBinaryNode(stream, &scene->mRootNode, (aiNode *)nullptr);
// Read all meshes // Read all meshes
if (scene->mNumMeshes) { if (scene->mNumMeshes) {

View File

@ -189,7 +189,7 @@ static std::string encodeXML(const std::string &data) {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
// Write a text model dump // Write a text model dump
static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene, IOStream *io, bool shortened) { static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene, IOStream *io, bool shortened) {
time_t tt = ::time(NULL); time_t tt = ::time(nullptr);
#if _WIN32 #if _WIN32
tm *p = gmtime(&tt); tm *p = gmtime(&tt);
#else #else

View File

@ -422,9 +422,9 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
anim->mNumChannels = static_cast<unsigned int>(mNodes.size()); anim->mNumChannels = static_cast<unsigned int>(mNodes.size());
anim->mChannels = new aiNodeAnim *[anim->mNumChannels]; anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown // FIX: set the array elements to nullptr to ensure proper deletion if an exception is thrown
for (unsigned int i = 0; i < anim->mNumChannels; ++i) for (unsigned int i = 0; i < anim->mNumChannels; ++i)
anim->mChannels[i] = NULL; anim->mChannels[i] = nullptr;
for (unsigned int a = 0; a < anim->mNumChannels; a++) { for (unsigned int a = 0; a < anim->mNumChannels; a++) {
const Node &node = mNodes[a]; const Node &node = mNodes[a];

View File

@ -230,7 +230,7 @@ public:
// -------------------------------------------------------- // --------------------------------------------------------
/** Access a field of the structure by its canonical name. The pointer version /** Access a field of the structure by its canonical name. The pointer version
* returns NULL on failure while the reference version raises an import error. */ * returns nullptr on failure while the reference version raises an import error. */
inline const Field &operator[](const std::string &ss) const; inline const Field &operator[](const std::string &ss) const;
inline const Field *Get(const std::string &ss) const; inline const Field *Get(const std::string &ss) const;
@ -359,7 +359,7 @@ private:
template <typename T> template <typename T>
T *_allocate(vector<T> &out, size_t &s) const { T *_allocate(vector<T> &out, size_t &s) const {
out.resize(s); out.resize(s);
return s ? &out.front() : NULL; return s ? &out.front() : nullptr;
} }
// -------------------------------------------------------- // --------------------------------------------------------
@ -367,14 +367,14 @@ private:
struct _defaultInitializer { struct _defaultInitializer {
template <typename T, unsigned int N> template <typename T, unsigned int N>
void operator()(T (&out)[N], const char * = NULL) { void operator()(T (&out)[N], const char * = nullptr) {
for (unsigned int i = 0; i < N; ++i) { for (unsigned int i = 0; i < N; ++i) {
out[i] = T(); out[i] = T();
} }
} }
template <typename T, unsigned int N, unsigned int M> template <typename T, unsigned int N, unsigned int M>
void operator()(T (&out)[N][M], const char * = NULL) { void operator()(T (&out)[N][M], const char * = nullptr) {
for (unsigned int i = 0; i < N; ++i) { for (unsigned int i = 0; i < N; ++i) {
for (unsigned int j = 0; j < M; ++j) { for (unsigned int j = 0; j < M; ++j) {
out[i][j] = T(); out[i][j] = T();
@ -383,7 +383,7 @@ private:
} }
template <typename T> template <typename T>
void operator()(T &out, const char * = NULL) { void operator()(T &out, const char * = nullptr) {
out = T(); out = T();
} }
}; };
@ -448,7 +448,7 @@ public:
public: public:
// -------------------------------------------------------- // --------------------------------------------------------
/** Access a structure by its canonical name, the pointer version returns NULL on failure /** Access a structure by its canonical name, the pointer version returns nullptr on failure
* while the reference version raises an error. */ * while the reference version raises an error. */
inline const Structure &operator[](const std::string &ss) const; inline const Structure &operator[](const std::string &ss) const;
inline const Structure *Get(const std::string &ss) const; inline const Structure *Get(const std::string &ss) const;

View File

@ -69,7 +69,7 @@ const Field& Structure :: operator [] (const std::string& ss) const
const Field* Structure :: Get (const std::string& ss) const const Field* Structure :: Get (const std::string& ss) const
{ {
std::map<std::string, size_t>::const_iterator it = indices.find(ss); std::map<std::string, size_t>::const_iterator it = indices.find(ss);
return it == indices.end() ? NULL : &fields[(*it).second]; return it == indices.end() ? nullptr : &fields[(*it).second];
} }
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -322,7 +322,9 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
break; break;
default: default:
ASSIMP_LOG_ERROR("Unknown option.");
ai_assert(false); // shouldn't be here ai_assert(false); // shouldn't be here
break;
} }
mat->AddProperty(&shader, 1, AI_MATKEY_SHADING_MODEL); mat->AddProperty(&shader, 1, AI_MATKEY_SHADING_MODEL);
if (shader != aiShadingMode_Gouraud) { if (shader != aiShadingMode_Gouraud) {

View File

@ -127,7 +127,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
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.get() == NULL) { if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + "."); throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
} }

View File

@ -298,14 +298,14 @@ struct Accessor {
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on. size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component. // For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
std::string mSource; // URL of the source array std::string mSource; // URL of the source array
mutable const Data *mData; // Pointer to the source array, if resolved. NULL else mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else
Accessor() { Accessor() {
mCount = 0; mCount = 0;
mSize = 0; mSize = 0;
mOffset = 0; mOffset = 0;
mStride = 0; mStride = 0;
mData = NULL; mData = nullptr;
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0; mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
} }
}; };
@ -321,13 +321,13 @@ struct InputChannel {
size_t mIndex; // Optional index, if multiple sets of the same data type are given size_t mIndex; // Optional index, if multiple sets of the same data type are given
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better. size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
std::string mAccessor; // ID of the accessor where to read the actual values from. std::string mAccessor; // ID of the accessor where to read the actual values from.
mutable const Accessor *mResolved; // Pointer to the accessor, if resolved. NULL else mutable const Accessor *mResolved; // Pointer to the accessor, if resolved. nullptr else
InputChannel() { InputChannel() {
mType = IT_Invalid; mType = IT_Invalid;
mIndex = 0; mIndex = 0;
mOffset = 0; mOffset = 0;
mResolved = NULL; mResolved = nullptr;
} }
}; };

View File

@ -145,7 +145,7 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
if (extension == "xml" || !extension.length() || checkSig) { if (extension == "xml" || !extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we /* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler * support a specific file extension in general pIOHandler
* might be NULL and it's our duty to return true here. * might be nullptr and it's our duty to return true here.
*/ */
if (!pIOHandler) { if (!pIOHandler) {
return true; return true;
@ -316,7 +316,7 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
for (const auto &nodeInst : pNode->mNodeInstances) { for (const auto &nodeInst : pNode->mNodeInstances) {
// find the corresponding node in the library // find the corresponding node in the library
const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode); const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
const Collada::Node *nd = itt == pParser.mNodeLibrary.end() ? NULL : (*itt).second; const Collada::Node *nd = itt == pParser.mNodeLibrary.end() ? nullptr : (*itt).second;
// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632 // FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
// need to check for both name and ID to catch all. To avoid breaking valid files, // need to check for both name and ID to catch all. To avoid breaking valid files,
@ -716,7 +716,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Collada::M
if (targetMesh->mSubMeshes.size() > 1) { if (targetMesh->mSubMeshes.size() > 1) {
throw DeadlyImportError("Morphing target mesh must be a single"); throw DeadlyImportError("Morphing target mesh must be a single");
} }
aimesh = CreateMesh(pParser, targetMesh, targetMesh->mSubMeshes.at(0), NULL, 0, 0); aimesh = CreateMesh(pParser, targetMesh, targetMesh->mSubMeshes.at(0), nullptr, 0, 0);
mTargetMeshes.push_back(aimesh); mTargetMeshes.push_back(aimesh);
} }
targetMeshes.push_back(aimesh); targetMeshes.push_back(aimesh);
@ -1000,7 +1000,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
combinedAnim->mChannels = new aiNodeAnim *[combinedAnim->mNumChannels]; combinedAnim->mChannels = new aiNodeAnim *[combinedAnim->mNumChannels];
// add the template anim as first channel by moving its aiNodeAnim to the combined animation // add the template anim as first channel by moving its aiNodeAnim to the combined animation
combinedAnim->mChannels[0] = templateAnim->mChannels[0]; combinedAnim->mChannels[0] = templateAnim->mChannels[0];
templateAnim->mChannels[0] = NULL; templateAnim->mChannels[0] = nullptr;
delete templateAnim; delete templateAnim;
// combined animation replaces template animation in the anim array // combined animation replaces template animation in the anim array
mAnims[a] = combinedAnim; mAnims[a] = combinedAnim;
@ -1009,7 +1009,7 @@ void ColladaLoader::StoreAnimations(aiScene *pScene, const ColladaParser &pParse
for (size_t b = 0; b < collectedAnimIndices.size(); ++b) { for (size_t b = 0; b < collectedAnimIndices.size(); ++b) {
aiAnimation *srcAnimation = mAnims[collectedAnimIndices[b]]; aiAnimation *srcAnimation = mAnims[collectedAnimIndices[b]];
combinedAnim->mChannels[1 + b] = srcAnimation->mChannels[0]; combinedAnim->mChannels[1 + b] = srcAnimation->mChannels[0];
srcAnimation->mChannels[0] = NULL; srcAnimation->mChannels[0] = nullptr;
delete srcAnimation; delete srcAnimation;
} }
@ -1116,9 +1116,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// find the collada node corresponding to the aiNode // find the collada node corresponding to the aiNode
const Collada::Node *srcNode = FindNode(pParser.mRootNode, nodeName); const Collada::Node *srcNode = FindNode(pParser.mRootNode, nodeName);
// ai_assert( srcNode != NULL); if (!srcNode) {
if (!srcNode)
continue; continue;
}
// now check all channels if they affect the current node // now check all channels if they affect the current node
std::string targetID, subElement; std::string targetID, subElement;
@ -1132,8 +1132,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
std::string::size_type slashPos = srcChannel.mTarget.find('/'); std::string::size_type slashPos = srcChannel.mTarget.find('/');
if (slashPos == std::string::npos) { if (slashPos == std::string::npos) {
std::string::size_type targetPos = srcChannel.mTarget.find(srcNode->mID); std::string::size_type targetPos = srcChannel.mTarget.find(srcNode->mID);
if (targetPos == std::string::npos) if (targetPos == std::string::npos) {
continue; continue;
}
// not node transform, but something else. store as unknown animation channel for now // not node transform, but something else. store as unknown animation channel for now
entry.mChannel = &(*cit); entry.mChannel = &(*cit);
@ -1777,11 +1778,12 @@ const Collada::Node *ColladaLoader::FindNode(const Collada::Node *pNode, const s
for (size_t a = 0; a < pNode->mChildren.size(); ++a) { for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
const Collada::Node *node = FindNode(pNode->mChildren[a], pName); const Collada::Node *node = FindNode(pNode->mChildren[a], pName);
if (node) if (node) {
return node; return node;
}
} }
return NULL; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------

View File

@ -89,7 +89,7 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
{ {
// validate io-handler instance // validate io-handler instance
if (nullptr == pIOHandler) { if (nullptr == pIOHandler) {
throw DeadlyImportError("IOSystem is NULL."); throw DeadlyImportError("IOSystem is nullptr.");
} }
std::unique_ptr<IOStream> daefile; std::unique_ptr<IOStream> daefile;
@ -322,7 +322,7 @@ void ColladaParser::ReadStructure() {
else if (IsElement("library_cameras")) else if (IsElement("library_cameras"))
ReadCameraLibrary(); ReadCameraLibrary();
else if (IsElement("library_nodes")) else if (IsElement("library_nodes"))
ReadSceneNode(NULL); /* some hacking to reuse this piece of code */ ReadSceneNode(nullptr); /* some hacking to reuse this piece of code */
else if (IsElement("scene")) else if (IsElement("scene"))
ReadScene(); ReadScene();
else else
@ -588,7 +588,7 @@ void ColladaParser::ReadAnimation(Collada::Animation *pParent) {
typedef std::map<std::string, AnimationChannel> ChannelMap; typedef std::map<std::string, AnimationChannel> ChannelMap;
ChannelMap channels; ChannelMap channels;
// this is the anim container in case we're a container // this is the anim container in case we're a container
Animation *anim = NULL; Animation *anim = nullptr;
// optional name given as an attribute // optional name given as an attribute
std::string animName; std::string animName;
@ -1713,9 +1713,6 @@ void ColladaParser::ReadGeometryLibrary() {
int indexID = GetAttribute("id"); int indexID = GetAttribute("id");
std::string id = mReader->getAttributeValue(indexID); std::string id = mReader->getAttributeValue(indexID);
// TODO: (thom) support SIDs
// ai_assert( TestAttribute( "sid") == -1);
// create a mesh and store it in the library under its (resolved) ID // create a mesh and store it in the library under its (resolved) ID
// Skip and warn if ID is not unique // Skip and warn if ID is not unique
if (mMeshLibrary.find(id) == mMeshLibrary.cend()) { if (mMeshLibrary.find(id) == mMeshLibrary.cend()) {
@ -2329,7 +2326,7 @@ size_t ColladaParser::ReadPrimitives(Mesh &pMesh, std::vector<InputChannel> &pPe
return numPrimitives; return numPrimitives;
} }
///@note This function willn't work correctly if both PerIndex and PerVertex channels have same channels. ///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates. ///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior ///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) { void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh, std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
@ -2525,8 +2522,6 @@ void ColladaParser::ReadSceneNode(Node *pNode) {
if (attrName > -1) if (attrName > -1)
child->mName = mReader->getAttributeValue(attrName); child->mName = mReader->getAttributeValue(attrName);
// TODO: (thom) support SIDs
// ai_assert( TestAttribute( "sid") == -1);
if (pNode) { if (pNode) {
pNode->mChildren.push_back(child); pNode->mChildren.push_back(child);
@ -2557,7 +2552,7 @@ void ColladaParser::ReadSceneNode(Node *pNode) {
ReadNodeTransformation(pNode, TF_SKEW); ReadNodeTransformation(pNode, TF_SKEW);
else if (IsElement("translate")) else if (IsElement("translate"))
ReadNodeTransformation(pNode, TF_TRANSLATE); ReadNodeTransformation(pNode, TF_TRANSLATE);
else if (IsElement("render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length()) { else if (IsElement("render") && pNode->mParent == nullptr && 0 == pNode->mPrimaryCamera.length()) {
// ... scene evaluation or, in other words, postprocessing pipeline, // ... scene evaluation or, in other words, postprocessing pipeline,
// or, again in other words, a turing-complete description how to // or, again in other words, a turing-complete description how to
// render a Collada scene. The only thing that is interesting for // render a Collada scene. The only thing that is interesting for
@ -2915,17 +2910,19 @@ const char *ColladaParser::GetTextContent() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace. // Reads the text contents of an element, returns nullptr if not given. Skips leading whitespace.
const char *ColladaParser::TestTextContent() { const char *ColladaParser::TestTextContent() {
// present node should be the beginning of an element // present node should be the beginning of an element
if (mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement()) if (mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement())
return NULL; return nullptr;
// read contents of the element // read contents of the element
if (!mReader->read()) if (!mReader->read()) {
return NULL; return nullptr;
if (mReader->getNodeType() != irr::io::EXN_TEXT && mReader->getNodeType() != irr::io::EXN_CDATA) }
return NULL; if (mReader->getNodeType() != irr::io::EXN_TEXT && mReader->getNodeType() != irr::io::EXN_CDATA) {
return nullptr;
}
// skip leading whitespace // skip leading whitespace
const char *text = mReader->getNodeData(); const char *text = mReader->getNodeData();

View File

@ -272,7 +272,7 @@ protected:
Skips leading whitespace. */ Skips leading whitespace. */
const char *GetTextContent(); const char *GetTextContent();
/** Reads the text contents of an element, returns NULL if not given. /** Reads the text contents of an element, returns nullptr if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char *TestTextContent(); const char *TestTextContent();

View File

@ -47,10 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include "FBXParser.h"
#include "FBXDocument.h" #include "FBXDocument.h"
#include "FBXImporter.h"
#include "FBXDocumentUtil.h" #include "FBXDocumentUtil.h"
#include "FBXImporter.h"
#include "FBXParser.h"
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
@ -58,65 +58,60 @@ namespace FBX {
using namespace Util; using namespace Util;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/) AnimationCurve::AnimationCurve(uint64_t id, const Element &element, const std::string &name, const Document & /*doc*/) :
: Object(id, element, name) Object(id, element, name) {
{ const Scope &sc = GetRequiredScope(element);
const Scope& sc = GetRequiredScope(element); const Element &KeyTime = GetRequiredElement(sc, "KeyTime");
const Element& KeyTime = GetRequiredElement(sc,"KeyTime"); const Element &KeyValueFloat = GetRequiredElement(sc, "KeyValueFloat");
const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
ParseVectorDataArray(keys, KeyTime); ParseVectorDataArray(keys, KeyTime);
ParseVectorDataArray(values, KeyValueFloat); ParseVectorDataArray(values, KeyValueFloat);
if(keys.size() != values.size()) { if (keys.size() != values.size()) {
DOMError("the number of key times does not match the number of keyframe values",&KeyTime); DOMError("the number of key times does not match the number of keyframe values", &KeyTime);
} }
// check if the key times are well-ordered // check if the key times are well-ordered
if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) { if (!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
DOMError("the keyframes are not in ascending order",&KeyTime); DOMError("the keyframes are not in ascending order", &KeyTime);
} }
const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"]; const Element *KeyAttrDataFloat = sc["KeyAttrDataFloat"];
if(KeyAttrDataFloat) { if (KeyAttrDataFloat) {
ParseVectorDataArray(attributes, *KeyAttrDataFloat); ParseVectorDataArray(attributes, *KeyAttrDataFloat);
} }
const Element* KeyAttrFlags = sc["KeyAttrFlags"]; const Element *KeyAttrFlags = sc["KeyAttrFlags"];
if(KeyAttrFlags) { if (KeyAttrFlags) {
ParseVectorDataArray(flags, *KeyAttrFlags); ParseVectorDataArray(flags, *KeyAttrFlags);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurve::~AnimationCurve() AnimationCurve::~AnimationCurve() {
{
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, const std::string &name,
const Document& doc, const char* const * target_prop_whitelist /*= NULL*/, const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
size_t whitelist_size /*= 0*/) size_t whitelist_size /*= 0*/) :
: Object(id, element, name) Object(id, element, name), target(), doc(doc) {
, target() const Scope &sc = GetRequiredScope(element);
, doc(doc)
{
const Scope& sc = GetRequiredScope(element);
// find target node // find target node
const char* whitelist[] = {"Model","NodeAttribute","Deformer"}; const char *whitelist[] = { "Model", "NodeAttribute", "Deformer" };
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,3); const std::vector<const Connection *> &conns = doc.GetConnectionsBySourceSequenced(ID(), whitelist, 3);
for(const Connection* con : conns) { for (const Connection *con : conns) {
// link should go for a property // link should go for a property
if (!con->PropertyName().length()) { if (!con->PropertyName().length()) {
continue; continue;
} }
if(target_prop_whitelist) { if (target_prop_whitelist) {
const char* const s = con->PropertyName().c_str(); const char *const s = con->PropertyName().c_str();
bool ok = false; bool ok = false;
for (size_t i = 0; i < whitelist_size; ++i) { for (size_t i = 0; i < whitelist_size; ++i) {
if (!strcmp(s, target_prop_whitelist[i])) { if (!strcmp(s, target_prop_whitelist[i])) {
@ -130,16 +125,14 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
} }
} }
const Object* const ob = con->DestinationObject(); const Object *const ob = con->DestinationObject();
if(!ob) { if (!ob) {
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element); DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring", &element);
continue; continue;
} }
// XXX support constraints as DOM class
//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
target = ob; target = ob;
if(!target) { if (!target) {
continue; continue;
} }
@ -147,42 +140,40 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
break; break;
} }
if(!target) { if (!target) {
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element); DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode", &element);
} }
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false); props = GetPropertyTable(doc, "AnimationCurveNode.FbxAnimCurveNode", element, sc, false);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurveNode::~AnimationCurveNode() AnimationCurveNode::~AnimationCurveNode() {
{
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const AnimationCurveMap& AnimationCurveNode::Curves() const const AnimationCurveMap &AnimationCurveNode::Curves() const {
{ if (curves.empty()) {
if ( curves.empty() ) {
// resolve attached animation curves // resolve attached animation curves
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve"); const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
for(const Connection* con : conns) { for (const Connection *con : conns) {
// link should go for a property // link should go for a property
if (!con->PropertyName().length()) { if (!con->PropertyName().length()) {
continue; continue;
} }
const Object* const ob = con->SourceObject(); const Object *const ob = con->SourceObject();
if(!ob) { if (nullptr == ob) {
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element); DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
continue; continue;
} }
const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob); const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
if(!anim) { if (nullptr == anim) {
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element); DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
continue; continue;
} }
@ -194,53 +185,49 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc) AnimationLayer::AnimationLayer(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
: Object(id, element, name) Object(id, element, name), doc(doc) {
, doc(doc) const Scope &sc = GetRequiredScope(element);
{
const Scope& sc = GetRequiredScope(element);
// note: the props table here bears little importance and is usually absent // note: the props table here bears little importance and is usually absent
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true); props = GetPropertyTable(doc, "AnimationLayer.FbxAnimLayer", element, sc, true);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationLayer::~AnimationLayer() AnimationLayer::~AnimationLayer() {
{
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
size_t whitelist_size /*= 0*/) const size_t whitelist_size /*= 0*/) const {
{
AnimationCurveNodeList nodes; AnimationCurveNodeList nodes;
// resolve attached animation nodes // resolve attached animation nodes
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode"); const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurveNode");
nodes.reserve(conns.size()); nodes.reserve(conns.size());
for(const Connection* con : conns) { for (const Connection *con : conns) {
// link should not go to a property // link should not go to a property
if (con->PropertyName().length()) { if (con->PropertyName().length()) {
continue; continue;
} }
const Object* const ob = con->SourceObject(); const Object *const ob = con->SourceObject();
if(!ob) { if (!ob) {
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element); DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring", &element);
continue; continue;
} }
const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob); const AnimationCurveNode *const anim = dynamic_cast<const AnimationCurveNode *>(ob);
if(!anim) { if (!anim) {
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element); DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode", &element);
continue; continue;
} }
if(target_prop_whitelist) { if (target_prop_whitelist) {
const char* s = anim->TargetProperty().c_str(); const char *s = anim->TargetProperty().c_str();
bool ok = false; bool ok = false;
for (size_t i = 0; i < whitelist_size; ++i) { for (size_t i = 0; i < whitelist_size; ++i) {
if (!strcmp(s, target_prop_whitelist[i])) { if (!strcmp(s, target_prop_whitelist[i])) {
@ -248,7 +235,7 @@ AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whi
break; break;
} }
} }
if(!ok) { if (!ok) {
continue; continue;
} }
} }
@ -259,34 +246,33 @@ AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whi
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc) AnimationStack::AnimationStack(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
: Object(id, element, name) Object(id, element, name) {
{ const Scope &sc = GetRequiredScope(element);
const Scope& sc = GetRequiredScope(element);
// note: we don't currently use any of these properties so we shouldn't bother if it is missing // note: we don't currently use any of these properties so we shouldn't bother if it is missing
props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true); props = GetPropertyTable(doc, "AnimationStack.FbxAnimStack", element, sc, true);
// resolve attached animation layers // resolve attached animation layers
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer"); const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationLayer");
layers.reserve(conns.size()); layers.reserve(conns.size());
for(const Connection* con : conns) { for (const Connection *con : conns) {
// link should not go to a property // link should not go to a property
if (con->PropertyName().length()) { if (con->PropertyName().length()) {
continue; continue;
} }
const Object* const ob = con->SourceObject(); const Object *const ob = con->SourceObject();
if(!ob) { if (!ob) {
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element); DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring", &element);
continue; continue;
} }
const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob); const AnimationLayer *const anim = dynamic_cast<const AnimationLayer *>(ob);
if(!anim) { if (!anim) {
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element); DOMWarning("source object for ->AnimationStack link is not an AnimationLayer", &element);
continue; continue;
} }
layers.push_back(anim); layers.push_back(anim);
@ -294,12 +280,11 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationStack::~AnimationStack() AnimationStack::~AnimationStack() {
{
// empty // empty
} }
} //!FBX } // namespace FBX
} //!Assimp } // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER #endif // ASSIMP_BUILD_NO_FBX_IMPORTER

View File

@ -804,11 +804,6 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]); aiMatrix4x4::Translation(-GeometricTranslation, chain[TransformationComp_GeometricTranslationInverse]);
} }
// is_complex needs to be consistent with NeedsComplexTransformationChain()
// or the interplay between this code and the animation converter would
// not be guaranteed.
//ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
// now, if we have more than just Translation, Scaling and Rotation, // now, if we have more than just Translation, Scaling and Rotation,
// we need to generate a full node chain to accommodate for assimp's // we need to generate a full node chain to accommodate for assimp's
// lack to express pivots and offsets. // lack to express pivots and offsets.
@ -1290,7 +1285,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
} }
if (binormals) { if (binormals) {
ai_assert(tangents.size() == vertices.size() && binormals->size() == vertices.size()); ai_assert(tangents.size() == vertices.size());
ai_assert(binormals->size() == vertices.size());
out_mesh->mTangents = new aiVector3D[vertices.size()]; out_mesh->mTangents = new aiVector3D[vertices.size()];
out_mesh->mBitangents = new aiVector3D[vertices.size()]; out_mesh->mBitangents = new aiVector3D[vertices.size()];
@ -2001,19 +1997,19 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
TrySetTextureProperties(out_mat, _textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
// Maya PBR // Maya PBR
TrySetTextureProperties(out_mat, _textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|baseColor", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|normalCamera", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
// Maya stingray // Maya stingray
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_normal_map", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_emissive_map", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_metallic_map", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map", aiTextureType_AMBIENT_OCCLUSION, mesh);
// 3DSMax PBR // 3DSMax PBR
TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh);
@ -3166,7 +3162,8 @@ FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList(const std::vector<c
} }
const AnimationCurve *const curve = kv.second; const AnimationCurve *const curve = kv.second;
ai_assert(curve->GetKeys().size() == curve->GetValues().size() && curve->GetKeys().size()); ai_assert(curve->GetKeys().size() == curve->GetValues().size());
ai_assert(curve->GetKeys().size());
//get values within the start/stop time window //get values within the start/stop time window
std::shared_ptr<KeyTimeList> Keys(new KeyTimeList()); std::shared_ptr<KeyTimeList> Keys(new KeyTimeList());

View File

@ -220,8 +220,8 @@ private:
* each output vertex the DOM index it maps to. * each output vertex the DOM index it maps to.
*/ */
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
aiNode *parent = NULL, unsigned int materialIndex = NO_MATERIAL_SEPARATION, aiNode *parent = nullptr, unsigned int materialIndex = NO_MATERIAL_SEPARATION,
std::vector<unsigned int> *outputVertStartIndices = NULL); std::vector<unsigned int> *outputVertStartIndices = nullptr);
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl, void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,

View File

@ -221,7 +221,7 @@ const Object* LazyObject::Get(bool dieOnError)
if(!DefaultLogger::isNullLogger()) { if(!DefaultLogger::isNullLogger()) {
ASSIMP_LOG_ERROR(ex.what()); ASSIMP_LOG_ERROR(ex.what());
} }
return NULL; return nullptr;
} }
if (!object.get()) { if (!object.get()) {
@ -467,7 +467,7 @@ void Document::ReadPropertyTemplates()
const Element *Properties70 = (*innerSc)["Properties70"]; const Element *Properties70 = (*innerSc)["Properties70"];
if(Properties70) { if(Properties70) {
std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>( std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>(
*Properties70,std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable*>(NULL)) *Properties70, std::shared_ptr<const PropertyTable>(static_cast<const PropertyTable *>(nullptr))
); );
templates[oname+"."+pname] = props; templates[oname+"."+pname] = props;

View File

@ -96,7 +96,7 @@ public:
template <typename T> template <typename T>
const T* Get(bool dieOnError = false) { const T* Get(bool dieOnError = false) {
const Object* const ob = Get(dieOnError); const Object* const ob = Get(dieOnError);
return ob ? dynamic_cast<const T*>(ob) : NULL; return ob ? dynamic_cast<const T *>(ob) : nullptr;
} }
uint64_t ID() const { uint64_t ID() const {
@ -213,7 +213,8 @@ private:
type name() const { \ type name() const { \
const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \ const int ival = PropertyGet<int>(Props(), fbx_stringize(name), static_cast<int>(default_value)); \
if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \ if (ival < 0 || ival >= AI_CONCAT(type, _MAX)) { \
ai_assert(static_cast<int>(default_value) >= 0 && static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \ ai_assert(static_cast<int>(default_value) >= 0); \
ai_assert(static_cast<int>(default_value) < AI_CONCAT(type, _MAX)); \
return static_cast<type>(default_value); \ return static_cast<type>(default_value); \
} \ } \
return static_cast<type>(ival); \ return static_cast<type>(ival); \
@ -744,7 +745,7 @@ public:
wants animations for. If the curve node does not match one of these, std::range_error wants animations for. If the curve node does not match one of these, std::range_error
will be thrown. */ will be thrown. */
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
const char* const * target_prop_whitelist = NULL, size_t whitelist_size = 0); const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
virtual ~AnimationCurveNode(); virtual ~AnimationCurveNode();
@ -756,7 +757,7 @@ public:
const AnimationCurveMap& Curves() const; const AnimationCurveMap& Curves() const;
/** Object the curve is assigned to, this can be NULL if the /** Object the curve is assigned to, this can be nullptr if the
* target object has no DOM representation or could not * target object has no DOM representation or could not
* be read for other reasons.*/ * be read for other reasons.*/
const Object* Target() const { const Object* Target() const {
@ -968,7 +969,7 @@ public:
// note: a connection ensures that the source and dest objects exist, but // note: a connection ensures that the source and dest objects exist, but
// not that they have DOM representations, so the return value of one of // not that they have DOM representations, so the return value of one of
// these functions can still be NULL. // these functions can still be nullptr.
const Object* SourceObject() const; const Object* SourceObject() const;
const Object* DestinationObject() const; const Object* DestinationObject() const;

View File

@ -65,7 +65,7 @@ void DOMError(const std::string& message, const Token& token)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DOMError(const std::string& message, const Element* element /*= NULL*/) void DOMError(const std::string& message, const Element* element /*= nullptr*/)
{ {
if(element) { if(element) {
DOMError(message,element->KeyToken()); DOMError(message,element->KeyToken());
@ -84,7 +84,7 @@ void DOMWarning(const std::string& message, const Token& token)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DOMWarning(const std::string& message, const Element* element /*= NULL*/) void DOMWarning(const std::string& message, const Element* element /*= nullptr*/)
{ {
if(element) { if(element) {
DOMWarning(message,element->KeyToken()); DOMWarning(message,element->KeyToken());
@ -106,7 +106,7 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
{ {
const Element* const Properties70 = sc["Properties70"]; const Element* const Properties70 = sc["Properties70"];
std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>( std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>(
static_cast<const PropertyTable*>(NULL)); static_cast<const PropertyTable *>(nullptr));
if(templateName.length()) { if(templateName.length()) {
PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName); PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName);

View File

@ -241,7 +241,7 @@ const MatIndexArray& MeshGeometry::GetMaterialIndices() const {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const { const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const {
if ( in_index >= m_mapping_counts.size() ) { if ( in_index >= m_mapping_counts.size() ) {
return NULL; return nullptr;
} }
ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() ); ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );

View File

@ -61,10 +61,10 @@ public:
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc ); Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
virtual ~Geometry(); virtual ~Geometry();
/** Get the Skin attached to this geometry or NULL */ /** Get the Skin attached to this geometry or nullptr */
const Skin* DeformerSkin() const; const Skin* DeformerSkin() const;
/** Get the BlendShape attached to this geometry or NULL */ /** Get the BlendShape attached to this geometry or nullptr */
const std::vector<const BlendShape*>& GetBlendShapes() const; const std::vector<const BlendShape*>& GetBlendShapes() const;
private: private:
@ -123,7 +123,7 @@ public:
/** Get per-face-vertex material assignments */ /** Get per-face-vertex material assignments */
const MatIndexArray& GetMaterialIndices() const; const MatIndexArray& GetMaterialIndices() const;
/** Convert from a fbx file vertex index (for example from a #Cluster weight) or NULL /** Convert from a fbx file vertex index (for example from a #Cluster weight) or nullptr
* if the vertex index is not valid. */ * if the vertex index is not valid. */
const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const; const unsigned int* ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const;

View File

@ -77,7 +77,7 @@ namespace {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ParseError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element) AI_WONT_RETURN void ParseError(const std::string& message, const Element* element)
{ {
if(element) { if(element) {
@ -181,7 +181,7 @@ Scope::Scope(Parser& parser,bool topLevel)
} }
TokenPtr n = parser.AdvanceToNextToken(); TokenPtr n = parser.AdvanceToNextToken();
if(n == NULL) { if (n == nullptr) {
ParseError("unexpected end of file"); ParseError("unexpected end of file");
} }
@ -196,7 +196,7 @@ Scope::Scope(Parser& parser,bool topLevel)
// Element() should stop at the next Key token (or right after a Close token) // Element() should stop at the next Key token (or right after a Close token)
n = parser.CurrentToken(); n = parser.CurrentToken();
if(n == NULL) { if (n == nullptr) {
if (topLevel) { if (topLevel) {
return; return;
} }
@ -236,7 +236,7 @@ TokenPtr Parser::AdvanceToNextToken()
{ {
last = current; last = current;
if (cursor == tokens.end()) { if (cursor == tokens.end()) {
current = NULL; current = nullptr;
} else { } else {
current = *cursor++; current = *cursor++;
} }
@ -258,7 +258,7 @@ TokenPtr Parser::LastToken() const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint64_t ParseTokenAsID(const Token& t, const char*& err_out) uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
{ {
err_out = NULL; err_out = nullptr;
if (t.Type() != TokenType_DATA) { if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token"; err_out = "expected TOK_DATA token";
@ -296,7 +296,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
size_t ParseTokenAsDim(const Token& t, const char*& err_out) size_t ParseTokenAsDim(const Token& t, const char*& err_out)
{ {
// same as ID parsing, except there is a trailing asterisk // same as ID parsing, except there is a trailing asterisk
err_out = NULL; err_out = nullptr;
if (t.Type() != TokenType_DATA) { if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token"; err_out = "expected TOK_DATA token";
@ -342,7 +342,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
float ParseTokenAsFloat(const Token& t, const char*& err_out) float ParseTokenAsFloat(const Token& t, const char*& err_out)
{ {
err_out = NULL; err_out = nullptr;
if (t.Type() != TokenType_DATA) { if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token"; err_out = "expected TOK_DATA token";
@ -385,7 +385,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int ParseTokenAsInt(const Token& t, const char*& err_out) int ParseTokenAsInt(const Token& t, const char*& err_out)
{ {
err_out = NULL; err_out = nullptr;
if (t.Type() != TokenType_DATA) { if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token"; err_out = "expected TOK_DATA token";
@ -421,7 +421,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out) int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
{ {
err_out = NULL; err_out = nullptr;
if (t.Type() != TokenType_DATA) { if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token"; err_out = "expected TOK_DATA token";
@ -458,7 +458,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string ParseTokenAsString(const Token& t, const char*& err_out) std::string ParseTokenAsString(const Token& t, const char*& err_out)
{ {
err_out = NULL; err_out = nullptr;
if (t.Type() != TokenType_DATA) { if (t.Type() != TokenType_DATA) {
err_out = "expected TOK_DATA token"; err_out = "expected TOK_DATA token";
@ -1211,7 +1211,7 @@ bool HasElement( const Scope& sc, const std::string& index ) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// extract a required element from a scope, abort if the element cannot be found // extract a required element from a scope, abort if the element cannot be found
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= NULL*/) const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= nullptr*/)
{ {
const Element* el = sc[index]; const Element* el = sc[index];
if(!el) { if(!el) {

View File

@ -137,7 +137,7 @@ public:
return element->second; return element->second;
} }
} }
return NULL; return nullptr;
} }
ElementCollection GetCollection(const std::string& index) const { ElementCollection GetCollection(const std::string& index) const {
@ -219,7 +219,7 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
bool HasElement( const Scope& sc, const std::string& index ); bool HasElement( const Scope& sc, const std::string& index );
// extract a required element from a scope, abort if the element cannot be found // extract a required element from a scope, abort if the element cannot be found
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL); const Element &GetRequiredElement(const Scope &sc, const std::string &index, const Element *element = nullptr);
// extract required compound scope // extract required compound scope
const Scope& GetRequiredScope(const Element& el); const Scope& GetRequiredScope(const Element& el);

View File

@ -70,7 +70,7 @@ Property::~Property()
namespace { namespace {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// read a typed property out of a FBX element. The return value is NULL if the property cannot be read. // read a typed property out of a FBX element. The return value is nullptr if the property cannot be read.
Property* ReadTypedProperty(const Element& element) Property* ReadTypedProperty(const Element& element)
{ {
ai_assert(element.KeyToken().StringContents() == "P"); ai_assert(element.KeyToken().StringContents() == "P");
@ -112,7 +112,7 @@ Property* ReadTypedProperty(const Element& element)
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) { else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4])); return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
} }
return NULL; return nullptr;
} }
@ -197,7 +197,7 @@ const Property* PropertyTable::Get(const std::string& name) const
return templateProps->Get(name); return templateProps->Get(name);
} }
return NULL; return nullptr;
} }
} }

View File

@ -110,7 +110,7 @@ public:
const Property* Get(const std::string& name) const; const Property* Get(const std::string& name) const;
// PropertyTable's need not be coupled with FBX elements so this can be NULL // PropertyTable's need not be coupled with FBX elements so this can be nullptr
const Element* GetElement() const { const Element* GetElement() const {
return element; return element;
} }

View File

@ -127,7 +127,7 @@ void ProcessDataToken( TokenList& output_tokens, const char*& start, const char*
TokenizeError("unexpected character, expected data token", line, column); TokenizeError("unexpected character, expected data token", line, column);
} }
start = end = NULL; start = end = nullptr;
} }
} }
@ -146,7 +146,7 @@ void Tokenize(TokenList& output_tokens, const char* input)
bool in_double_quotes = false; bool in_double_quotes = false;
bool pending_data_token = false; bool pending_data_token = false;
const char* token_begin = NULL, *token_end = NULL; const char *token_begin = nullptr, *token_end = nullptr;
for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) { for (const char* cur = input;*cur;column += (*cur == '\t' ? ASSIMP_FBX_TAB_WIDTH : 1), ++cur) {
const char c = *cur; const char c = *cur;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, 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,
@ -43,17 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the MDL importer class */ /** @file Implementation of the MDL importer class */
#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER #ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
// internal headers // internal headers
#include "AssetLib/HMP/HMPLoader.h" #include "AssetLib/HMP/HMPLoader.h"
#include "AssetLib/MD2/MD2FileData.h" #include "AssetLib/MD2/MD2FileData.h"
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory> #include <memory>
@ -74,24 +71,21 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
HMPImporter::HMPImporter() HMPImporter::HMPImporter() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
HMPImporter::~HMPImporter() HMPImporter::~HMPImporter() {
{
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// 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 HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const bool HMPImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const {
{
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if (extension == "hmp" ) if (extension == "hmp")
return true; return true;
// if check for extension is not enough, check for the magic tokens // if check for extension is not enough, check for the magic tokens
@ -100,167 +94,155 @@ bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4; tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4;
tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5; tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5;
tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7; tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7;
return CheckMagicToken(pIOHandler,pFile,tokens,3,0); return CheckMagicToken(pIOHandler, pFile, tokens, 3, 0);
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get list of all file extensions that are handled by this loader // Get list of all file extensions that are handled by this loader
const aiImporterDesc* HMPImporter::GetInfo () const const aiImporterDesc *HMPImporter::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 HMPImporter::InternReadFile( const std::string& pFile, void HMPImporter::InternReadFile(const std::string &pFile,
aiScene* _pScene, IOSystem* _pIOHandler) aiScene *_pScene, IOSystem *_pIOHandler) {
{ pScene = _pScene;
pScene = _pScene;
mIOHandler = _pIOHandler; mIOHandler = _pIOHandler;
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile)); std::unique_ptr<IOStream> file(mIOHandler->Open(pFile));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == nullptr) if (file.get() == nullptr) {
throw DeadlyImportError( "Failed to open HMP file " + pFile + "."); throw DeadlyImportError("Failed to open HMP file " + pFile + ".");
}
// Check whether the HMP file is large enough to contain // Check whether the HMP file is large enough to contain
// at least the file header // at least the file header
const size_t fileSize = file->FileSize(); const size_t fileSize = file->FileSize();
if( fileSize < 50) if (fileSize < 50)
throw DeadlyImportError( "HMP File is too small."); throw DeadlyImportError("HMP File is too small.");
// 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
mBuffer = new uint8_t[fileSize]; mBuffer = new uint8_t[fileSize];
file->Read( (void*)mBuffer, 1, fileSize); file->Read((void *)mBuffer, 1, fileSize);
iFileSize = (unsigned int)fileSize; iFileSize = (unsigned int)fileSize;
// Determine the file subtype and call the appropriate member function // Determine the file subtype and call the appropriate member function
const uint32_t iMagic = *((uint32_t*)this->mBuffer); const uint32_t iMagic = *((uint32_t *)this->mBuffer);
// HMP4 format // HMP4 format
if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic || if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_4 == iMagic) AI_HMP_MAGIC_NUMBER_BE_4 == iMagic) {
{
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A4, magic word is HMP4"); ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A4, magic word is HMP4");
InternReadFile_HMP4(); InternReadFile_HMP4();
} }
// HMP5 format // HMP5 format
else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic || else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_5 == iMagic) AI_HMP_MAGIC_NUMBER_BE_5 == iMagic) {
{
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A5, magic word is HMP5"); ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A5, magic word is HMP5");
InternReadFile_HMP5(); InternReadFile_HMP5();
} }
// HMP7 format // HMP7 format
else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic || else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
AI_HMP_MAGIC_NUMBER_BE_7 == iMagic) AI_HMP_MAGIC_NUMBER_BE_7 == iMagic) {
{
ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A7, magic word is HMP7"); ASSIMP_LOG_DEBUG("HMP subtype: 3D GameStudio A7, magic word is HMP7");
InternReadFile_HMP7(); InternReadFile_HMP7();
} } else {
else
{
// Print the magic word to the logger // Print the magic word to the logger
char szBuffer[5]; char szBuffer[5];
szBuffer[0] = ((char*)&iMagic)[0]; szBuffer[0] = ((char *)&iMagic)[0];
szBuffer[1] = ((char*)&iMagic)[1]; szBuffer[1] = ((char *)&iMagic)[1];
szBuffer[2] = ((char*)&iMagic)[2]; szBuffer[2] = ((char *)&iMagic)[2];
szBuffer[3] = ((char*)&iMagic)[3]; szBuffer[3] = ((char *)&iMagic)[3];
szBuffer[4] = '\0'; szBuffer[4] = '\0';
// We're definitely unable to load this file // We're definitely unable to load this file
throw DeadlyImportError( "Unknown HMP subformat " + pFile + throw DeadlyImportError("Unknown HMP subformat " + pFile +
". Magic word (" + szBuffer + ") is not known"); ". Magic word (" + szBuffer + ") is not known");
} }
// Set the AI_SCENE_FLAGS_TERRAIN bit // Set the AI_SCENE_FLAGS_TERRAIN bit
pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN; pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
delete[] mBuffer; delete[] mBuffer;
mBuffer= nullptr; mBuffer = nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::ValidateHeader_HMP457( ) void HMPImporter::ValidateHeader_HMP457() {
{ const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
if (120 > iFileSize) if (120 > iFileSize) {
{
throw DeadlyImportError("HMP file is too small (header size is " throw DeadlyImportError("HMP file is too small (header size is "
"120 bytes, this file is smaller)"); "120 bytes, this file is smaller)");
} }
if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y) if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y)
throw DeadlyImportError("Size of triangles in either x or y direction is zero"); throw DeadlyImportError("Size of triangles in either x or y direction is zero");
if(pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts/pcHeader->fnumverts_x) < 1.0f) if (pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts / pcHeader->fnumverts_x) < 1.0f)
throw DeadlyImportError("Number of triangles in either x or y direction is zero"); throw DeadlyImportError("Number of triangles in either x or y direction is zero");
if(!pcHeader->numframes) if (!pcHeader->numframes)
throw DeadlyImportError("There are no frames. At least one should be there"); throw DeadlyImportError("There are no frames. At least one should be there");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::InternReadFile_HMP4( ) void HMPImporter::InternReadFile_HMP4() {
{
throw DeadlyImportError("HMP4 is currently not supported"); throw DeadlyImportError("HMP4 is currently not supported");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::InternReadFile_HMP5( ) void HMPImporter::InternReadFile_HMP5() {
{
// read the file header and skip everything to byte 84 // read the file header and skip everything to byte 84
const HMP::Header_HMP5* pcHeader = (const HMP::Header_HMP5*)mBuffer; const HMP::Header_HMP5 *pcHeader = (const HMP::Header_HMP5 *)mBuffer;
const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84); const unsigned char *szCurrent = (const unsigned char *)(mBuffer + 84);
ValidateHeader_HMP457(); ValidateHeader_HMP457();
// generate an output mesh // generate an output mesh
pScene->mNumMeshes = 1; pScene->mNumMeshes = 1;
pScene->mMeshes = new aiMesh*[1]; pScene->mMeshes = new aiMesh *[1];
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh(); aiMesh *pcMesh = pScene->mMeshes[0] = new aiMesh();
pcMesh->mMaterialIndex = 0; pcMesh->mMaterialIndex = 0;
pcMesh->mVertices = new aiVector3D[pcHeader->numverts]; pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
pcMesh->mNormals = new aiVector3D[pcHeader->numverts]; pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x); const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
const unsigned int width = (unsigned int)pcHeader->fnumverts_x; const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
// generate/load a material for the terrain // generate/load a material for the terrain
CreateMaterial(szCurrent,&szCurrent); CreateMaterial(szCurrent, &szCurrent);
// goto offset 120, I don't know why ... // goto offset 120, I don't know why ...
// (fixme) is this the frame header? I assume yes since it starts with 2. // (fixme) is this the frame header? I assume yes since it starts with 2.
szCurrent += 36; szCurrent += 36;
SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width); SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7) * height * width);
// now load all vertices from the file // now load all vertices from the file
aiVector3D* pcVertOut = pcMesh->mVertices; aiVector3D *pcVertOut = pcMesh->mVertices;
aiVector3D* pcNorOut = pcMesh->mNormals; aiVector3D *pcNorOut = pcMesh->mNormals;
const HMP::Vertex_HMP5* src = (const HMP::Vertex_HMP5*) szCurrent; const HMP::Vertex_HMP5 *src = (const HMP::Vertex_HMP5 *)szCurrent;
for (unsigned int y = 0; y < height;++y) for (unsigned int y = 0; y < height; ++y) {
{ for (unsigned int x = 0; x < width; ++x) {
for (unsigned int x = 0; x < width;++x)
{
pcVertOut->x = x * pcHeader->ftrisize_x; pcVertOut->x = x * pcHeader->ftrisize_x;
pcVertOut->y = y * pcHeader->ftrisize_y; pcVertOut->y = y * pcHeader->ftrisize_y;
pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f; pcVertOut->z = (((float)src->z / 0xffff) - 0.5f) * pcHeader->ftrisize_x * 8.0f;
MD2::LookupNormalIndex(src->normals162index, *pcNorOut ); MD2::LookupNormalIndex(src->normals162index, *pcNorOut);
++pcVertOut;++pcNorOut;++src; ++pcVertOut;
++pcNorOut;
++src;
} }
} }
// generate texture coordinates if necessary // generate texture coordinates if necessary
if (pcHeader->numskins) if (pcHeader->numskins)
GenerateTextureCoords(width,height); GenerateTextureCoords(width, height);
// now build a list of faces // now build a list of faces
CreateOutputFaceList(width,height); CreateOutputFaceList(width, height);
// there is no nodegraph in HMP files. Simply assign the one mesh // there is no nodegraph in HMP files. Simply assign the one mesh
// (no, not the one ring) to the root node // (no, not the one ring) to the root node
@ -272,17 +254,16 @@ void HMPImporter::InternReadFile_HMP5( )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::InternReadFile_HMP7( ) void HMPImporter::InternReadFile_HMP7() {
{
// read the file header and skip everything to byte 84 // read the file header and skip everything to byte 84
const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer; const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84); const unsigned char *szCurrent = (const unsigned char *)(mBuffer + 84);
ValidateHeader_HMP457(); ValidateHeader_HMP457();
// generate an output mesh // generate an output mesh
pScene->mNumMeshes = 1; pScene->mNumMeshes = 1;
pScene->mMeshes = new aiMesh*[1]; pScene->mMeshes = new aiMesh *[1];
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh(); aiMesh *pcMesh = pScene->mMeshes[0] = new aiMesh();
pcMesh->mMaterialIndex = 0; pcMesh->mMaterialIndex = 0;
pcMesh->mVertices = new aiVector3D[pcHeader->numverts]; pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
@ -292,44 +273,44 @@ void HMPImporter::InternReadFile_HMP7( )
const unsigned int width = (unsigned int)pcHeader->fnumverts_x; const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
// generate/load a material for the terrain // generate/load a material for the terrain
CreateMaterial(szCurrent,&szCurrent); CreateMaterial(szCurrent, &szCurrent);
// goto offset 120, I don't know why ... // goto offset 120, I don't know why ...
// (fixme) is this the frame header? I assume yes since it starts with 2. // (fixme) is this the frame header? I assume yes since it starts with 2.
szCurrent += 36; szCurrent += 36;
SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width); SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7) * height * width);
// now load all vertices from the file // now load all vertices from the file
aiVector3D* pcVertOut = pcMesh->mVertices; aiVector3D *pcVertOut = pcMesh->mVertices;
aiVector3D* pcNorOut = pcMesh->mNormals; aiVector3D *pcNorOut = pcMesh->mNormals;
const HMP::Vertex_HMP7* src = (const HMP::Vertex_HMP7*) szCurrent; const HMP::Vertex_HMP7 *src = (const HMP::Vertex_HMP7 *)szCurrent;
for (unsigned int y = 0; y < height;++y) for (unsigned int y = 0; y < height; ++y) {
{ for (unsigned int x = 0; x < width; ++x) {
for (unsigned int x = 0; x < width;++x)
{
pcVertOut->x = x * pcHeader->ftrisize_x; pcVertOut->x = x * pcHeader->ftrisize_x;
pcVertOut->y = y * pcHeader->ftrisize_y; pcVertOut->y = y * pcHeader->ftrisize_y;
// FIXME: What exctly is the correct scaling factor to use? // FIXME: What exctly is the correct scaling factor to use?
// possibly pcHeader->scale_origin[2] in combination with a // possibly pcHeader->scale_origin[2] in combination with a
// signed interpretation of src->z? // signed interpretation of src->z?
pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f; pcVertOut->z = (((float)src->z / 0xffff) - 0.5f) * pcHeader->ftrisize_x * 8.0f;
pcNorOut->x = ((float)src->normal_x / 0x80 ); // * pcHeader->scale_origin[0]; pcNorOut->x = ((float)src->normal_x / 0x80); // * pcHeader->scale_origin[0];
pcNorOut->y = ((float)src->normal_y / 0x80 ); // * pcHeader->scale_origin[1]; pcNorOut->y = ((float)src->normal_y / 0x80); // * pcHeader->scale_origin[1];
pcNorOut->z = 1.0f; pcNorOut->z = 1.0f;
pcNorOut->Normalize(); pcNorOut->Normalize();
++pcVertOut;++pcNorOut;++src; ++pcVertOut;
++pcNorOut;
++src;
} }
} }
// generate texture coordinates if necessary // generate texture coordinates if necessary
if (pcHeader->numskins)GenerateTextureCoords(width,height); if (pcHeader->numskins) GenerateTextureCoords(width, height);
// now build a list of faces // now build a list of faces
CreateOutputFaceList(width,height); CreateOutputFaceList(width, height);
// there is no nodegraph in HMP files. Simply assign the one mesh // there is no nodegraph in HMP files. Simply assign the one mesh
// (no, not the One Ring) to the root node // (no, not the One Ring) to the root node
@ -341,96 +322,89 @@ void HMPImporter::InternReadFile_HMP7( )
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::CreateMaterial(const unsigned char* szCurrent, void HMPImporter::CreateMaterial(const unsigned char *szCurrent,
const unsigned char** szCurrentOut) const unsigned char **szCurrentOut) {
{ aiMesh *const pcMesh = pScene->mMeshes[0];
aiMesh* const pcMesh = pScene->mMeshes[0]; const HMP::Header_HMP5 *const pcHeader = (const HMP::Header_HMP5 *)mBuffer;
const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
// we don't need to generate texture coordinates if // we don't need to generate texture coordinates if
// we have no textures in the file ... // we have no textures in the file ...
if (pcHeader->numskins) if (pcHeader->numskins) {
{
pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts]; pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
pcMesh->mNumUVComponents[0] = 2; pcMesh->mNumUVComponents[0] = 2;
// now read the first skin and skip all others // now read the first skin and skip all others
ReadFirstSkin(pcHeader->numskins,szCurrent,&szCurrent); ReadFirstSkin(pcHeader->numskins, szCurrent, &szCurrent);
} } else {
else
{
// generate a default material // generate a default material
const int iMode = (int)aiShadingMode_Gouraud; const int iMode = (int)aiShadingMode_Gouraud;
aiMaterial* pcHelper = new aiMaterial(); aiMaterial *pcHelper = new aiMaterial();
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL); pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
aiColor3D clr; aiColor3D clr;
clr.b = clr.g = clr.r = 0.6f; clr.b = clr.g = clr.r = 0.6f;
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE); pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR); pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
clr.b = clr.g = clr.r = 0.05f; clr.b = clr.g = clr.r = 0.05f;
pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT); pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
aiString szName; aiString szName;
szName.Set(AI_DEFAULT_MATERIAL_NAME); szName.Set(AI_DEFAULT_MATERIAL_NAME);
pcHelper->AddProperty(&szName,AI_MATKEY_NAME); pcHelper->AddProperty(&szName, AI_MATKEY_NAME);
// add the material to the scene // add the material to the scene
pScene->mNumMaterials = 1; pScene->mNumMaterials = 1;
pScene->mMaterials = new aiMaterial*[1]; pScene->mMaterials = new aiMaterial *[1];
pScene->mMaterials[0] = pcHelper; pScene->mMaterials[0] = pcHelper;
} }
*szCurrentOut = szCurrent; *szCurrentOut = szCurrent;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height) void HMPImporter::CreateOutputFaceList(unsigned int width, unsigned int height) {
{ aiMesh *const pcMesh = this->pScene->mMeshes[0];
aiMesh* const pcMesh = this->pScene->mMeshes[0];
// Allocate enough storage // Allocate enough storage
pcMesh->mNumFaces = (width-1) * (height-1); pcMesh->mNumFaces = (width - 1) * (height - 1);
pcMesh->mFaces = new aiFace[pcMesh->mNumFaces]; pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
pcMesh->mNumVertices = pcMesh->mNumFaces*4; pcMesh->mNumVertices = pcMesh->mNumFaces * 4;
aiVector3D* pcVertices = new aiVector3D[pcMesh->mNumVertices]; aiVector3D *pcVertices = new aiVector3D[pcMesh->mNumVertices];
aiVector3D* pcNormals = new aiVector3D[pcMesh->mNumVertices]; aiVector3D *pcNormals = new aiVector3D[pcMesh->mNumVertices];
aiFace* pcFaceOut(pcMesh->mFaces); aiFace *pcFaceOut(pcMesh->mFaces);
aiVector3D* pcVertOut = pcVertices; aiVector3D *pcVertOut = pcVertices;
aiVector3D* pcNorOut = pcNormals; aiVector3D *pcNorOut = pcNormals;
aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL; aiVector3D *pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : nullptr;
aiVector3D* pcUVOut(pcUVs); aiVector3D *pcUVOut(pcUVs);
// Build the terrain square // Build the terrain square
unsigned int iCurrent = 0; unsigned int iCurrent = 0;
for (unsigned int y = 0; y < height-1;++y) { for (unsigned int y = 0; y < height - 1; ++y) {
for (unsigned int x = 0; x < width-1;++x,++pcFaceOut) { for (unsigned int x = 0; x < width - 1; ++x, ++pcFaceOut) {
pcFaceOut->mNumIndices = 4; pcFaceOut->mNumIndices = 4;
pcFaceOut->mIndices = new unsigned int[4]; pcFaceOut->mIndices = new unsigned int[4];
*pcVertOut++ = pcMesh->mVertices[y*width+x]; *pcVertOut++ = pcMesh->mVertices[y * width + x];
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x]; *pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x];
*pcVertOut++ = pcMesh->mVertices[(y+1)*width+x+1]; *pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x + 1];
*pcVertOut++ = pcMesh->mVertices[y*width+x+1]; *pcVertOut++ = pcMesh->mVertices[y * width + x + 1];
*pcNorOut++ = pcMesh->mNormals[y * width + x];
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x];
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x + 1];
*pcNorOut++ = pcMesh->mNormals[y * width + x + 1];
*pcNorOut++ = pcMesh->mNormals[y*width+x]; if (pcMesh->mTextureCoords[0]) {
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x]; *pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x];
*pcNorOut++ = pcMesh->mNormals[(y+1)*width+x+1]; *pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x];
*pcNorOut++ = pcMesh->mNormals[y*width+x+1]; *pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x + 1];
*pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x + 1];
if (pcMesh->mTextureCoords[0])
{
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x];
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
*pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x+1];
*pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
} }
for (unsigned int i = 0; i < 4;++i) for (unsigned int i = 0; i < 4; ++i)
pcFaceOut->mIndices[i] = iCurrent++; pcFaceOut->mIndices[i] = iCurrent++;
} }
} }
@ -440,58 +414,58 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
delete[] pcMesh->mNormals; delete[] pcMesh->mNormals;
pcMesh->mNormals = pcNormals; pcMesh->mNormals = pcNormals;
if (pcMesh->mTextureCoords[0]) if (pcMesh->mTextureCoords[0]) {
{
delete[] pcMesh->mTextureCoords[0]; delete[] pcMesh->mTextureCoords[0];
pcMesh->mTextureCoords[0] = pcUVs; pcMesh->mTextureCoords[0] = pcUVs;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor, void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char *szCursor,
const unsigned char** szCursorOut) const unsigned char **szCursorOut) {
{ ai_assert(0 != iNumSkins);
ai_assert( 0 != iNumSkins ); ai_assert(nullptr != szCursor);
ai_assert( nullptr != szCursor);
// read the type of the skin ... // read the type of the skin ...
// sometimes we need to skip 12 bytes here, I don't know why ... // sometimes we need to skip 12 bytes here, I don't know why ...
uint32_t iType = *((uint32_t*)szCursor); uint32_t iType = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t); szCursor += sizeof(uint32_t);
if (0 == iType) if (0 == iType) {
{
szCursor += sizeof(uint32_t) * 2; szCursor += sizeof(uint32_t) * 2;
iType = *((uint32_t*)szCursor); iType = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t); szCursor += sizeof(uint32_t);
if (!iType) if (!iType)
throw DeadlyImportError("Unable to read HMP7 skin chunk"); throw DeadlyImportError("Unable to read HMP7 skin chunk");
} }
// read width and height // read width and height
uint32_t iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t); uint32_t iWidth = *((uint32_t *)szCursor);
uint32_t iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t); szCursor += sizeof(uint32_t);
uint32_t iHeight = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
// allocate an output material // allocate an output material
aiMaterial* pcMat = new aiMaterial(); aiMaterial *pcMat = new aiMaterial();
// read the skin, this works exactly as for MDL7 // read the skin, this works exactly as for MDL7
ParseSkinLump_3DGS_MDL7(szCursor,&szCursor, ParseSkinLump_3DGS_MDL7(szCursor, &szCursor,
pcMat,iType,iWidth,iHeight); pcMat, iType, iWidth, iHeight);
// now we need to skip any other skins ... // now we need to skip any other skins ...
for (unsigned int i = 1; i< iNumSkins;++i) for (unsigned int i = 1; i < iNumSkins; ++i) {
{ iType = *((uint32_t *)szCursor);
iType = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t); szCursor += sizeof(uint32_t);
iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t); iWidth = *((uint32_t *)szCursor);
iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t); szCursor += sizeof(uint32_t);
iHeight = *((uint32_t *)szCursor);
szCursor += sizeof(uint32_t);
SkipSkinLump_3DGS_MDL7(szCursor,&szCursor,iType,iWidth,iHeight); SkipSkinLump_3DGS_MDL7(szCursor, &szCursor, iType, iWidth, iHeight);
SizeCheck(szCursor); SizeCheck(szCursor);
} }
// setup the material ... // setup the material ...
pScene->mNumMaterials = 1; pScene->mNumMaterials = 1;
pScene->mMaterials = new aiMaterial*[1]; pScene->mMaterials = new aiMaterial *[1];
pScene->mMaterials[0] = pcMat; pScene->mMaterials[0] = pcMat;
*szCursorOut = szCursor; *szCursorOut = szCursor;
@ -500,20 +474,20 @@ void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szC
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Generate proepr texture coords // Generate proepr texture coords
void HMPImporter::GenerateTextureCoords( void HMPImporter::GenerateTextureCoords(
const unsigned int width, const unsigned int height) const unsigned int width, const unsigned int height) {
{ ai_assert(nullptr != pScene->mMeshes);
ai_assert(NULL != pScene->mMeshes && NULL != pScene->mMeshes[0] && ai_assert(nullptr != pScene->mMeshes[0]);
NULL != pScene->mMeshes[0]->mTextureCoords[0]); ai_assert(nullptr != pScene->mMeshes[0]->mTextureCoords[0]);
aiVector3D* uv = pScene->mMeshes[0]->mTextureCoords[0]; aiVector3D *uv = pScene->mMeshes[0]->mTextureCoords[0];
const float fY = (1.0f / height) + (1.0f / height) / (height-1); const float fY = (1.0f / height) + (1.0f / height) / (height - 1);
const float fX = (1.0f / width) + (1.0f / width) / (width-1); const float fX = (1.0f / width) + (1.0f / width) / (width - 1);
for (unsigned int y = 0; y < height;++y) { for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width;++x,++uv) { for (unsigned int x = 0; x < width; ++x, ++uv) {
uv->y = fY*y; uv->y = fY * y;
uv->x = fX*x; uv->x = fX * x;
uv->z = 0.0f; uv->z = 0.0f;
} }
} }

View File

@ -131,7 +131,7 @@ void WritePolygon(std::vector<IfcVector3> &resultpoly, TempMesh &result) {
void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs, TempMesh &result, void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs, TempMesh &result,
const TempMesh &first_operand, const TempMesh &first_operand,
ConversionData & /*conv*/) { ConversionData & /*conv*/) {
ai_assert(hs != NULL); ai_assert(hs != nullptr);
const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>(); const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>();
if (!plane) { if (!plane) {
@ -366,7 +366,7 @@ bool PointInPoly(const IfcVector3 &p, const std::vector<IfcVector3> &boundary) {
void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPolygonalBoundedHalfSpace *hs, TempMesh &result, void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPolygonalBoundedHalfSpace *hs, TempMesh &result,
const TempMesh &first_operand, const TempMesh &first_operand,
ConversionData &conv) { ConversionData &conv) {
ai_assert(hs != NULL); ai_assert(hs != nullptr);
const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>(); const Schema_2x3::IfcPlane *const plane = hs->BaseSurface->ToPtr<Schema_2x3::IfcPlane>();
if (!plane) { if (!plane) {
@ -665,7 +665,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, TempMesh &result, void ProcessBooleanExtrudedAreaSolidDifference(const Schema_2x3::IfcExtrudedAreaSolid *as, TempMesh &result,
const TempMesh &first_operand, const TempMesh &first_operand,
ConversionData &conv) { ConversionData &conv) {
ai_assert(as != NULL); ai_assert(as != nullptr);
// This case is handled by reduction to an instance of the quadrify() algorithm. // This case is handled by reduction to an instance of the quadrify() algorithm.
// Obviously, this won't work for arbitrarily complex cases. In fact, the first // Obviously, this won't work for arbitrarily complex cases. In fact, the first

View File

@ -389,7 +389,8 @@ public:
// -------------------------------------------------- // --------------------------------------------------
void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const { void SampleDiscrete(TempMesh& out,IfcFloat a,IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a));
ai_assert(InRange(b));
return base->SampleDiscrete(out,TrimParam(a),TrimParam(b)); return base->SampleDiscrete(out,TrimParam(a),TrimParam(b));
} }
@ -446,7 +447,8 @@ public:
// -------------------------------------------------- // --------------------------------------------------
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const { size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
ai_assert(InRange(a) && InRange(b)); ai_assert(InRange(a));
ai_assert(InRange(b));
return static_cast<size_t>( std::ceil(b) - std::floor(a) ); return static_cast<size_t>( std::ceil(b) - std::floor(a) );
} }
@ -489,7 +491,7 @@ Curve* Curve::Convert(const IFC::Schema_2x3::IfcCurve& curve,ConversionData& con
} }
// XXX OffsetCurve2D, OffsetCurve3D not currently supported // XXX OffsetCurve2D, OffsetCurve3D not currently supported
return NULL; return nullptr;
} }
#ifdef ASSIMP_BUILD_DEBUG #ifdef ASSIMP_BUILD_DEBUG

View File

@ -174,7 +174,7 @@ void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t m
TempOpening& opening = fake_openings.back(); TempOpening& opening = fake_openings.back();
opening.extrusionDir = master_normal; opening.extrusionDir = master_normal;
opening.solid = NULL; opening.solid = nullptr;
opening.profileMesh = std::make_shared<TempMesh>(); opening.profileMesh = std::make_shared<TempMesh>();
opening.profileMesh->mVerts.reserve(*iit); opening.profileMesh->mVerts.reserve(*iit);

View File

@ -172,7 +172,7 @@ void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
if (GetExtension(pFile) == "ifczip") { if (GetExtension(pFile) == "ifczip") {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC #ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
unzFile zip = unzOpen(pFile.c_str()); unzFile zip = unzOpen(pFile.c_str());
if (zip == NULL) { if (zip == nullptr) {
ThrowException("Could not open ifczip file for reading, unzip failed"); ThrowException("Could not open ifczip file for reading, unzip failed");
} }
@ -373,7 +373,7 @@ void SetUnits(ConversionData &conv) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SetCoordinateSpace(ConversionData &conv) { void SetCoordinateSpace(ConversionData &conv) {
const Schema_2x3::IfcRepresentationContext *fav = NULL; const Schema_2x3::IfcRepresentationContext *fav = nullptr;
for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) { for (const Schema_2x3::IfcRepresentationContext &v : conv.proj.RepresentationContexts) {
fav = &v; fav = &v;
// Model should be the most suitable type of context, hence ignore the others // Model should be the most suitable type of context, hence ignore the others
@ -790,7 +790,7 @@ aiNode *ProcessSpatialStructure(aiNode *parent, const Schema_2x3::IfcProduct &el
for (const Schema_2x3::IfcObjectDefinition &def : aggr->RelatedObjects) { for (const Schema_2x3::IfcObjectDefinition &def : aggr->RelatedObjects) {
if (const Schema_2x3::IfcProduct *const prod = def.ToPtr<Schema_2x3::IfcProduct>()) { if (const Schema_2x3::IfcProduct *const prod = def.ToPtr<Schema_2x3::IfcProduct>()) {
aiNode *const ndnew = ProcessSpatialStructure(nd_aggr.get(), *prod, conv, NULL); aiNode *const ndnew = ProcessSpatialStructure(nd_aggr.get(), *prod, conv, nullptr);
if (ndnew) { if (ndnew) {
nd_aggr->mChildren[nd_aggr->mNumChildren++] = ndnew; nd_aggr->mChildren[nd_aggr->mNumChildren++] = ndnew;
} }
@ -870,7 +870,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
if (def.GetID() == prod->GetID()) { if (def.GetID() == prod->GetID()) {
IFCImporter::LogVerboseDebug("selecting this spatial structure as root structure"); IFCImporter::LogVerboseDebug("selecting this spatial structure as root structure");
// got it, this is one primary site. // got it, this is one primary site.
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL)); nodes.push_back(ProcessSpatialStructure(nullptr, *prod, conv, nullptr));
} }
} }
} }
@ -887,7 +887,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
continue; continue;
} }
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL)); nodes.push_back(ProcessSpatialStructure(nullptr, *prod, conv, nullptr));
} }
nb_nodes = nodes.size(); nb_nodes = nodes.size();
@ -897,7 +897,7 @@ void ProcessSpatialStructures(ConversionData &conv) {
conv.out->mRootNode = nodes[0]; conv.out->mRootNode = nodes[0];
} else if (nb_nodes > 1) { } else if (nb_nodes > 1) {
conv.out->mRootNode = new aiNode("Root"); conv.out->mRootNode = new aiNode("Root");
conv.out->mRootNode->mParent = NULL; conv.out->mRootNode->mParent = nullptr;
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes); conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
conv.out->mRootNode->mChildren = new aiNode *[conv.out->mRootNode->mNumChildren]; conv.out->mRootNode->mChildren = new aiNode *[conv.out->mRootNode->mNumChildren];

View File

@ -54,333 +54,333 @@ namespace {
typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry; typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry;
static const SchemaEntry schema_raw_2x3[] = { static const SchemaEntry schema_raw_2x3[] = {
SchemaEntry("ifcstairtypeenum",NULL ) SchemaEntry("ifcstairtypeenum",nullptr )
, SchemaEntry("ifcspacetypeenum",NULL ) , SchemaEntry("ifcspacetypeenum",nullptr )
, SchemaEntry("ifcwalltypeenum",NULL ) , SchemaEntry("ifcwalltypeenum",nullptr )
, SchemaEntry("ifcmonthinyearnumber",NULL ) , SchemaEntry("ifcmonthinyearnumber",nullptr )
, SchemaEntry("ifcheatfluxdensitymeasure",NULL ) , SchemaEntry("ifcheatfluxdensitymeasure",nullptr )
, SchemaEntry("ifckinematicviscositymeasure",NULL ) , SchemaEntry("ifckinematicviscositymeasure",nullptr )
, SchemaEntry("ifcsequenceenum",NULL ) , SchemaEntry("ifcsequenceenum",nullptr )
, SchemaEntry("ifcairtoairheatrecoverytypeenum",NULL ) , SchemaEntry("ifcairtoairheatrecoverytypeenum",nullptr )
, SchemaEntry("ifcactorselect",NULL ) , SchemaEntry("ifcactorselect",nullptr )
, SchemaEntry("ifctransformertypeenum",NULL ) , SchemaEntry("ifctransformertypeenum",nullptr )
, SchemaEntry("ifcunitaryequipmenttypeenum",NULL ) , SchemaEntry("ifcunitaryequipmenttypeenum",nullptr )
, SchemaEntry("ifcelectricflowstoragedevicetypeenum",NULL ) , SchemaEntry("ifcelectricflowstoragedevicetypeenum",nullptr )
, SchemaEntry("ifcenergysequenceenum",NULL ) , SchemaEntry("ifcenergysequenceenum",nullptr )
, SchemaEntry("ifcworkcontroltypeenum",NULL ) , SchemaEntry("ifcworkcontroltypeenum",nullptr )
, SchemaEntry("ifccurvaturemeasure",NULL ) , SchemaEntry("ifccurvaturemeasure",nullptr )
, SchemaEntry("ifcparametervalue",NULL ) , SchemaEntry("ifcparametervalue",nullptr )
, SchemaEntry("ifcappliedvalueselect",NULL ) , SchemaEntry("ifcappliedvalueselect",nullptr )
, SchemaEntry("ifcwarpingconstantmeasure",NULL ) , SchemaEntry("ifcwarpingconstantmeasure",nullptr )
, SchemaEntry("ifcarithmeticoperatorenum",NULL ) , SchemaEntry("ifcarithmeticoperatorenum",nullptr )
, SchemaEntry("ifclinearforcemeasure",NULL ) , SchemaEntry("ifclinearforcemeasure",nullptr )
, SchemaEntry("ifcwindowpanelpositionenum",NULL ) , SchemaEntry("ifcwindowpanelpositionenum",nullptr )
, SchemaEntry("ifcflowmetertypeenum",NULL ) , SchemaEntry("ifcflowmetertypeenum",nullptr )
, SchemaEntry("ifcrampflighttypeenum",NULL ) , SchemaEntry("ifcrampflighttypeenum",nullptr )
, SchemaEntry("ifcspecularhighlightselect",NULL ) , SchemaEntry("ifcspecularhighlightselect",nullptr )
, SchemaEntry("ifcactiontypeenum",NULL ) , SchemaEntry("ifcactiontypeenum",nullptr )
, SchemaEntry("ifcgeometricprojectionenum",NULL ) , SchemaEntry("ifcgeometricprojectionenum",nullptr )
, SchemaEntry("ifctimeseriesdatatypeenum",NULL ) , SchemaEntry("ifctimeseriesdatatypeenum",nullptr )
, SchemaEntry("ifcmagneticfluxmeasure",NULL ) , SchemaEntry("ifcmagneticfluxmeasure",nullptr )
, SchemaEntry("ifcobjecttypeenum",NULL ) , SchemaEntry("ifcobjecttypeenum",nullptr )
, SchemaEntry("ifcdataoriginenum",NULL ) , SchemaEntry("ifcdataoriginenum",nullptr )
, SchemaEntry("ifcmassdensitymeasure",NULL ) , SchemaEntry("ifcmassdensitymeasure",nullptr )
, SchemaEntry("ifclightfixturetypeenum",NULL ) , SchemaEntry("ifclightfixturetypeenum",nullptr )
, SchemaEntry("ifcservicelifetypeenum",NULL ) , SchemaEntry("ifcservicelifetypeenum",nullptr )
, SchemaEntry("ifcelectricvoltagemeasure",NULL ) , SchemaEntry("ifcelectricvoltagemeasure",nullptr )
, SchemaEntry("ifcheatingvaluemeasure",NULL ) , SchemaEntry("ifcheatingvaluemeasure",nullptr )
, SchemaEntry("ifcpresentabletext",NULL ) , SchemaEntry("ifcpresentabletext",nullptr )
, SchemaEntry("ifcaheadorbehind",NULL ) , SchemaEntry("ifcaheadorbehind",nullptr )
, SchemaEntry("ifcsimplevalue",NULL ) , SchemaEntry("ifcsimplevalue",nullptr )
, SchemaEntry("ifcsensortypeenum",NULL ) , SchemaEntry("ifcsensortypeenum",nullptr )
, SchemaEntry("ifcderivedunitenum",NULL ) , SchemaEntry("ifcderivedunitenum",nullptr )
, SchemaEntry("ifcsizeselect",NULL ) , SchemaEntry("ifcsizeselect",nullptr )
, SchemaEntry("ifctransportelementtypeenum",NULL ) , SchemaEntry("ifctransportelementtypeenum",nullptr )
, SchemaEntry("ifcinventorytypeenum",NULL ) , SchemaEntry("ifcinventorytypeenum",nullptr )
, SchemaEntry("ifctextdecoration",NULL ) , SchemaEntry("ifctextdecoration",nullptr )
, SchemaEntry("ifcdirectionsenseenum",NULL ) , SchemaEntry("ifcdirectionsenseenum",nullptr )
, SchemaEntry("ifcductfittingtypeenum",NULL ) , SchemaEntry("ifcductfittingtypeenum",nullptr )
, SchemaEntry("ifcdocumentstatusenum",NULL ) , SchemaEntry("ifcdocumentstatusenum",nullptr )
, SchemaEntry("ifcslabtypeenum",NULL ) , SchemaEntry("ifcslabtypeenum",nullptr )
, SchemaEntry("ifcdoorstyleconstructionenum",NULL ) , SchemaEntry("ifcdoorstyleconstructionenum",nullptr )
, SchemaEntry("ifcvolumemeasure",NULL ) , SchemaEntry("ifcvolumemeasure",nullptr )
, SchemaEntry("ifcinductancemeasure",NULL ) , SchemaEntry("ifcinductancemeasure",nullptr )
, SchemaEntry("ifccurtainwalltypeenum",NULL ) , SchemaEntry("ifccurtainwalltypeenum",nullptr )
, SchemaEntry("ifcsiunitname",NULL ) , SchemaEntry("ifcsiunitname",nullptr )
, SchemaEntry("ifcspecularexponent",NULL ) , SchemaEntry("ifcspecularexponent",nullptr )
, SchemaEntry("ifcsoundpressuremeasure",NULL ) , SchemaEntry("ifcsoundpressuremeasure",nullptr )
, SchemaEntry("ifcanalysistheorytypeenum",NULL ) , SchemaEntry("ifcanalysistheorytypeenum",nullptr )
, SchemaEntry("ifcgasterminaltypeenum",NULL ) , SchemaEntry("ifcgasterminaltypeenum",nullptr )
, SchemaEntry("ifcyearnumber",NULL ) , SchemaEntry("ifcyearnumber",nullptr )
, SchemaEntry("ifcmodulusofelasticitymeasure",NULL ) , SchemaEntry("ifcmodulusofelasticitymeasure",nullptr )
, SchemaEntry("ifcchangeactionenum",NULL ) , SchemaEntry("ifcchangeactionenum",nullptr )
, SchemaEntry("ifcdampertypeenum",NULL ) , SchemaEntry("ifcdampertypeenum",nullptr )
, SchemaEntry("ifcevaporatortypeenum",NULL ) , SchemaEntry("ifcevaporatortypeenum",nullptr )
, SchemaEntry("ifcionconcentrationmeasure",NULL ) , SchemaEntry("ifcionconcentrationmeasure",nullptr )
, SchemaEntry("ifcductsegmenttypeenum",NULL ) , SchemaEntry("ifcductsegmenttypeenum",nullptr )
, SchemaEntry("ifcprotectivedevicetypeenum",NULL ) , SchemaEntry("ifcprotectivedevicetypeenum",nullptr )
, SchemaEntry("ifcabsorbeddosemeasure",NULL ) , SchemaEntry("ifcabsorbeddosemeasure",nullptr )
, SchemaEntry("ifcmassperlengthmeasure",NULL ) , SchemaEntry("ifcmassperlengthmeasure",nullptr )
, SchemaEntry("ifctextfontname",NULL ) , SchemaEntry("ifctextfontname",nullptr )
, SchemaEntry("ifcorientationselect",NULL ) , SchemaEntry("ifcorientationselect",nullptr )
, SchemaEntry("ifcilluminancemeasure",NULL ) , SchemaEntry("ifcilluminancemeasure",nullptr )
, SchemaEntry("ifcfiresuppressionterminaltypeenum",NULL ) , SchemaEntry("ifcfiresuppressionterminaltypeenum",nullptr )
, SchemaEntry("ifcfontstyle",NULL ) , SchemaEntry("ifcfontstyle",nullptr )
, SchemaEntry("ifcmomentofinertiameasure",NULL ) , SchemaEntry("ifcmomentofinertiameasure",nullptr )
, SchemaEntry("ifcmodulusofsubgradereactionmeasure",NULL ) , SchemaEntry("ifcmodulusofsubgradereactionmeasure",nullptr )
, SchemaEntry("ifccomplexnumber",NULL ) , SchemaEntry("ifccomplexnumber",nullptr )
, SchemaEntry("ifchumidifiertypeenum",NULL ) , SchemaEntry("ifchumidifiertypeenum",nullptr )
, SchemaEntry("ifcpresentationstyleselect",NULL ) , SchemaEntry("ifcpresentationstyleselect",nullptr )
, SchemaEntry("ifcthermaltransmittancemeasure",NULL ) , SchemaEntry("ifcthermaltransmittancemeasure",nullptr )
, SchemaEntry("ifcribplatedirectionenum",NULL ) , SchemaEntry("ifcribplatedirectionenum",nullptr )
, SchemaEntry("ifcclassificationnotationselect",NULL ) , SchemaEntry("ifcclassificationnotationselect",nullptr )
, SchemaEntry("ifcminuteinhour",NULL ) , SchemaEntry("ifcminuteinhour",nullptr )
, SchemaEntry("ifcinternalorexternalenum",NULL ) , SchemaEntry("ifcinternalorexternalenum",nullptr )
, SchemaEntry("ifcrotationalfrequencymeasure",NULL ) , SchemaEntry("ifcrotationalfrequencymeasure",nullptr )
, SchemaEntry("ifcsanitaryterminaltypeenum",NULL ) , SchemaEntry("ifcsanitaryterminaltypeenum",nullptr )
, SchemaEntry("ifcsymbolstyleselect",NULL ) , SchemaEntry("ifcsymbolstyleselect",nullptr )
, SchemaEntry("ifcelementcompositionenum",NULL ) , SchemaEntry("ifcelementcompositionenum",nullptr )
, SchemaEntry("ifctextpath",NULL ) , SchemaEntry("ifctextpath",nullptr )
, SchemaEntry("ifcpowermeasure",NULL ) , SchemaEntry("ifcpowermeasure",nullptr )
, SchemaEntry("ifcsurfacestyleelementselect",NULL ) , SchemaEntry("ifcsurfacestyleelementselect",nullptr )
, SchemaEntry("ifcresourceconsumptionenum",NULL ) , SchemaEntry("ifcresourceconsumptionenum",nullptr )
, SchemaEntry("ifcelectriccapacitancemeasure",NULL ) , SchemaEntry("ifcelectriccapacitancemeasure",nullptr )
, SchemaEntry("ifclayersetdirectionenum",NULL ) , SchemaEntry("ifclayersetdirectionenum",nullptr )
, SchemaEntry("ifcrailingtypeenum",NULL ) , SchemaEntry("ifcrailingtypeenum",nullptr )
, SchemaEntry("ifcobjectiveenum",NULL ) , SchemaEntry("ifcobjectiveenum",nullptr )
, SchemaEntry("ifcdocumentselect",NULL ) , SchemaEntry("ifcdocumentselect",nullptr )
, SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",NULL ) , SchemaEntry("ifcmodulusoflinearsubgradereactionmeasure",nullptr )
, SchemaEntry("ifcthermaladmittancemeasure",NULL ) , SchemaEntry("ifcthermaladmittancemeasure",nullptr )
, SchemaEntry("ifctransitioncode",NULL ) , SchemaEntry("ifctransitioncode",nullptr )
, SchemaEntry("ifcconnectiontypeenum",NULL ) , SchemaEntry("ifcconnectiontypeenum",nullptr )
, SchemaEntry("ifcmonetarymeasure",NULL ) , SchemaEntry("ifcmonetarymeasure",nullptr )
, SchemaEntry("ifcstackterminaltypeenum",NULL ) , SchemaEntry("ifcstackterminaltypeenum",nullptr )
, SchemaEntry("ifccolour",NULL ) , SchemaEntry("ifccolour",nullptr )
, SchemaEntry("ifctext",NULL ) , SchemaEntry("ifctext",nullptr )
, SchemaEntry("ifccontextdependentmeasure",NULL ) , SchemaEntry("ifccontextdependentmeasure",nullptr )
, SchemaEntry("ifcthermalconductivitymeasure",NULL ) , SchemaEntry("ifcthermalconductivitymeasure",nullptr )
, SchemaEntry("ifcprojectedortruelengthenum",NULL ) , SchemaEntry("ifcprojectedortruelengthenum",nullptr )
, SchemaEntry("ifcpressuremeasure",NULL ) , SchemaEntry("ifcpressuremeasure",nullptr )
, SchemaEntry("ifcmoisturediffusivitymeasure",NULL ) , SchemaEntry("ifcmoisturediffusivitymeasure",nullptr )
, SchemaEntry("ifcbooleanoperator",NULL ) , SchemaEntry("ifcbooleanoperator",nullptr )
, SchemaEntry("ifcpropertysourceenum",NULL ) , SchemaEntry("ifcpropertysourceenum",nullptr )
, SchemaEntry("ifctimestamp",NULL ) , SchemaEntry("ifctimestamp",nullptr )
, SchemaEntry("ifcmaterialselect",NULL ) , SchemaEntry("ifcmaterialselect",nullptr )
, SchemaEntry("ifcgloballyuniqueid",NULL ) , SchemaEntry("ifcgloballyuniqueid",nullptr )
, SchemaEntry("ifcreflectancemethodenum",NULL ) , SchemaEntry("ifcreflectancemethodenum",nullptr )
, SchemaEntry("ifcvaporpermeabilitymeasure",NULL ) , SchemaEntry("ifcvaporpermeabilitymeasure",nullptr )
, SchemaEntry("ifctimeseriesscheduletypeenum",NULL ) , SchemaEntry("ifctimeseriesscheduletypeenum",nullptr )
, SchemaEntry("ifclinearmomentmeasure",NULL ) , SchemaEntry("ifclinearmomentmeasure",nullptr )
, SchemaEntry("ifcgeometricsetselect",NULL ) , SchemaEntry("ifcgeometricsetselect",nullptr )
, SchemaEntry("ifcsectionmodulusmeasure",NULL ) , SchemaEntry("ifcsectionmodulusmeasure",nullptr )
, SchemaEntry("ifcbsplinecurveform",NULL ) , SchemaEntry("ifcbsplinecurveform",nullptr )
, SchemaEntry("ifcdimensionextentusage",NULL ) , SchemaEntry("ifcdimensionextentusage",nullptr )
, SchemaEntry("ifcthermalexpansioncoefficientmeasure",NULL ) , SchemaEntry("ifcthermalexpansioncoefficientmeasure",nullptr )
, SchemaEntry("ifchourinday",NULL ) , SchemaEntry("ifchourinday",nullptr )
, SchemaEntry("ifclinearvelocitymeasure",NULL ) , SchemaEntry("ifclinearvelocitymeasure",nullptr )
, SchemaEntry("ifctorquemeasure",NULL ) , SchemaEntry("ifctorquemeasure",nullptr )
, SchemaEntry("ifctemperaturegradientmeasure",NULL ) , SchemaEntry("ifctemperaturegradientmeasure",nullptr )
, SchemaEntry("ifcfillstyleselect",NULL ) , SchemaEntry("ifcfillstyleselect",nullptr )
, SchemaEntry("ifcelectricchargemeasure",NULL ) , SchemaEntry("ifcelectricchargemeasure",nullptr )
, SchemaEntry("ifcheatexchangertypeenum",NULL ) , SchemaEntry("ifcheatexchangertypeenum",nullptr )
, SchemaEntry("ifcelectriccurrentenum",NULL ) , SchemaEntry("ifcelectriccurrentenum",nullptr )
, SchemaEntry("ifcdaylightsavinghour",NULL ) , SchemaEntry("ifcdaylightsavinghour",nullptr )
, SchemaEntry("ifcshell",NULL ) , SchemaEntry("ifcshell",nullptr )
, SchemaEntry("ifcdoseequivalentmeasure",NULL ) , SchemaEntry("ifcdoseequivalentmeasure",nullptr )
, SchemaEntry("ifcprojectordertypeenum",NULL ) , SchemaEntry("ifcprojectordertypeenum",nullptr )
, SchemaEntry("ifcderivedmeasurevalue",NULL ) , SchemaEntry("ifcderivedmeasurevalue",nullptr )
, SchemaEntry("ifclightdistributioncurveenum",NULL ) , SchemaEntry("ifclightdistributioncurveenum",nullptr )
, SchemaEntry("ifcwarpingmomentmeasure",NULL ) , SchemaEntry("ifcwarpingmomentmeasure",nullptr )
, SchemaEntry("ifcmembertypeenum",NULL ) , SchemaEntry("ifcmembertypeenum",nullptr )
, SchemaEntry("ifcsoundpowermeasure",NULL ) , SchemaEntry("ifcsoundpowermeasure",nullptr )
, SchemaEntry("ifctextalignment",NULL ) , SchemaEntry("ifctextalignment",nullptr )
, SchemaEntry("ifccurveoredgecurve",NULL ) , SchemaEntry("ifccurveoredgecurve",nullptr )
, SchemaEntry("ifcmassflowratemeasure",NULL ) , SchemaEntry("ifcmassflowratemeasure",nullptr )
, SchemaEntry("ifcisothermalmoisturecapacitymeasure",NULL ) , SchemaEntry("ifcisothermalmoisturecapacitymeasure",nullptr )
, SchemaEntry("ifccsgselect",NULL ) , SchemaEntry("ifccsgselect",nullptr )
, SchemaEntry("ifccoolingtowertypeenum",NULL ) , SchemaEntry("ifccoolingtowertypeenum",nullptr )
, SchemaEntry("ifcmassmeasure",NULL ) , SchemaEntry("ifcmassmeasure",nullptr )
, SchemaEntry("ifcpileconstructionenum",NULL ) , SchemaEntry("ifcpileconstructionenum",nullptr )
, SchemaEntry("ifcdoorstyleoperationenum",NULL ) , SchemaEntry("ifcdoorstyleoperationenum",nullptr )
, SchemaEntry("ifcflowdirectionenum",NULL ) , SchemaEntry("ifcflowdirectionenum",nullptr )
, SchemaEntry("ifcthermalloadsourceenum",NULL ) , SchemaEntry("ifcthermalloadsourceenum",nullptr )
, SchemaEntry("ifclengthmeasure",NULL ) , SchemaEntry("ifclengthmeasure",nullptr )
, SchemaEntry("ifcconstraintenum",NULL ) , SchemaEntry("ifcconstraintenum",nullptr )
, SchemaEntry("ifcaxis2placement",NULL ) , SchemaEntry("ifcaxis2placement",nullptr )
, SchemaEntry("ifcloadgrouptypeenum",NULL ) , SchemaEntry("ifcloadgrouptypeenum",nullptr )
, SchemaEntry("ifcvalue",NULL ) , SchemaEntry("ifcvalue",nullptr )
, SchemaEntry("ifcreinforcingbarsurfaceenum",NULL ) , SchemaEntry("ifcreinforcingbarsurfaceenum",nullptr )
, SchemaEntry("ifcprojectorderrecordtypeenum",NULL ) , SchemaEntry("ifcprojectorderrecordtypeenum",nullptr )
, SchemaEntry("ifcdatetimeselect",NULL ) , SchemaEntry("ifcdatetimeselect",nullptr )
, SchemaEntry("ifcstructuralsurfacetypeenum",NULL ) , SchemaEntry("ifcstructuralsurfacetypeenum",nullptr )
, SchemaEntry("ifcpermeablecoveringoperationenum",NULL ) , SchemaEntry("ifcpermeablecoveringoperationenum",nullptr )
, SchemaEntry("ifcfontweight",NULL ) , SchemaEntry("ifcfontweight",nullptr )
, SchemaEntry("ifcphmeasure",NULL ) , SchemaEntry("ifcphmeasure",nullptr )
, SchemaEntry("ifcdescriptivemeasure",NULL ) , SchemaEntry("ifcdescriptivemeasure",nullptr )
, SchemaEntry("ifccurvestylefontselect",NULL ) , SchemaEntry("ifccurvestylefontselect",nullptr )
, SchemaEntry("ifcunit",NULL ) , SchemaEntry("ifcunit",nullptr )
, SchemaEntry("ifchatchlinedistanceselect",NULL ) , SchemaEntry("ifchatchlinedistanceselect",nullptr )
, SchemaEntry("ifctextstyleselect",NULL ) , SchemaEntry("ifctextstyleselect",nullptr )
, SchemaEntry("ifcmetricvalueselect",NULL ) , SchemaEntry("ifcmetricvalueselect",nullptr )
, SchemaEntry("ifcvectorordirection",NULL ) , SchemaEntry("ifcvectorordirection",nullptr )
, SchemaEntry("ifcassemblyplaceenum",NULL ) , SchemaEntry("ifcassemblyplaceenum",nullptr )
, SchemaEntry("ifcairterminaltypeenum",NULL ) , SchemaEntry("ifcairterminaltypeenum",nullptr )
, SchemaEntry("ifccoveringtypeenum",NULL ) , SchemaEntry("ifccoveringtypeenum",nullptr )
, SchemaEntry("ifcplanarforcemeasure",NULL ) , SchemaEntry("ifcplanarforcemeasure",nullptr )
, SchemaEntry("ifcvalvetypeenum",NULL ) , SchemaEntry("ifcvalvetypeenum",nullptr )
, SchemaEntry("ifcalarmtypeenum",NULL ) , SchemaEntry("ifcalarmtypeenum",nullptr )
, SchemaEntry("ifcdynamicviscositymeasure",NULL ) , SchemaEntry("ifcdynamicviscositymeasure",nullptr )
, SchemaEntry("ifccurrencyenum",NULL ) , SchemaEntry("ifccurrencyenum",nullptr )
, SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",NULL ) , SchemaEntry("ifcmodulusofrotationalsubgradereactionmeasure",nullptr )
, SchemaEntry("ifccablecarrierfittingtypeenum",NULL ) , SchemaEntry("ifccablecarrierfittingtypeenum",nullptr )
, SchemaEntry("ifcboolean",NULL ) , SchemaEntry("ifcboolean",nullptr )
, SchemaEntry("ifcactionsourcetypeenum",NULL ) , SchemaEntry("ifcactionsourcetypeenum",nullptr )
, SchemaEntry("ifcstructuralactivityassignmentselect",NULL ) , SchemaEntry("ifcstructuralactivityassignmentselect",nullptr )
, SchemaEntry("ifcdistributionchamberelementtypeenum",NULL ) , SchemaEntry("ifcdistributionchamberelementtypeenum",nullptr )
, SchemaEntry("ifcevaporativecoolertypeenum",NULL ) , SchemaEntry("ifcevaporativecoolertypeenum",nullptr )
, SchemaEntry("ifcmagneticfluxdensitymeasure",NULL ) , SchemaEntry("ifcmagneticfluxdensitymeasure",nullptr )
, SchemaEntry("ifclightdistributiondatasourceselect",NULL ) , SchemaEntry("ifclightdistributiondatasourceselect",nullptr )
, SchemaEntry("ifctubebundletypeenum",NULL ) , SchemaEntry("ifctubebundletypeenum",nullptr )
, SchemaEntry("ifcaccelerationmeasure",NULL ) , SchemaEntry("ifcaccelerationmeasure",nullptr )
, SchemaEntry("ifcboilertypeenum",NULL ) , SchemaEntry("ifcboilertypeenum",nullptr )
, SchemaEntry("ifcramptypeenum",NULL ) , SchemaEntry("ifcramptypeenum",nullptr )
, SchemaEntry("ifcluminousintensitydistributionmeasure",NULL ) , SchemaEntry("ifcluminousintensitydistributionmeasure",nullptr )
, SchemaEntry("ifctrimmingpreference",NULL ) , SchemaEntry("ifctrimmingpreference",nullptr )
, SchemaEntry("ifcspecificheatcapacitymeasure",NULL ) , SchemaEntry("ifcspecificheatcapacitymeasure",nullptr )
, SchemaEntry("ifcamountofsubstancemeasure",NULL ) , SchemaEntry("ifcamountofsubstancemeasure",nullptr )
, SchemaEntry("ifcroleenum",NULL ) , SchemaEntry("ifcroleenum",nullptr )
, SchemaEntry("ifcdocumentconfidentialityenum",NULL ) , SchemaEntry("ifcdocumentconfidentialityenum",nullptr )
, SchemaEntry("ifcfrequencymeasure",NULL ) , SchemaEntry("ifcfrequencymeasure",nullptr )
, SchemaEntry("ifcsectiontypeenum",NULL ) , SchemaEntry("ifcsectiontypeenum",nullptr )
, SchemaEntry("ifcelementassemblytypeenum",NULL ) , SchemaEntry("ifcelementassemblytypeenum",nullptr )
, SchemaEntry("ifcfootingtypeenum",NULL ) , SchemaEntry("ifcfootingtypeenum",nullptr )
, SchemaEntry("ifclayereditem",NULL ) , SchemaEntry("ifclayereditem",nullptr )
, SchemaEntry("ifccablesegmenttypeenum",NULL ) , SchemaEntry("ifccablesegmenttypeenum",nullptr )
, SchemaEntry("ifcdefinedsymbolselect",NULL ) , SchemaEntry("ifcdefinedsymbolselect",nullptr )
, SchemaEntry("ifcbuildingelementproxytypeenum",NULL ) , SchemaEntry("ifcbuildingelementproxytypeenum",nullptr )
, SchemaEntry("ifcelectricgeneratortypeenum",NULL ) , SchemaEntry("ifcelectricgeneratortypeenum",nullptr )
, SchemaEntry("ifcrotationalstiffnessmeasure",NULL ) , SchemaEntry("ifcrotationalstiffnessmeasure",nullptr )
, SchemaEntry("ifcspaceheatertypeenum",NULL ) , SchemaEntry("ifcspaceheatertypeenum",nullptr )
, SchemaEntry("ifcareameasure",NULL ) , SchemaEntry("ifcareameasure",nullptr )
, SchemaEntry("ifclabel",NULL ) , SchemaEntry("ifclabel",nullptr )
, SchemaEntry("ifccostscheduletypeenum",NULL ) , SchemaEntry("ifccostscheduletypeenum",nullptr )
, SchemaEntry("ifcswitchingdevicetypeenum",NULL ) , SchemaEntry("ifcswitchingdevicetypeenum",nullptr )
, SchemaEntry("ifcelectrictimecontroltypeenum",NULL ) , SchemaEntry("ifcelectrictimecontroltypeenum",nullptr )
, SchemaEntry("ifcfiltertypeenum",NULL ) , SchemaEntry("ifcfiltertypeenum",nullptr )
, SchemaEntry("ifcpositivelengthmeasure",NULL ) , SchemaEntry("ifcpositivelengthmeasure",nullptr )
, SchemaEntry("ifcnullstyle",NULL ) , SchemaEntry("ifcnullstyle",nullptr )
, SchemaEntry("ifcconditioncriterionselect",NULL ) , SchemaEntry("ifcconditioncriterionselect",nullptr )
, SchemaEntry("ifcshearmodulusmeasure",NULL ) , SchemaEntry("ifcshearmodulusmeasure",nullptr )
, SchemaEntry("ifcnormalisedratiomeasure",NULL ) , SchemaEntry("ifcnormalisedratiomeasure",nullptr )
, SchemaEntry("ifcdoorpaneloperationenum",NULL ) , SchemaEntry("ifcdoorpaneloperationenum",nullptr )
, SchemaEntry("ifcpointorvertexpoint",NULL ) , SchemaEntry("ifcpointorvertexpoint",nullptr )
, SchemaEntry("ifcrooftypeenum",NULL ) , SchemaEntry("ifcrooftypeenum",nullptr )
, SchemaEntry("ifccountmeasure",NULL ) , SchemaEntry("ifccountmeasure",nullptr )
, SchemaEntry("ifcelectricconductancemeasure",NULL ) , SchemaEntry("ifcelectricconductancemeasure",nullptr )
, SchemaEntry("ifcproceduretypeenum",NULL ) , SchemaEntry("ifcproceduretypeenum",nullptr )
, SchemaEntry("ifcflowinstrumenttypeenum",NULL ) , SchemaEntry("ifcflowinstrumenttypeenum",nullptr )
, SchemaEntry("ifcelectricmotortypeenum",NULL ) , SchemaEntry("ifcelectricmotortypeenum",nullptr )
, SchemaEntry("ifcsurfaceside",NULL ) , SchemaEntry("ifcsurfaceside",nullptr )
, SchemaEntry("ifcstructuralcurvetypeenum",NULL ) , SchemaEntry("ifcstructuralcurvetypeenum",nullptr )
, SchemaEntry("ifccondensertypeenum",NULL ) , SchemaEntry("ifccondensertypeenum",nullptr )
, SchemaEntry("ifclinearstiffnessmeasure",NULL ) , SchemaEntry("ifclinearstiffnessmeasure",nullptr )
, SchemaEntry("ifcunitenum",NULL ) , SchemaEntry("ifcunitenum",nullptr )
, SchemaEntry("ifcoccupanttypeenum",NULL ) , SchemaEntry("ifcoccupanttypeenum",nullptr )
, SchemaEntry("ifcthermalloadtypeenum",NULL ) , SchemaEntry("ifcthermalloadtypeenum",nullptr )
, SchemaEntry("ifcreinforcingbarroleenum",NULL ) , SchemaEntry("ifcreinforcingbarroleenum",nullptr )
, SchemaEntry("ifcbenchmarkenum",NULL ) , SchemaEntry("ifcbenchmarkenum",nullptr )
, SchemaEntry("ifcpositiveplaneanglemeasure",NULL ) , SchemaEntry("ifcpositiveplaneanglemeasure",nullptr )
, SchemaEntry("ifctexttransformation",NULL ) , SchemaEntry("ifctexttransformation",nullptr )
, SchemaEntry("ifcdraughtingcalloutelement",NULL ) , SchemaEntry("ifcdraughtingcalloutelement",nullptr )
, SchemaEntry("ifcratiomeasure",NULL ) , SchemaEntry("ifcratiomeasure",nullptr )
, SchemaEntry("ifcsolidanglemeasure",NULL ) , SchemaEntry("ifcsolidanglemeasure",nullptr )
, SchemaEntry("ifcpipesegmenttypeenum",NULL ) , SchemaEntry("ifcpipesegmenttypeenum",nullptr )
, SchemaEntry("ifccablecarriersegmenttypeenum",NULL ) , SchemaEntry("ifccablecarriersegmenttypeenum",nullptr )
, SchemaEntry("ifccolourorfactor",NULL ) , SchemaEntry("ifccolourorfactor",nullptr )
, SchemaEntry("ifcidentifier",NULL ) , SchemaEntry("ifcidentifier",nullptr )
, SchemaEntry("ifctendontypeenum",NULL ) , SchemaEntry("ifctendontypeenum",nullptr )
, SchemaEntry("ifccontrollertypeenum",NULL ) , SchemaEntry("ifccontrollertypeenum",nullptr )
, SchemaEntry("ifcradioactivitymeasure",NULL ) , SchemaEntry("ifcradioactivitymeasure",nullptr )
, SchemaEntry("ifctimemeasure",NULL ) , SchemaEntry("ifctimemeasure",nullptr )
, SchemaEntry("ifcpumptypeenum",NULL ) , SchemaEntry("ifcpumptypeenum",nullptr )
, SchemaEntry("ifcelectricheatertypeenum",NULL ) , SchemaEntry("ifcelectricheatertypeenum",nullptr )
, SchemaEntry("ifcbeamtypeenum",NULL ) , SchemaEntry("ifcbeamtypeenum",nullptr )
, SchemaEntry("ifcstateenum",NULL ) , SchemaEntry("ifcstateenum",nullptr )
, SchemaEntry("ifcsiprefix",NULL ) , SchemaEntry("ifcsiprefix",nullptr )
, SchemaEntry("ifcnumericmeasure",NULL ) , SchemaEntry("ifcnumericmeasure",nullptr )
, SchemaEntry("ifcoutlettypeenum",NULL ) , SchemaEntry("ifcoutlettypeenum",nullptr )
, SchemaEntry("ifccompoundplaneanglemeasure",NULL ) , SchemaEntry("ifccompoundplaneanglemeasure",nullptr )
, SchemaEntry("ifcservicelifefactortypeenum",NULL ) , SchemaEntry("ifcservicelifefactortypeenum",nullptr )
, SchemaEntry("ifclogicaloperatorenum",NULL ) , SchemaEntry("ifclogicaloperatorenum",nullptr )
, SchemaEntry("ifcbooleanoperand",NULL ) , SchemaEntry("ifcbooleanoperand",nullptr )
, SchemaEntry("ifcobjectreferenceselect",NULL ) , SchemaEntry("ifcobjectreferenceselect",nullptr )
, SchemaEntry("ifccooledbeamtypeenum",NULL ) , SchemaEntry("ifccooledbeamtypeenum",nullptr )
, SchemaEntry("ifcductsilencertypeenum",NULL ) , SchemaEntry("ifcductsilencertypeenum",nullptr )
, SchemaEntry("ifcsectionalareaintegralmeasure",NULL ) , SchemaEntry("ifcsectionalareaintegralmeasure",nullptr )
, SchemaEntry("ifcfontvariant",NULL ) , SchemaEntry("ifcfontvariant",nullptr )
, SchemaEntry("ifcvolumetricflowratemeasure",NULL ) , SchemaEntry("ifcvolumetricflowratemeasure",nullptr )
, SchemaEntry("ifcplatetypeenum",NULL ) , SchemaEntry("ifcplatetypeenum",nullptr )
, SchemaEntry("ifcenvironmentalimpactcategoryenum",NULL ) , SchemaEntry("ifcenvironmentalimpactcategoryenum",nullptr )
, SchemaEntry("ifcvibrationisolatortypeenum",NULL ) , SchemaEntry("ifcvibrationisolatortypeenum",nullptr )
, SchemaEntry("ifcthermodynamictemperaturemeasure",NULL ) , SchemaEntry("ifcthermodynamictemperaturemeasure",nullptr )
, SchemaEntry("ifcrotationalmassmeasure",NULL ) , SchemaEntry("ifcrotationalmassmeasure",nullptr )
, SchemaEntry("ifcsecondinminute",NULL ) , SchemaEntry("ifcsecondinminute",nullptr )
, SchemaEntry("ifcdayinmonthnumber",NULL ) , SchemaEntry("ifcdayinmonthnumber",nullptr )
, SchemaEntry("ifcdimensioncount",NULL ) , SchemaEntry("ifcdimensioncount",nullptr )
, SchemaEntry("ifcwindowstyleoperationenum",NULL ) , SchemaEntry("ifcwindowstyleoperationenum",nullptr )
, SchemaEntry("ifcthermalresistancemeasure",NULL ) , SchemaEntry("ifcthermalresistancemeasure",nullptr )
, SchemaEntry("ifcmeasurevalue",NULL ) , SchemaEntry("ifcmeasurevalue",nullptr )
, SchemaEntry("ifcwindowpaneloperationenum",NULL ) , SchemaEntry("ifcwindowpaneloperationenum",nullptr )
, SchemaEntry("ifcchillertypeenum",NULL ) , SchemaEntry("ifcchillertypeenum",nullptr )
, SchemaEntry("ifcpositiveratiomeasure",NULL ) , SchemaEntry("ifcpositiveratiomeasure",nullptr )
, SchemaEntry("ifcinteger",NULL ) , SchemaEntry("ifcinteger",nullptr )
, SchemaEntry("ifclogical",NULL ) , SchemaEntry("ifclogical",nullptr )
, SchemaEntry("ifcjunctionboxtypeenum",NULL ) , SchemaEntry("ifcjunctionboxtypeenum",nullptr )
, SchemaEntry("ifcaddresstypeenum",NULL ) , SchemaEntry("ifcaddresstypeenum",nullptr )
, SchemaEntry("ifcwasteterminaltypeenum",NULL ) , SchemaEntry("ifcwasteterminaltypeenum",nullptr )
, SchemaEntry("ifctrimmingselect",NULL ) , SchemaEntry("ifctrimmingselect",nullptr )
, SchemaEntry("ifclightemissionsourceenum",NULL ) , SchemaEntry("ifclightemissionsourceenum",nullptr )
, SchemaEntry("ifcsoundscaleenum",NULL ) , SchemaEntry("ifcsoundscaleenum",nullptr )
, SchemaEntry("ifcluminousfluxmeasure",NULL ) , SchemaEntry("ifcluminousfluxmeasure",nullptr )
, SchemaEntry("ifcelectricresistancemeasure",NULL ) , SchemaEntry("ifcelectricresistancemeasure",nullptr )
, SchemaEntry("ifcintegercountratemeasure",NULL ) , SchemaEntry("ifcintegercountratemeasure",nullptr )
, SchemaEntry("ifcphysicalorvirtualenum",NULL ) , SchemaEntry("ifcphysicalorvirtualenum",nullptr )
, SchemaEntry("ifcmolecularweightmeasure",NULL ) , SchemaEntry("ifcmolecularweightmeasure",nullptr )
, SchemaEntry("ifcprofiletypeenum",NULL ) , SchemaEntry("ifcprofiletypeenum",nullptr )
, SchemaEntry("ifcboxalignment",NULL ) , SchemaEntry("ifcboxalignment",nullptr )
, SchemaEntry("ifcglobalorlocalenum",NULL ) , SchemaEntry("ifcglobalorlocalenum",nullptr )
, SchemaEntry("ifcspecularroughness",NULL ) , SchemaEntry("ifcspecularroughness",nullptr )
, SchemaEntry("ifclamptypeenum",NULL ) , SchemaEntry("ifclamptypeenum",nullptr )
, SchemaEntry("ifcpiletypeenum",NULL ) , SchemaEntry("ifcpiletypeenum",nullptr )
, SchemaEntry("ifcelectriccurrentmeasure",NULL ) , SchemaEntry("ifcelectriccurrentmeasure",nullptr )
, SchemaEntry("ifcfantypeenum",NULL ) , SchemaEntry("ifcfantypeenum",nullptr )
, SchemaEntry("ifcsurfaceorfacesurface",NULL ) , SchemaEntry("ifcsurfaceorfacesurface",nullptr )
, SchemaEntry("ifcpipefittingtypeenum",NULL ) , SchemaEntry("ifcpipefittingtypeenum",nullptr )
, SchemaEntry("ifctanktypeenum",NULL ) , SchemaEntry("ifctanktypeenum",nullptr )
, SchemaEntry("ifccurvefontorscaledcurvefontselect",NULL ) , SchemaEntry("ifccurvefontorscaledcurvefontselect",nullptr )
, SchemaEntry("ifcwindowstyleconstructionenum",NULL ) , SchemaEntry("ifcwindowstyleconstructionenum",nullptr )
, SchemaEntry("ifcairterminalboxtypeenum",NULL ) , SchemaEntry("ifcairterminalboxtypeenum",nullptr )
, SchemaEntry("ifcstairflighttypeenum",NULL ) , SchemaEntry("ifcstairflighttypeenum",nullptr )
, SchemaEntry("ifcluminousintensitymeasure",NULL ) , SchemaEntry("ifcluminousintensitymeasure",nullptr )
, SchemaEntry("ifcmotorconnectiontypeenum",NULL ) , SchemaEntry("ifcmotorconnectiontypeenum",nullptr )
, SchemaEntry("ifcplaneanglemeasure",NULL ) , SchemaEntry("ifcplaneanglemeasure",nullptr )
, SchemaEntry("ifcactuatortypeenum",NULL ) , SchemaEntry("ifcactuatortypeenum",nullptr )
, SchemaEntry("ifccolumntypeenum",NULL ) , SchemaEntry("ifccolumntypeenum",nullptr )
, SchemaEntry("ifctextfontselect",NULL ) , SchemaEntry("ifctextfontselect",nullptr )
, SchemaEntry("ifcdoorpanelpositionenum",NULL ) , SchemaEntry("ifcdoorpanelpositionenum",nullptr )
, SchemaEntry("ifccoiltypeenum",NULL ) , SchemaEntry("ifccoiltypeenum",nullptr )
, SchemaEntry("ifcangularvelocitymeasure",NULL ) , SchemaEntry("ifcangularvelocitymeasure",nullptr )
, SchemaEntry("ifcanalysismodeltypeenum",NULL ) , SchemaEntry("ifcanalysismodeltypeenum",nullptr )
, SchemaEntry("ifclibraryselect",NULL ) , SchemaEntry("ifclibraryselect",nullptr )
, SchemaEntry("ifcforcemeasure",NULL ) , SchemaEntry("ifcforcemeasure",nullptr )
, SchemaEntry("ifcfillareastyletileshapeselect",NULL ) , SchemaEntry("ifcfillareastyletileshapeselect",nullptr )
, SchemaEntry("ifcelectricappliancetypeenum",NULL ) , SchemaEntry("ifcelectricappliancetypeenum",nullptr )
, SchemaEntry("ifcsurfacetextureenum",NULL ) , SchemaEntry("ifcsurfacetextureenum",nullptr )
, SchemaEntry("ifccharacterstyleselect",NULL ) , SchemaEntry("ifccharacterstyleselect",nullptr )
, SchemaEntry("ifcenergymeasure",NULL ) , SchemaEntry("ifcenergymeasure",nullptr )
, SchemaEntry("ifcreal",NULL ) , SchemaEntry("ifcreal",nullptr )
, SchemaEntry("ifccompressortypeenum",NULL ) , SchemaEntry("ifccompressortypeenum",nullptr )
, SchemaEntry("ifcelectricdistributionpointfunctionenum",NULL ) , SchemaEntry("ifcelectricdistributionpointfunctionenum",nullptr )
, SchemaEntry("ifcroot",&STEP::ObjectHelper<IfcRoot,4>::Construct ) , SchemaEntry("ifcroot",&STEP::ObjectHelper<IfcRoot,4>::Construct )
, SchemaEntry("ifcobjectdefinition",&STEP::ObjectHelper<IfcObjectDefinition,0>::Construct ) , SchemaEntry("ifcobjectdefinition",&STEP::ObjectHelper<IfcObjectDefinition,0>::Construct )
, SchemaEntry("ifctypeobject",&STEP::ObjectHelper<IfcTypeObject,2>::Construct ) , SchemaEntry("ifctypeobject",&STEP::ObjectHelper<IfcTypeObject,2>::Construct )

View File

@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/Step/STEPFile.h" #include "AssetLib/Step/STEPFile.h"
#ifdef _WIN32 #if _MSC_VER > 1920
# pragma warning( disable : 4512 ) # pragma warning( disable : 4512 )
#endif // _WIN32 #endif // _WIN32

View File

@ -71,7 +71,7 @@ aiMesh* TempMesh::ToMesh()
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0))); ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(),mVertcnt.end(),size_t(0)));
if (mVerts.empty()) { if (mVerts.empty()) {
return NULL; return nullptr;
} }
std::unique_ptr<aiMesh> mesh(new aiMesh()); std::unique_ptr<aiMesh> mesh(new aiMesh());

View File

@ -201,7 +201,7 @@ struct ConversionData
struct MeshCacheIndex { struct MeshCacheIndex {
const IFC::Schema_2x3::IfcRepresentationItem* item; unsigned int matindex; const IFC::Schema_2x3::IfcRepresentationItem* item; unsigned int matindex;
MeshCacheIndex() : item(NULL), matindex(0) { } MeshCacheIndex() : item(nullptr), matindex(0) { }
MeshCacheIndex(const IFC::Schema_2x3::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { } MeshCacheIndex(const IFC::Schema_2x3::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { }
bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; } bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; }
bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); } bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); }

File diff suppressed because it is too large Load Diff

View File

@ -139,8 +139,9 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile)); std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if (file.get() == nullptr) {
throw DeadlyImportError( "Failed to open IRRMESH file " + pFile + ""); throw DeadlyImportError("Failed to open IRRMESH file " + pFile + ".");
}
// Construct the irrXML parser // Construct the irrXML parser
CIrrXML_IOStreamReader st(file.get()); CIrrXML_IOStreamReader st(file.get());

View File

@ -538,11 +538,11 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey> &out,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Extract animation channel // Extract animation channel
void AnimResolver::ExtractAnimChannel(aiNodeAnim **out, unsigned int /*= 0*/) { void AnimResolver::ExtractAnimChannel(aiNodeAnim **out, unsigned int /*= 0*/) {
*out = NULL; *out = nullptr;
//FIXME: crashes if more than one component is animated at different timings, to be resolved. //FIXME: crashes if more than one component is animated at different timings, to be resolved.
// If we have no envelopes, return NULL // If we have no envelopes, return nullptr
if (envelopes.empty()) { if (envelopes.empty()) {
return; return;
} }

View File

@ -211,7 +211,7 @@ public:
// ------------------------------------------------------------------ // ------------------------------------------------------------------
/** @brief Extract a node animation channel /** @brief Extract a node animation channel
* @param out Receives a pointer to a newly allocated node anim. * @param out Receives a pointer to a newly allocated node anim.
* If there's just one keyframe defined, *out is set to NULL and * If there's just one keyframe defined, *out is set to nullptr and
* no animation channel is computed. * no animation channel is computed.
* @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags. * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
*/ */
@ -261,7 +261,7 @@ protected:
* @param envl_y Y-component envelope * @param envl_y Y-component envelope
* @param envl_z Z-component envelope * @param envl_z Z-component envelope
* @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags. * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
* @note Up to two input envelopes may be NULL * @note Up to two input envelopes may be nullptr
*/ */
void GetKeys(std::vector<aiVectorKey>& out, void GetKeys(std::vector<aiVectorKey>& out,
LWO::Envelope* envl_x, LWO::Envelope* envl_x,

View File

@ -255,7 +255,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
mSurfaces->push_back( LWO::Surface () ); mSurfaces->push_back( LWO::Surface () );
LWO::Surface& surf = mSurfaces->back(); LWO::Surface& surf = mSurfaces->back();
LWO::Texture* pTex = NULL; LWO::Texture *pTex = nullptr;
GetS0(surf.mName,size); GetS0(surf.mName,size);
bool running = true; bool running = true;

View File

@ -917,7 +917,7 @@ inline void CreateNewEntry(std::vector<T> &list, unsigned int srcIdx) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead, inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry *base, unsigned int numRead,
unsigned int idx, float *data) { unsigned int idx, float *data) {
ai_assert(NULL != data); ai_assert(nullptr != data);
LWO::ReferrerList &refList = mCurLayer->mPointReferrers; LWO::ReferrerList &refList = mCurLayer->mPointReferrers;
unsigned int i; unsigned int i;

View File

@ -305,7 +305,7 @@ private:
/** Add children to a node /** Add children to a node
* @param node Node to become a father * @param node Node to become a father
* @param parent Index of the node * @param parent Index of the node
* @param apcNodes Flat list of nodes - used nodes are set to NULL. * @param apcNodes Flat list of nodes - used nodes are set to nullptr.
*/ */
void AddChildren(aiNode* node, uint16_t parent, void AddChildren(aiNode* node, uint16_t parent,
std::vector<aiNode*>& apcNodes); std::vector<aiNode*>& apcNodes);

View File

@ -79,7 +79,7 @@ inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) { bool LWOImporter::HandleTextures(aiMaterial *pcMat, const TextureList &in, aiTextureType type) {
ai_assert(NULL != pcMat); ai_assert(nullptr != pcMat);
unsigned int cur = 0, temp = 0; unsigned int cur = 0, temp = 0;
aiString s; aiString s;
@ -603,7 +603,7 @@ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader *head, unsi
} }
// get the destination channel // get the destination channel
TextureList *listRef = NULL; TextureList *listRef = nullptr;
switch (tex.type) { switch (tex.type) {
case AI_LWO_COLR: case AI_LWO_COLR:
listRef = &surf.mColorTextures; listRef = &surf.mColorTextures;

View File

@ -342,7 +342,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
if (src.type == LWS::NodeDesc::OBJECT) { if (src.type == LWS::NodeDesc::OBJECT) {
// If the object is from an external file, get it // If the object is from an external file, get it
aiScene *obj = NULL; aiScene *obj = nullptr;
if (src.path.length()) { if (src.path.length()) {
obj = batch.GetImport(src.id); obj = batch.GetImport(src.id);
if (!obj) { if (!obj) {
@ -359,7 +359,7 @@ void LWSImporter::BuildGraph(aiNode *nd, LWS::NodeDesc &src, std::vector<Attachm
//Remove first node from obj (the old pivot), reset transform of second node (the mesh node) //Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
aiNode *newRootNode = obj->mRootNode->mChildren[0]; aiNode *newRootNode = obj->mRootNode->mChildren[0];
obj->mRootNode->mChildren[0] = NULL; obj->mRootNode->mChildren[0] = nullptr;
delete obj->mRootNode; delete obj->mRootNode;
obj->mRootNode = newRootNode; obj->mRootNode = newRootNode;
@ -600,7 +600,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
d.number = cur_object++; d.number = cur_object++;
} }
std::string path = FindLWOFile(c); std::string path = FindLWOFile(c);
d.id = batch.AddLoadRequest(path, 0, NULL); d.id = batch.AddLoadRequest(path, 0, nullptr);
d.path = path; d.path = path;
nodes.push_back(d); nodes.push_back(d);

View File

@ -84,7 +84,19 @@ public:
*/ */
struct NodeDesc { struct NodeDesc {
NodeDesc() : NodeDesc() :
type(), id(), number(0), parent(0), name(""), isPivotSet(false), lightColor(1.f, 1.f, 1.f), lightIntensity(1.f), lightType(0), lightFalloffType(0), lightConeAngle(45.f), lightEdgeAngle(), parent_resolved(NULL) {} type(),
id(),
number(0),
parent(0),
name(""),
isPivotSet(false),
lightColor(1.f, 1.f, 1.f),
lightIntensity(1.f),
lightType(0),
lightFalloffType(0),
lightConeAngle(45.f),
lightEdgeAngle(),
parent_resolved(nullptr) {}
enum { enum {

View File

@ -181,7 +181,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
} }
m3d->material[mi].name = SafeStr(name, true); m3d->material[mi].name = SafeStr(name, true);
m3d->material[mi].numprop = 0; m3d->material[mi].numprop = 0;
m3d->material[mi].prop = NULL; m3d->material[mi].prop = nullptr;
// iterate through the material property table and see what we got // iterate through the material property table and see what we got
for (k = 0; k < 15; k++) { for (k = 0; k < 15; k++) {
unsigned int j; unsigned int j;
@ -229,8 +229,8 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
} }
if (aiTxProps[k].pKey && if (aiTxProps[k].pKey &&
mat->GetTexture((aiTextureType)aiTxProps[k].type, mat->GetTexture((aiTextureType)aiTxProps[k].type,
aiTxProps[k].index, &name, NULL, NULL, NULL, aiTxProps[k].index, &name, nullptr, nullptr, nullptr,
NULL, NULL) == AI_SUCCESS) { nullptr, nullptr) == AI_SUCCESS) {
unsigned int i; unsigned int i;
for (j = name.length - 1; j > 0 && name.data[j] != '.'; j++) for (j = name.length - 1; j > 0 && name.data[j] != '.'; j++)
; ;
@ -259,7 +259,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
m3d->texture[i].name = fn; m3d->texture[i].name = fn;
m3d->texture[i].w = 0; m3d->texture[i].w = 0;
m3d->texture[i].h = 0; m3d->texture[i].h = 0;
m3d->texture[i].d = NULL; m3d->texture[i].d = nullptr;
} }
addProp(&m3d->material[mi], addProp(&m3d->material[mi],
m3d_propertytypes[k].id + 128, i); m3d_propertytypes[k].id + 128, i);

View File

@ -618,8 +618,10 @@ aiColor4D M3DImporter::mkColor(uint32_t c) {
void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid) { void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid) {
ai_assert(m != nullptr); ai_assert(m != nullptr);
ai_assert(m3d); ai_assert(m3d);
ai_assert(posid != M3D_UNDEF && posid < m3d->numvertex); ai_assert(posid != M3D_UNDEF);
ai_assert(orientid != M3D_UNDEF && orientid < m3d->numvertex); ai_assert(posid < m3d->numvertex);
ai_assert(orientid != M3D_UNDEF);
ai_assert(orientid < m3d->numvertex);
if (!m3d->numvertex || !m3d->vertex) if (!m3d->numvertex || !m3d->vertex)
return; return;
m3dv_t *p = &m3d->vertex[posid]; m3dv_t *p = &m3d->vertex[posid];

View File

@ -71,14 +71,14 @@ static const aiMatProp aiProps[] = {
{ AI_MATKEY_OPACITY }, /* m3dp_d */ { AI_MATKEY_OPACITY }, /* m3dp_d */
{ AI_MATKEY_SHADING_MODEL }, /* m3dp_il */ { AI_MATKEY_SHADING_MODEL }, /* m3dp_il */
{ NULL, 0, 0 }, /* m3dp_Pr */ { nullptr, 0, 0 }, /* m3dp_Pr */
{ AI_MATKEY_REFLECTIVITY }, /* m3dp_Pm */ { AI_MATKEY_REFLECTIVITY }, /* m3dp_Pm */
{ NULL, 0, 0 }, /* m3dp_Ps */ { nullptr, 0, 0 }, /* m3dp_Ps */
{ AI_MATKEY_REFRACTI }, /* m3dp_Ni */ { AI_MATKEY_REFRACTI }, /* m3dp_Ni */
{ NULL, 0, 0 }, /* m3dp_Nt */ { nullptr, 0, 0 }, /* m3dp_Nt */
{ NULL, 0, 0 }, { nullptr, 0, 0 },
{ NULL, 0, 0 }, { nullptr, 0, 0 },
{ NULL, 0, 0 } { nullptr, 0, 0 }
}; };
/* --- Texture Map Properties --- !!!!! must match m3d_propertytypes !!!!! */ /* --- Texture Map Properties --- !!!!! must match m3d_propertytypes !!!!! */
@ -88,19 +88,19 @@ static const aiMatProp aiTxProps[] = {
{ AI_MATKEY_TEXTURE_SPECULAR(0) }, /* m3dp_map_Ks */ { AI_MATKEY_TEXTURE_SPECULAR(0) }, /* m3dp_map_Ks */
{ AI_MATKEY_TEXTURE_SHININESS(0) }, /* m3dp_map_Ns */ { AI_MATKEY_TEXTURE_SHININESS(0) }, /* m3dp_map_Ns */
{ AI_MATKEY_TEXTURE_EMISSIVE(0) }, /* m3dp_map_Ke */ { AI_MATKEY_TEXTURE_EMISSIVE(0) }, /* m3dp_map_Ke */
{ NULL, 0, 0 }, /* m3dp_map_Tf */ { nullptr, 0, 0 }, /* m3dp_map_Tf */
{ AI_MATKEY_TEXTURE_HEIGHT(0) }, /* m3dp_bump */ { AI_MATKEY_TEXTURE_HEIGHT(0) }, /* m3dp_bump */
{ AI_MATKEY_TEXTURE_OPACITY(0) }, /* m3dp_map_d */ { AI_MATKEY_TEXTURE_OPACITY(0) }, /* m3dp_map_d */
{ AI_MATKEY_TEXTURE_NORMALS(0) }, /* m3dp_map_N */ { AI_MATKEY_TEXTURE_NORMALS(0) }, /* m3dp_map_N */
{ AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE_ROUGHNESS,0) },/* m3dp_map_Pr */ { AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE_ROUGHNESS,0) },/* m3dp_map_Pr */
{ AI_MATKEY_TEXTURE(aiTextureType_METALNESS,0) }, /* m3dp_map_Pm */ { AI_MATKEY_TEXTURE(aiTextureType_METALNESS,0) }, /* m3dp_map_Pm */
{ NULL, 0, 0 }, /* m3dp_map_Ps */ { nullptr, 0, 0 }, /* m3dp_map_Ps */
{ AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,0) }, /* m3dp_map_Ni */ { AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,0) }, /* m3dp_map_Ni */
{ NULL, 0, 0 }, /* m3dp_map_Nt */ { nullptr, 0, 0 }, /* m3dp_map_Nt */
{ NULL, 0, 0 }, { nullptr, 0, 0 },
{ NULL, 0, 0 }, { nullptr, 0, 0 },
{ NULL, 0, 0 } { nullptr, 0, 0 }
}; };
#endif // AI_M3DMATERIALS_H_INC #endif // AI_M3DMATERIALS_H_INC

View File

@ -72,7 +72,7 @@ unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
std::unique_ptr<Assimp::IOStream> pStream( std::unique_ptr<Assimp::IOStream> pStream(
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb")); (reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
size_t fileSize = 0; size_t fileSize = 0;
unsigned char *data = NULL; unsigned char *data = nullptr;
// sometimes pStream is nullptr in a single-threaded scenario too for some reason // sometimes pStream is nullptr in a single-threaded scenario too for some reason
// (should be an empty object returning nothing I guess) // (should be an empty object returning nothing I guess)
if (pStream) { if (pStream) {

View File

@ -85,7 +85,9 @@ typedef uint16_t M3D_INDEX;
#define M3D_BONEMAXLEVEL 8 #define M3D_BONEMAXLEVEL 8
#endif #endif
#ifndef _MSC_VER #ifndef _MSC_VER
#ifndef _inline
#define _inline __inline__ #define _inline __inline__
#endif
#define _pack __attribute__((packed)) #define _pack __attribute__((packed))
#define _unused __attribute__((unused)) #define _unused __attribute__((unused))
#else #else
@ -99,7 +101,7 @@ typedef uint16_t M3D_INDEX;
#define _register #define _register
#endif #endif
#ifdef _WIN32 #if _MSC_VER > 1920
# pragma warning(push) # pragma warning(push)
# pragma warning(disable : 4100 4127 4189 4505 4244 4403 4701 4703) # pragma warning(disable : 4100 4127 4189 4505 4244 4403 4701 4703)
# if (_MSC_VER > 1800 ) # if (_MSC_VER > 1800 )

View File

@ -221,20 +221,21 @@ void MD2Importer::InternReadFile( const std::string& pFile,
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile)); std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) if (file.get() == nullptr) {
throw DeadlyImportError( "Failed to open MD2 file " + pFile + ""); throw DeadlyImportError("Failed to open MD2 file " + pFile + "");
}
// check whether the md3 file is large enough to contain // check whether the md3 file is large enough to contain
// at least the file header // at least the file header
fileSize = (unsigned int)file->FileSize(); fileSize = (unsigned int)file->FileSize();
if( fileSize < sizeof(MD2::Header)) if (fileSize < sizeof(MD2::Header)) {
throw DeadlyImportError( "MD2 File is too small"); throw DeadlyImportError("MD2 File is too small");
}
std::vector<uint8_t> mBuffer2(fileSize); std::vector<uint8_t> mBuffer2(fileSize);
file->Read(&mBuffer2[0], 1, fileSize); file->Read(&mBuffer2[0], 1, fileSize);
mBuffer = &mBuffer2[0]; mBuffer = &mBuffer2[0];
m_pcHeader = (BE_NCONST MD2::Header*)mBuffer; m_pcHeader = (BE_NCONST MD2::Header*)mBuffer;
#ifdef AI_BUILD_BIG_ENDIAN #ifdef AI_BUILD_BIG_ENDIAN

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, 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,
@ -82,7 +80,15 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MD5Importer::MD5Importer() : MD5Importer::MD5Importer() :
mIOHandler(nullptr), mBuffer(), fileSize(), iLineNumber(), pScene(), bHadMD5Mesh(), bHadMD5Anim(), bHadMD5Camera(), configNoAutoLoad(false) { mIOHandler(nullptr),
mBuffer(),
mFileSize(),
mLineNumber(),
mScene(),
mHadMD5Mesh(),
mHadMD5Anim(),
mHadMD5Camera(),
mCconfigNoAutoLoad(false) {
// empty // empty
} }
@ -106,6 +112,7 @@ bool MD5Importer::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
const char *tokens[] = { "MD5Version" }; const char *tokens[] = { "MD5Version" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
} }
return false; return false;
} }
@ -119,16 +126,15 @@ const aiImporterDesc *MD5Importer::GetInfo() const {
// Setup import properties // Setup import properties
void MD5Importer::SetupProperties(const Importer *pImp) { void MD5Importer::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD // AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0)); mCconfigNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD, 0));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void MD5Importer::InternReadFile(const std::string &pFile, void MD5Importer::InternReadFile(const std::string &pFile, aiScene *_pScene, IOSystem *pIOHandler) {
aiScene *_pScene, IOSystem *pIOHandler) {
mIOHandler = pIOHandler; mIOHandler = pIOHandler;
pScene = _pScene; mScene = _pScene;
bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false; mHadMD5Mesh = mHadMD5Anim = mHadMD5Camera = false;
// remove the file extension // remove the file extension
const std::string::size_type pos = pFile.find_last_of('.'); const std::string::size_type pos = pFile.find_last_of('.');
@ -138,7 +144,7 @@ void MD5Importer::InternReadFile(const std::string &pFile,
try { try {
if (extension == "md5camera") { if (extension == "md5camera") {
LoadMD5CameraFile(); LoadMD5CameraFile();
} else if (configNoAutoLoad || extension == "md5anim") { } else if (mCconfigNoAutoLoad || extension == "md5anim") {
// determine file extension and process just *one* file // determine file extension and process just *one* file
if (extension.length() == 0) { if (extension.length() == 0) {
throw DeadlyImportError("Failure, need file extension to determine MD5 part type"); throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
@ -158,17 +164,17 @@ void MD5Importer::InternReadFile(const std::string &pFile,
} }
// make sure we have at least one file // make sure we have at least one file
if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) { if (!mHadMD5Mesh && !mHadMD5Anim && !mHadMD5Camera) {
throw DeadlyImportError("Failed to read valid contents out of this MD5* file"); throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
} }
// Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system // Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f, mScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f); 0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
// the output scene wouldn't pass the validation without this flag // the output scene wouldn't pass the validation without this flag
if (!bHadMD5Mesh) { if (!mHadMD5Mesh) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; mScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
} }
// clean the instance -- the BaseImporter instance may be reused later. // clean the instance -- the BaseImporter instance may be reused later.
@ -181,17 +187,17 @@ void MD5Importer::LoadFileIntoMemory(IOStream *file) {
// unload the previous buffer, if any // unload the previous buffer, if any
UnloadFileFromMemory(); UnloadFileFromMemory();
ai_assert(NULL != file); ai_assert(nullptr != file);
fileSize = (unsigned int)file->FileSize(); mFileSize = (unsigned int)file->FileSize();
ai_assert(fileSize); ai_assert(mFileSize);
// 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
mBuffer = new char[fileSize + 1]; mBuffer = new char[mFileSize + 1];
file->Read((void *)mBuffer, 1, fileSize); file->Read((void *)mBuffer, 1, mFileSize);
iLineNumber = 1; mLineNumber = 1;
// append a terminal 0 // append a terminal 0
mBuffer[fileSize] = '\0'; mBuffer[mFileSize] = '\0';
// now remove all line comments from the file // now remove all line comments from the file
CommentRemover::RemoveLineComments("//", mBuffer, ' '); CommentRemover::RemoveLineComments("//", mBuffer, ' ');
@ -202,8 +208,8 @@ void MD5Importer::LoadFileIntoMemory(IOStream *file) {
void MD5Importer::UnloadFileFromMemory() { void MD5Importer::UnloadFileFromMemory() {
// delete the file buffer // delete the file buffer
delete[] mBuffer; delete[] mBuffer;
mBuffer = NULL; mBuffer = nullptr;
fileSize = 0; mFileSize = 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -243,7 +249,8 @@ void MD5Importer::MakeDataUnique(MD5::MeshDesc &meshSrc) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5MESH // Recursive node graph construction from a MD5MESH
void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) { void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &bones) {
ai_assert(NULL != piParent && !piParent->mNumChildren); ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
// First find out how many children we'll have // First find out how many children we'll have
for (int i = 0; i < (int)bones.size(); ++i) { for (int i = 0; i < (int)bones.size(); ++i) {
@ -293,7 +300,8 @@ void MD5Importer::AttachChilds_Mesh(int iParentID, aiNode *piParent, BoneList &b
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursive node graph construction from a MD5ANIM // Recursive node graph construction from a MD5ANIM
void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) { void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneList &bones, const aiNodeAnim **node_anims) {
ai_assert(NULL != piParent && !piParent->mNumChildren); ai_assert(nullptr != piParent);
ai_assert(!piParent->mNumChildren);
// First find out how many children we'll have // First find out how many children we'll have
for (int i = 0; i < (int)bones.size(); ++i) { for (int i = 0; i < (int)bones.size(); ++i) {
@ -332,37 +340,37 @@ void MD5Importer::AttachChilds_Anim(int iParentID, aiNode *piParent, AnimBoneLis
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Load a MD5MESH file // Load a MD5MESH file
void MD5Importer::LoadMD5MeshFile() { void MD5Importer::LoadMD5MeshFile() {
std::string pFile = mFile + "md5mesh"; std::string filename = mFile + "md5mesh";
std::unique_ptr<IOStream> file(mIOHandler->Open(pFile, "rb")); std::unique_ptr<IOStream> file(mIOHandler->Open(filename, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if (file.get() == nullptr || !file->FileSize()) { if (file.get() == nullptr || !file->FileSize()) {
ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + pFile); ASSIMP_LOG_WARN("Failed to access MD5MESH file: " + filename);
return; return;
} }
bHadMD5Mesh = true; mHadMD5Mesh = true;
LoadFileIntoMemory(file.get()); LoadFileIntoMemory(file.get());
// now construct a parser and parse the file // now construct a parser and parse the file
MD5::MD5Parser parser(mBuffer, fileSize); MD5::MD5Parser parser(mBuffer, mFileSize);
// load the mesh information from it // load the mesh information from it
MD5::MD5MeshParser meshParser(parser.mSections); MD5::MD5MeshParser meshParser(parser.mSections);
// create the bone hierarchy - first the root node and dummy nodes for all meshes // create the bone hierarchy - first the root node and dummy nodes for all meshes
pScene->mRootNode = new aiNode("<MD5_Root>"); mScene->mRootNode = new aiNode("<MD5_Root>");
pScene->mRootNode->mNumChildren = 2; mScene->mRootNode->mNumChildren = 2;
pScene->mRootNode->mChildren = new aiNode *[2]; mScene->mRootNode->mChildren = new aiNode *[2];
// build the hierarchy from the MD5MESH file // build the hierarchy from the MD5MESH file
aiNode *pcNode = pScene->mRootNode->mChildren[1] = new aiNode(); aiNode *pcNode = mScene->mRootNode->mChildren[1] = new aiNode();
pcNode->mName.Set("<MD5_Hierarchy>"); pcNode->mName.Set("<MD5_Hierarchy>");
pcNode->mParent = pScene->mRootNode; pcNode->mParent = mScene->mRootNode;
AttachChilds_Mesh(-1, pcNode, meshParser.mJoints); AttachChilds_Mesh(-1, pcNode, meshParser.mJoints);
pcNode = pScene->mRootNode->mChildren[0] = new aiNode(); pcNode = mScene->mRootNode->mChildren[0] = new aiNode();
pcNode->mName.Set("<MD5_Mesh>"); pcNode->mName.Set("<MD5_Mesh>");
pcNode->mParent = pScene->mRootNode; pcNode->mParent = mScene->mRootNode;
#if 0 #if 0
if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */ if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */
@ -371,28 +379,31 @@ void MD5Importer::LoadMD5MeshFile() {
// FIX: MD5 files exported from Blender can have empty meshes // FIX: MD5 files exported from Blender can have empty meshes
for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) { for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) if (!(*it).mFaces.empty() && !(*it).mVertices.empty()) {
++pScene->mNumMaterials; ++mScene->mNumMaterials;
}
} }
// generate all meshes // generate all meshes
pScene->mNumMeshes = pScene->mNumMaterials; mScene->mNumMeshes = mScene->mNumMaterials;
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes]; mScene->mMeshes = new aiMesh *[mScene->mNumMeshes];
pScene->mMaterials = new aiMaterial *[pScene->mNumMeshes]; mScene->mMaterials = new aiMaterial *[mScene->mNumMeshes];
// storage for node mesh indices // storage for node mesh indices
pcNode->mNumMeshes = pScene->mNumMeshes; pcNode->mNumMeshes = mScene->mNumMeshes;
pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes]; pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) for (unsigned int m = 0; m < pcNode->mNumMeshes; ++m) {
pcNode->mMeshes[m] = m; pcNode->mMeshes[m] = m;
}
unsigned int n = 0; unsigned int n = 0;
for (std::vector<MD5::MeshDesc>::iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) { for (std::vector<MD5::MeshDesc>::iterator it = meshParser.mMeshes.begin(), end = meshParser.mMeshes.end(); it != end; ++it) {
MD5::MeshDesc &meshSrc = *it; MD5::MeshDesc &meshSrc = *it;
if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty()) if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty()) {
continue; continue;
}
aiMesh *mesh = pScene->mMeshes[n] = new aiMesh(); aiMesh *mesh = mScene->mMeshes[n] = new aiMesh();
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// generate unique vertices in our internal verbose format // generate unique vertices in our internal verbose format
@ -422,17 +433,19 @@ void MD5Importer::LoadMD5MeshFile() {
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) { for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w]; MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
/* FIX for some invalid exporters */ /* FIX for some invalid exporters */
if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON)) if (!(weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON)) {
++piCount[weightDesc.mBone]; ++piCount[weightDesc.mBone];
}
} }
} }
// check how many we will need // check how many we will need
for (unsigned int p = 0; p < meshParser.mJoints.size(); ++p) for (unsigned int p = 0; p < meshParser.mJoints.size(); ++p) {
if (piCount[p]) mesh->mNumBones++; if (piCount[p]) mesh->mNumBones++;
}
if (mesh->mNumBones) // just for safety // just for safety
{ if (mesh->mNumBones) {
mesh->mBones = new aiBone *[mesh->mNumBones]; mesh->mBones = new aiBone *[mesh->mNumBones];
for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) { for (unsigned int q = 0, h = 0; q < meshParser.mJoints.size(); ++q) {
if (!piCount[q]) continue; if (!piCount[q]) continue;
@ -457,8 +470,9 @@ void MD5Importer::LoadMD5MeshFile() {
// there are models which have weights which don't sum to 1 ... // there are models which have weights which don't sum to 1 ...
ai_real fSum = 0.0; ai_real fSum = 0.0;
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
fSum += meshSrc.mWeights[w].mWeight; fSum += meshSrc.mWeights[w].mWeight;
}
if (!fSum) { if (!fSum) {
ASSIMP_LOG_ERROR("MD5MESH: The sum of all vertex bone weights is 0"); ASSIMP_LOG_ERROR("MD5MESH: The sum of all vertex bone weights is 0");
continue; continue;
@ -466,11 +480,12 @@ void MD5Importer::LoadMD5MeshFile() {
// process bone weights // process bone weights
for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) { for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights; ++w) {
if (w >= meshSrc.mWeights.size()) if (w >= meshSrc.mWeights.size()) {
throw DeadlyImportError("MD5MESH: Invalid weight index"); throw DeadlyImportError("MD5MESH: Invalid weight index");
}
MD5::WeightDesc &weightDesc = meshSrc.mWeights[w]; MD5::WeightDesc &weightDesc = meshSrc.mWeights[w];
if (weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON) { if (weightDesc.mWeight < AI_MD5_WEIGHT_EPSILON && weightDesc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
continue; continue;
} }
@ -504,12 +519,12 @@ void MD5Importer::LoadMD5MeshFile() {
for (unsigned int c = 0; c < mesh->mNumFaces; ++c) { for (unsigned int c = 0; c < mesh->mNumFaces; ++c) {
mesh->mFaces[c].mNumIndices = 3; mesh->mFaces[c].mNumIndices = 3;
mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices; mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
meshSrc.mFaces[c].mIndices = NULL; meshSrc.mFaces[c].mIndices = nullptr;
} }
// generate a material for the mesh // generate a material for the mesh
aiMaterial *mat = new aiMaterial(); aiMaterial *mat = new aiMaterial();
pScene->mMaterials[n] = mat; mScene->mMaterials[n] = mat;
// insert the typical doom3 textures: // insert the typical doom3 textures:
// nnn_local.tga - normal map // nnn_local.tga - normal map
@ -555,10 +570,11 @@ void MD5Importer::LoadMD5AnimFile() {
ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile); ASSIMP_LOG_WARN("Failed to read MD5ANIM file: " + pFile);
return; return;
} }
LoadFileIntoMemory(file.get()); LoadFileIntoMemory(file.get());
// parse the basic file structure // parse the basic file structure
MD5::MD5Parser parser(mBuffer, fileSize); MD5::MD5Parser parser(mBuffer, mFileSize);
// load the animation information from the parse tree // load the animation information from the parse tree
MD5::MD5AnimParser animParser(parser.mSections); MD5::MD5AnimParser animParser(parser.mSections);
@ -568,10 +584,10 @@ void MD5Importer::LoadMD5AnimFile() {
animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) { animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded"); ASSIMP_LOG_ERROR("MD5ANIM: No frames or animated bones loaded");
} else { } else {
bHadMD5Anim = true; mHadMD5Anim = true;
pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations = 1]; mScene->mAnimations = new aiAnimation *[mScene->mNumAnimations = 1];
aiAnimation *anim = pScene->mAnimations[0] = new aiAnimation(); aiAnimation *anim = mScene->mAnimations[0] = new aiAnimation();
anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size(); anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size();
anim->mChannels = new aiNodeAnim *[anim->mNumChannels]; anim->mChannels = new aiNodeAnim *[anim->mNumChannels];
for (unsigned int i = 0; i < anim->mNumChannels; ++i) { for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
@ -637,15 +653,15 @@ void MD5Importer::LoadMD5AnimFile() {
// If we didn't build the hierarchy yet (== we didn't load a MD5MESH), // If we didn't build the hierarchy yet (== we didn't load a MD5MESH),
// construct it now from the data given in the MD5ANIM. // construct it now from the data given in the MD5ANIM.
if (!pScene->mRootNode) { if (!mScene->mRootNode) {
pScene->mRootNode = new aiNode(); mScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("<MD5_Hierarchy>"); mScene->mRootNode->mName.Set("<MD5_Hierarchy>");
AttachChilds_Anim(-1, pScene->mRootNode, animParser.mAnimatedBones, (const aiNodeAnim **)anim->mChannels); AttachChilds_Anim(-1, mScene->mRootNode, animParser.mAnimatedBones, (const aiNodeAnim **)anim->mChannels);
// Call SkeletonMeshBuilder to construct a mesh to represent the shape // Call SkeletonMeshBuilder to construct a mesh to represent the shape
if (pScene->mRootNode->mNumChildren) { if (mScene->mRootNode->mNumChildren) {
SkeletonMeshBuilder skeleton_maker(pScene, pScene->mRootNode->mChildren[0]); SkeletonMeshBuilder skeleton_maker(mScene, mScene->mRootNode->mChildren[0]);
} }
} }
} }
@ -661,11 +677,11 @@ void MD5Importer::LoadMD5CameraFile() {
if (!file.get() || !file->FileSize()) { if (!file.get() || !file->FileSize()) {
throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile); throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
} }
bHadMD5Camera = true; mHadMD5Camera = true;
LoadFileIntoMemory(file.get()); LoadFileIntoMemory(file.get());
// parse the basic file structure // parse the basic file structure
MD5::MD5Parser parser(mBuffer, fileSize); MD5::MD5Parser parser(mBuffer, mFileSize);
// load the camera animation data from the parse tree // load the camera animation data from the parse tree
MD5::MD5CameraParser cameraParser(parser.mSections); MD5::MD5CameraParser cameraParser(parser.mSections);
@ -679,14 +695,14 @@ void MD5Importer::LoadMD5CameraFile() {
// Construct output graph - a simple root with a dummy child. // Construct output graph - a simple root with a dummy child.
// The root node performs the coordinate system conversion // The root node performs the coordinate system conversion
aiNode *root = pScene->mRootNode = new aiNode("<MD5CameraRoot>"); aiNode *root = mScene->mRootNode = new aiNode("<MD5CameraRoot>");
root->mChildren = new aiNode *[root->mNumChildren = 1]; root->mChildren = new aiNode *[root->mNumChildren = 1];
root->mChildren[0] = new aiNode("<MD5Camera>"); root->mChildren[0] = new aiNode("<MD5Camera>");
root->mChildren[0]->mParent = root; root->mChildren[0]->mParent = root;
// ... but with one camera assigned to it // ... but with one camera assigned to it
pScene->mCameras = new aiCamera *[pScene->mNumCameras = 1]; mScene->mCameras = new aiCamera *[mScene->mNumCameras = 1];
aiCamera *cam = pScene->mCameras[0] = new aiCamera(); aiCamera *cam = mScene->mCameras[0] = new aiCamera();
cam->mName = "<MD5Camera>"; cam->mName = "<MD5Camera>";
// FIXME: Fov is currently set to the first frame's value // FIXME: Fov is currently set to the first frame's value
@ -703,8 +719,8 @@ void MD5Importer::LoadMD5CameraFile() {
cuts.push_back(static_cast<unsigned int>(frames.size() - 1)); cuts.push_back(static_cast<unsigned int>(frames.size() - 1));
} }
pScene->mNumAnimations = static_cast<unsigned int>(cuts.size() - 1); mScene->mNumAnimations = static_cast<unsigned int>(cuts.size() - 1);
aiAnimation **tmp = pScene->mAnimations = new aiAnimation *[pScene->mNumAnimations]; aiAnimation **tmp = mScene->mAnimations = new aiAnimation *[mScene->mNumAnimations];
for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end() - 1; ++it) { for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end() - 1; ++it) {
aiAnimation *anim = *tmp++ = new aiAnimation(); aiAnimation *anim = *tmp++ = new aiAnimation();

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, 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,
@ -156,25 +155,25 @@ protected:
char *mBuffer; char *mBuffer;
/** Size of the file */ /** Size of the file */
unsigned int fileSize; unsigned int mFileSize;
/** Current line number. For debugging purposes */ /** Current line number. For debugging purposes */
unsigned int iLineNumber; unsigned int mLineNumber;
/** Scene to be filled */ /** Scene to be filled */
aiScene *pScene; aiScene *mScene;
/** true if a MD5MESH file has already been parsed */ /** true if a MD5MESH file has already been parsed */
bool bHadMD5Mesh; bool mHadMD5Mesh;
/** true if a MD5ANIM file has already been parsed */ /** true if a MD5ANIM file has already been parsed */
bool bHadMD5Anim; bool mHadMD5Anim;
/** true if a MD5CAMERA file has already been parsed */ /** true if a MD5CAMERA file has already been parsed */
bool bHadMD5Camera; bool mHadMD5Camera;
/** configuration option: prevent anim autoload */ /** configuration option: prevent anim autoload */
bool configNoAutoLoad; bool mCconfigNoAutoLoad;
}; };
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -45,25 +45,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the MD5 parser class * @brief Implementation of the MD5 parser class
*/ */
// internal headers // internal headers
#include "AssetLib/MD5/MD5Loader.h" #include "AssetLib/MD5/MD5Loader.h"
#include "Material/MaterialSystem.h" #include "Material/MaterialSystem.h"
#include <assimp/fast_atof.h>
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/fast_atof.h>
#include <assimp/mesh.h> #include <assimp/mesh.h>
#include <assimp/DefaultLogger.hpp>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::MD5; using namespace Assimp::MD5;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Parse the segment structure fo a MD5 file // Parse the segment structure fo a MD5 file
MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize ) MD5Parser::MD5Parser(char *_buffer, unsigned int _fileSize) {
{ ai_assert(nullptr != _buffer);
ai_assert(NULL != _buffer && 0 != _fileSize); ai_assert(0 != _fileSize);
buffer = _buffer; buffer = _buffer;
fileSize = _fileSize; fileSize = _fileSize;
@ -78,48 +77,45 @@ MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
bool running = true; bool running = true;
while (running) { while (running) {
mSections.push_back(Section()); mSections.push_back(Section());
Section& sec = mSections.back(); Section &sec = mSections.back();
if(!ParseSection(sec)) { if (!ParseSection(sec)) {
break; break;
} }
} }
if ( !DefaultLogger::isNullLogger()) { if (!DefaultLogger::isNullLogger()) {
char szBuffer[128]; // should be sufficiently large char szBuffer[128]; // should be sufficiently large
::ai_snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size()); ::ai_snprintf(szBuffer, 128, "MD5Parser end. Parsed %i sections", (int)mSections.size());
ASSIMP_LOG_DEBUG(szBuffer); ASSIMP_LOG_DEBUG(szBuffer);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Report error to the log stream // Report error to the log stream
/*static*/ AI_WONT_RETURN void MD5Parser::ReportError (const char* error, unsigned int line) /*static*/ AI_WONT_RETURN void MD5Parser::ReportError(const char *error, unsigned int line) {
{
char szBuffer[1024]; char szBuffer[1024];
::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s",line,error); ::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s", line, error);
throw DeadlyImportError(szBuffer); throw DeadlyImportError(szBuffer);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Report warning to the log stream // Report warning to the log stream
/*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line) /*static*/ void MD5Parser::ReportWarning(const char *warn, unsigned int line) {
{
char szBuffer[1024]; char szBuffer[1024];
::sprintf(szBuffer,"[MD5] Line %u: %s",line,warn); ::sprintf(szBuffer, "[MD5] Line %u: %s", line, warn);
ASSIMP_LOG_WARN(szBuffer); ASSIMP_LOG_WARN(szBuffer);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Parse and validate the MD5 header // Parse and validate the MD5 header
void MD5Parser::ParseHeader() void MD5Parser::ParseHeader() {
{
// parse and validate the file version // parse and validate the file version
SkipSpaces(); SkipSpaces();
if (!TokenMatch(buffer,"MD5Version",10)) { if (!TokenMatch(buffer, "MD5Version", 10)) {
ReportError("Invalid MD5 file: MD5Version tag has not been found"); ReportError("Invalid MD5 file: MD5Version tag has not been found");
} }
SkipSpaces(); SkipSpaces();
unsigned int iVer = ::strtoul10(buffer,(const char**)&buffer); unsigned int iVer = ::strtoul10(buffer, (const char **)&buffer);
if (10 != iVer) { if (10 != iVer) {
ReportError("MD5 version tag is unknown (10 is expected)"); ReportError("MD5 version tag is unknown (10 is expected)");
} }
@ -127,23 +123,24 @@ void MD5Parser::ParseHeader()
// print the command line options to the console // print the command line options to the console
// FIX: can break the log length limit, so we need to be careful // FIX: can break the log length limit, so we need to be careful
char* sz = buffer; char *sz = buffer;
while (!IsLineEnd( *buffer++)); while (!IsLineEnd(*buffer++))
ASSIMP_LOG_INFO(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz)))); ;
ASSIMP_LOG_INFO(std::string(sz, std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer - sz))));
SkipSpacesAndLineEnd(); SkipSpacesAndLineEnd();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursive MD5 parsing function // Recursive MD5 parsing function
bool MD5Parser::ParseSection(Section& out) bool MD5Parser::ParseSection(Section &out) {
{
// store the current line number for use in error messages // store the current line number for use in error messages
out.iLineNumber = lineNumber; out.iLineNumber = lineNumber;
// first parse the name of the section // first parse the name of the section
char* sz = buffer; char *sz = buffer;
while (!IsSpaceOrNewLine( *buffer))buffer++; while (!IsSpaceOrNewLine(*buffer))
out.mName = std::string(sz,(uintptr_t)(buffer-sz)); buffer++;
out.mName = std::string(sz, (uintptr_t)(buffer - sz));
SkipSpaces(); SkipSpaces();
bool running = true; bool running = true;
@ -152,8 +149,7 @@ bool MD5Parser::ParseSection(Section& out)
// it is a normal section so read all lines // it is a normal section so read all lines
buffer++; buffer++;
bool run = true; bool run = true;
while (run) while (run) {
{
if (!SkipSpacesAndLineEnd()) { if (!SkipSpacesAndLineEnd()) {
return false; // seems this was the last section return false; // seems this was the last section
} }
@ -163,25 +159,26 @@ bool MD5Parser::ParseSection(Section& out)
} }
out.mElements.push_back(Element()); out.mElements.push_back(Element());
Element& elem = out.mElements.back(); Element &elem = out.mElements.back();
elem.iLineNumber = lineNumber; elem.iLineNumber = lineNumber;
elem.szStart = buffer; elem.szStart = buffer;
// terminate the line with zero // terminate the line with zero
while (!IsLineEnd( *buffer))buffer++; while (!IsLineEnd(*buffer))
buffer++;
if (*buffer) { if (*buffer) {
++lineNumber; ++lineNumber;
*buffer++ = '\0'; *buffer++ = '\0';
} }
} }
break; break;
} } else if (!IsSpaceOrNewLine(*buffer)) {
else if (!IsSpaceOrNewLine(*buffer)) {
// it is an element at global scope. Parse its value and go on // it is an element at global scope. Parse its value and go on
sz = buffer; sz = buffer;
while (!IsSpaceOrNewLine( *buffer++)); while (!IsSpaceOrNewLine(*buffer++))
out.mGlobalValue = std::string(sz,(uintptr_t)(buffer-sz)); ;
out.mGlobalValue = std::string(sz, (uintptr_t)(buffer - sz));
continue; continue;
} }
break; break;
@ -193,161 +190,161 @@ bool MD5Parser::ParseSection(Section& out)
// Some dirty macros just because they're so funny and easy to debug // Some dirty macros just because they're so funny and easy to debug
// skip all spaces ... handle EOL correctly // skip all spaces ... handle EOL correctly
#define AI_MD5_SKIP_SPACES() if(!SkipSpaces(&sz)) \ #define AI_MD5_SKIP_SPACES() \
MD5Parser::ReportWarning("Unexpected end of line",elem.iLineNumber); if (!SkipSpaces(&sz)) \
MD5Parser::ReportWarning("Unexpected end of line", elem.iLineNumber);
// read a triple float in brackets: (1.0 1.0 1.0) // read a triple float in brackets: (1.0 1.0 1.0)
#define AI_MD5_READ_TRIPLE(vec) \ #define AI_MD5_READ_TRIPLE(vec) \
AI_MD5_SKIP_SPACES(); \ AI_MD5_SKIP_SPACES(); \
if ('(' != *sz++) \ if ('(' != *sz++) \
MD5Parser::ReportWarning("Unexpected token: ( was expected",elem.iLineNumber); \ MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber); \
AI_MD5_SKIP_SPACES(); \ AI_MD5_SKIP_SPACES(); \
sz = fast_atoreal_move<float>(sz,(float&)vec.x); \ sz = fast_atoreal_move<float>(sz, (float &)vec.x); \
AI_MD5_SKIP_SPACES(); \ AI_MD5_SKIP_SPACES(); \
sz = fast_atoreal_move<float>(sz,(float&)vec.y); \ sz = fast_atoreal_move<float>(sz, (float &)vec.y); \
AI_MD5_SKIP_SPACES(); \ AI_MD5_SKIP_SPACES(); \
sz = fast_atoreal_move<float>(sz,(float&)vec.z); \ sz = fast_atoreal_move<float>(sz, (float &)vec.z); \
AI_MD5_SKIP_SPACES(); \ AI_MD5_SKIP_SPACES(); \
if (')' != *sz++) \ if (')' != *sz++) \
MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber); MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
// parse a string, enclosed in quotation marks or not // parse a string, enclosed in quotation marks or not
#define AI_MD5_PARSE_STRING(out) \ #define AI_MD5_PARSE_STRING(out) \
bool bQuota = (*sz == '\"'); \ bool bQuota = (*sz == '\"'); \
const char* szStart = sz; \ const char *szStart = sz; \
while (!IsSpaceOrNewLine(*sz))++sz; \ while (!IsSpaceOrNewLine(*sz)) \
const char* szEnd = sz; \ ++sz; \
if (bQuota) { \ const char *szEnd = sz; \
szStart++; \ if (bQuota) { \
if ('\"' != *(szEnd-=1)) { \ szStart++; \
if ('\"' != *(szEnd -= 1)) { \
MD5Parser::ReportWarning("Expected closing quotation marks in string", \ MD5Parser::ReportWarning("Expected closing quotation marks in string", \
elem.iLineNumber); \ elem.iLineNumber); \
continue; \ continue; \
} \ } \
} \ } \
out.length = (size_t)(szEnd - szStart); \ out.length = (size_t)(szEnd - szStart); \
::memcpy(out.data,szStart,out.length); \ ::memcpy(out.data, szStart, out.length); \
out.data[out.length] = '\0'; out.data[out.length] = '\0';
// parse a string, enclosed in quotation marks // parse a string, enclosed in quotation marks
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \ #define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
while('\"'!=*sz)++sz; \ while ('\"' != *sz) \
const char* szStart = ++sz; \ ++sz; \
while('\"'!=*sz)++sz; \ const char *szStart = ++sz; \
const char* szEnd = (sz++); \ while ('\"' != *sz) \
out.length = (ai_uint32) (szEnd - szStart); \ ++sz; \
::memcpy(out.data,szStart,out.length); \ const char *szEnd = (sz++); \
out.length = (ai_uint32)(szEnd - szStart); \
::memcpy(out.data, szStart, out.length); \
out.data[out.length] = '\0'; out.data[out.length] = '\0';
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// .MD5MESH parsing function // .MD5MESH parsing function
MD5MeshParser::MD5MeshParser(SectionList& mSections) MD5MeshParser::MD5MeshParser(SectionList &mSections) {
{
ASSIMP_LOG_DEBUG("MD5MeshParser begin"); ASSIMP_LOG_DEBUG("MD5MeshParser begin");
// now parse all sections // now parse all sections
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){ for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ( (*iter).mName == "numMeshes") { if ((*iter).mName == "numMeshes") {
mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str())); mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
} } else if ((*iter).mName == "numJoints") {
else if ( (*iter).mName == "numJoints") {
mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str())); mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
} } else if ((*iter).mName == "joints") {
else if ((*iter).mName == "joints") {
// "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 ) // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
for (const auto & elem : (*iter).mElements){ for (const auto &elem : (*iter).mElements) {
mJoints.push_back(BoneDesc()); mJoints.push_back(BoneDesc());
BoneDesc& desc = mJoints.back(); BoneDesc &desc = mJoints.back();
const char* sz = elem.szStart; const char *sz = elem.szStart;
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName); AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
// negative values, at least -1, is allowed here // negative values, at least -1, is allowed here
desc.mParentIndex = (int)strtol10(sz,&sz); desc.mParentIndex = (int)strtol10(sz, &sz);
AI_MD5_READ_TRIPLE(desc.mPositionXYZ); AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
} }
} } else if ((*iter).mName == "mesh") {
else if ((*iter).mName == "mesh") {
mMeshes.push_back(MeshDesc()); mMeshes.push_back(MeshDesc());
MeshDesc& desc = mMeshes.back(); MeshDesc &desc = mMeshes.back();
for (const auto & elem : (*iter).mElements){ for (const auto &elem : (*iter).mElements) {
const char* sz = elem.szStart; const char *sz = elem.szStart;
// shader attribute // shader attribute
if (TokenMatch(sz,"shader",6)) { if (TokenMatch(sz, "shader", 6)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader); AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
} }
// numverts attribute // numverts attribute
else if (TokenMatch(sz,"numverts",8)) { else if (TokenMatch(sz, "numverts", 8)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
desc.mVertices.resize(strtoul10(sz)); desc.mVertices.resize(strtoul10(sz));
} }
// numtris attribute // numtris attribute
else if (TokenMatch(sz,"numtris",7)) { else if (TokenMatch(sz, "numtris", 7)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
desc.mFaces.resize(strtoul10(sz)); desc.mFaces.resize(strtoul10(sz));
} }
// numweights attribute // numweights attribute
else if (TokenMatch(sz,"numweights",10)) { else if (TokenMatch(sz, "numweights", 10)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
desc.mWeights.resize(strtoul10(sz)); desc.mWeights.resize(strtoul10(sz));
} }
// vert attribute // vert attribute
// "vert 0 ( 0.394531 0.513672 ) 0 1" // "vert 0 ( 0.394531 0.513672 ) 0 1"
else if (TokenMatch(sz,"vert",4)) { else if (TokenMatch(sz, "vert", 4)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
const unsigned int idx = ::strtoul10(sz,&sz); const unsigned int idx = ::strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
if (idx >= desc.mVertices.size()) if (idx >= desc.mVertices.size())
desc.mVertices.resize(idx+1); desc.mVertices.resize(idx + 1);
VertexDesc& vert = desc.mVertices[idx]; VertexDesc &vert = desc.mVertices[idx];
if ('(' != *sz++) if ('(' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ( was expected",elem.iLineNumber); MD5Parser::ReportWarning("Unexpected token: ( was expected", elem.iLineNumber);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.x); sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.x);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.y); sz = fast_atoreal_move<float>(sz, (float &)vert.mUV.y);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
if (')' != *sz++) if (')' != *sz++)
MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber); MD5Parser::ReportWarning("Unexpected token: ) was expected", elem.iLineNumber);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
vert.mFirstWeight = ::strtoul10(sz,&sz); vert.mFirstWeight = ::strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
vert.mNumWeights = ::strtoul10(sz,&sz); vert.mNumWeights = ::strtoul10(sz, &sz);
} }
// tri attribute // tri attribute
// "tri 0 15 13 12" // "tri 0 15 13 12"
else if (TokenMatch(sz,"tri",3)) { else if (TokenMatch(sz, "tri", 3)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
const unsigned int idx = strtoul10(sz,&sz); const unsigned int idx = strtoul10(sz, &sz);
if (idx >= desc.mFaces.size()) if (idx >= desc.mFaces.size())
desc.mFaces.resize(idx+1); desc.mFaces.resize(idx + 1);
aiFace& face = desc.mFaces[idx]; aiFace &face = desc.mFaces[idx];
face.mIndices = new unsigned int[face.mNumIndices = 3]; face.mIndices = new unsigned int[face.mNumIndices = 3];
for (unsigned int i = 0; i < 3;++i) { for (unsigned int i = 0; i < 3; ++i) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
face.mIndices[i] = strtoul10(sz,&sz); face.mIndices[i] = strtoul10(sz, &sz);
} }
} }
// weight attribute // weight attribute
// "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )" // "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
else if (TokenMatch(sz,"weight",6)) { else if (TokenMatch(sz, "weight", 6)) {
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
const unsigned int idx = strtoul10(sz,&sz); const unsigned int idx = strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
if (idx >= desc.mWeights.size()) if (idx >= desc.mWeights.size())
desc.mWeights.resize(idx+1); desc.mWeights.resize(idx + 1);
WeightDesc& weight = desc.mWeights[idx]; WeightDesc &weight = desc.mWeights[idx];
weight.mBone = strtoul10(sz,&sz); weight.mBone = strtoul10(sz, &sz);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
sz = fast_atoreal_move<float>(sz,weight.mWeight); sz = fast_atoreal_move<float>(sz, weight.mWeight);
AI_MD5_READ_TRIPLE(weight.vOffsetPosition); AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
} }
} }
@ -358,57 +355,54 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// .MD5ANIM parsing function // .MD5ANIM parsing function
MD5AnimParser::MD5AnimParser(SectionList& mSections) MD5AnimParser::MD5AnimParser(SectionList &mSections) {
{
ASSIMP_LOG_DEBUG("MD5AnimParser begin"); ASSIMP_LOG_DEBUG("MD5AnimParser begin");
fFrameRate = 24.0f; fFrameRate = 24.0f;
mNumAnimatedComponents = UINT_MAX; mNumAnimatedComponents = UINT_MAX;
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) { for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "hierarchy") { if ((*iter).mName == "hierarchy") {
// "sheath" 0 63 6 // "sheath" 0 63 6
for (const auto & elem : (*iter).mElements) { for (const auto &elem : (*iter).mElements) {
mAnimatedBones.push_back ( AnimBoneDesc () ); mAnimatedBones.push_back(AnimBoneDesc());
AnimBoneDesc& desc = mAnimatedBones.back(); AnimBoneDesc &desc = mAnimatedBones.back();
const char* sz = elem.szStart; const char *sz = elem.szStart;
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName); AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
// parent index - negative values are allowed (at least -1) // parent index - negative values are allowed (at least -1)
desc.mParentIndex = ::strtol10(sz,&sz); desc.mParentIndex = ::strtol10(sz, &sz);
// flags (highest is 2^6-1) // flags (highest is 2^6-1)
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
if(63 < (desc.iFlags = ::strtoul10(sz,&sz))){ if (63 < (desc.iFlags = ::strtoul10(sz, &sz))) {
MD5Parser::ReportWarning("Invalid flag combination in hierarchy section",elem.iLineNumber); MD5Parser::ReportWarning("Invalid flag combination in hierarchy section", elem.iLineNumber);
} }
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
// index of the first animation keyframe component for this joint // index of the first animation keyframe component for this joint
desc.iFirstKeyIndex = ::strtoul10(sz,&sz); desc.iFirstKeyIndex = ::strtoul10(sz, &sz);
} }
} } else if ((*iter).mName == "baseframe") {
else if((*iter).mName == "baseframe") {
// ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 ) // ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
for (const auto & elem : (*iter).mElements) { for (const auto &elem : (*iter).mElements) {
const char* sz = elem.szStart; const char *sz = elem.szStart;
mBaseFrames.push_back ( BaseFrameDesc () ); mBaseFrames.push_back(BaseFrameDesc());
BaseFrameDesc& desc = mBaseFrames.back(); BaseFrameDesc &desc = mBaseFrames.back();
AI_MD5_READ_TRIPLE(desc.vPositionXYZ); AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
AI_MD5_READ_TRIPLE(desc.vRotationQuat); AI_MD5_READ_TRIPLE(desc.vRotationQuat);
} }
} } else if ((*iter).mName == "frame") {
else if((*iter).mName == "frame") {
if (!(*iter).mGlobalValue.length()) { if (!(*iter).mGlobalValue.length()) {
MD5Parser::ReportWarning("A frame section must have a frame index",(*iter).iLineNumber); MD5Parser::ReportWarning("A frame section must have a frame index", (*iter).iLineNumber);
continue; continue;
} }
mFrames.push_back ( FrameDesc () ); mFrames.push_back(FrameDesc());
FrameDesc& desc = mFrames.back(); FrameDesc &desc = mFrames.back();
desc.iIndex = strtoul10((*iter).mGlobalValue.c_str()); desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
// we do already know how much storage we will presumably need // we do already know how much storage we will presumably need
@ -417,31 +411,28 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
} }
// now read all elements (continuous list of floats) // now read all elements (continuous list of floats)
for (const auto & elem : (*iter).mElements){ for (const auto &elem : (*iter).mElements) {
const char* sz = elem.szStart; const char *sz = elem.szStart;
while (SkipSpacesAndLineEnd(&sz)) { while (SkipSpacesAndLineEnd(&sz)) {
float f;sz = fast_atoreal_move<float>(sz,f); float f;
sz = fast_atoreal_move<float>(sz, f);
desc.mValues.push_back(f); desc.mValues.push_back(f);
} }
} }
} } else if ((*iter).mName == "numFrames") {
else if((*iter).mName == "numFrames") {
mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str())); mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
} } else if ((*iter).mName == "numJoints") {
else if((*iter).mName == "numJoints") {
const unsigned int num = strtoul10((*iter).mGlobalValue.c_str()); const unsigned int num = strtoul10((*iter).mGlobalValue.c_str());
mAnimatedBones.reserve(num); mAnimatedBones.reserve(num);
// try to guess the number of animated components if that element is not given // try to guess the number of animated components if that element is not given
if (UINT_MAX == mNumAnimatedComponents) { if (UINT_MAX == mNumAnimatedComponents) {
mNumAnimatedComponents = num * 6; mNumAnimatedComponents = num * 6;
} }
} } else if ((*iter).mName == "numAnimatedComponents") {
else if((*iter).mName == "numAnimatedComponents") { mAnimatedBones.reserve(strtoul10((*iter).mGlobalValue.c_str()));
mAnimatedBones.reserve( strtoul10((*iter).mGlobalValue.c_str())); } else if ((*iter).mName == "frameRate") {
} fast_atoreal_move<float>((*iter).mGlobalValue.c_str(), fFrameRate);
else if((*iter).mName == "frameRate") {
fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate);
} }
} }
ASSIMP_LOG_DEBUG("MD5AnimParser end"); ASSIMP_LOG_DEBUG("MD5AnimParser end");
@ -449,32 +440,27 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// .MD5CAMERA parsing function // .MD5CAMERA parsing function
MD5CameraParser::MD5CameraParser(SectionList& mSections) MD5CameraParser::MD5CameraParser(SectionList &mSections) {
{
ASSIMP_LOG_DEBUG("MD5CameraParser begin"); ASSIMP_LOG_DEBUG("MD5CameraParser begin");
fFrameRate = 24.0f; fFrameRate = 24.0f;
for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) { for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end(); iter != iterEnd; ++iter) {
if ((*iter).mName == "numFrames") { if ((*iter).mName == "numFrames") {
frames.reserve(strtoul10((*iter).mGlobalValue.c_str())); frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
} } else if ((*iter).mName == "frameRate") {
else if ((*iter).mName == "frameRate") { fFrameRate = fast_atof((*iter).mGlobalValue.c_str());
fFrameRate = fast_atof ((*iter).mGlobalValue.c_str()); } else if ((*iter).mName == "numCuts") {
}
else if ((*iter).mName == "numCuts") {
cuts.reserve(strtoul10((*iter).mGlobalValue.c_str())); cuts.reserve(strtoul10((*iter).mGlobalValue.c_str()));
} } else if ((*iter).mName == "cuts") {
else if ((*iter).mName == "cuts") { for (const auto &elem : (*iter).mElements) {
for (const auto & elem : (*iter).mElements){ cuts.push_back(strtoul10(elem.szStart) + 1);
cuts.push_back(strtoul10(elem.szStart)+1);
} }
} } else if ((*iter).mName == "camera") {
else if ((*iter).mName == "camera") { for (const auto &elem : (*iter).mElements) {
for (const auto & elem : (*iter).mElements){ const char *sz = elem.szStart;
const char* sz = elem.szStart;
frames.push_back(CameraAnimFrameDesc()); frames.push_back(CameraAnimFrameDesc());
CameraAnimFrameDesc& cur = frames.back(); CameraAnimFrameDesc &cur = frames.back();
AI_MD5_READ_TRIPLE(cur.vPositionXYZ); AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
AI_MD5_READ_TRIPLE(cur.vRotationQuat); AI_MD5_READ_TRIPLE(cur.vRotationQuat);
AI_MD5_SKIP_SPACES(); AI_MD5_SKIP_SPACES();
@ -484,4 +470,3 @@ MD5CameraParser::MD5CameraParser(SectionList& mSections)
} }
ASSIMP_LOG_DEBUG("MD5CameraParser end"); ASSIMP_LOG_DEBUG("MD5CameraParser end");
} }

View File

@ -267,7 +267,7 @@ void MDCImporter::InternReadFile(
// necessary that we don't crash if an exception occurs // necessary that we don't crash if an exception occurs
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) { for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
pScene->mMeshes[i] = NULL; pScene->mMeshes[i] = nullptr;
} }
// now read all surfaces // now read all surfaces
@ -347,8 +347,8 @@ void MDCImporter::InternReadFile(
#endif #endif
const MDC::CompressedVertex *pcCVerts = NULL; const MDC::CompressedVertex *pcCVerts = nullptr;
int16_t *mdcCompVert = NULL; int16_t *mdcCompVert = nullptr;
// access compressed frames for large frame numbers, but never for the first // access compressed frames for large frame numbers, but never for the first
if (this->configFrameID && pcSurface->ulNumCompFrames > 0) { if (this->configFrameID && pcSurface->ulNumCompFrames > 0) {
@ -359,7 +359,7 @@ void MDCImporter::InternReadFile(
pcSurface->ulOffsetCompVerts) + pcSurface->ulOffsetCompVerts) +
*mdcCompVert * pcSurface->ulNumVertices; *mdcCompVert * pcSurface->ulNumVertices;
} else } else
mdcCompVert = NULL; mdcCompVert = nullptr;
} }
// copy all faces // copy all faces

View File

@ -68,8 +68,8 @@ namespace Assimp {
namespace MDL { namespace MDL {
namespace HalfLife { namespace HalfLife {
#ifdef _WIN32 #if _MSC_VER > 1920
# pragma warning(disable : 4706) # pragma warning(disable : 4706)
#endif // _WIN32 #endif // _WIN32
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -829,7 +829,7 @@ void HL1MDLLoader::read_meshes() {
} }
} else { } else {
for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) { for (int faceIdx = 0; faceIdx < num_faces; ++faceIdx) {
if (i & 1) { if (faceIdx & 1) {
// Preserve winding order. // Preserve winding order.
mesh_faces.push_back(HL1MeshFace{ mesh_faces.push_back(HL1MeshFace{
tricmds[faceIdx + 1], tricmds[faceIdx + 1],

View File

@ -222,12 +222,14 @@ void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, unsigned
std::unique_ptr<IOStream> file(io_->Open(file_path)); std::unique_ptr<IOStream> file(io_->Open(file_path));
if (file.get() == NULL) if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + DefaultIOSystem::fileName(file_path) + "."); throw DeadlyImportError("Failed to open MDL file " + DefaultIOSystem::fileName(file_path) + ".");
}
const size_t file_size = file->FileSize(); const size_t file_size = file->FileSize();
if (file_size < sizeof(MDLFileHeader)) if (file_size < sizeof(MDLFileHeader)) {
throw DeadlyImportError("MDL file is too small."); throw DeadlyImportError("MDL file is too small.");
}
buffer = new unsigned char[1 + file_size]; buffer = new unsigned char[1 + file_size];
file->Read((void *)buffer, 1, file_size); file->Read((void *)buffer, 1, file_size);

View File

@ -278,7 +278,7 @@ void MDLImporter::SizeCheck(const void *szPos) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Just for debugging purposes // Just for debugging purposes
void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) { void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) {
ai_assert(NULL != szFile); ai_assert(nullptr != szFile);
if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) { if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) {
// remove a directory if there is one // remove a directory if there is one
const char *szFilePtr = ::strrchr(szFile, '\\'); const char *szFilePtr = ::strrchr(szFile, '\\');
@ -304,7 +304,7 @@ void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate a quake file header // Validate a quake file header
void MDLImporter::ValidateHeader_Quake1(const MDL::Header *pcHeader) { void MDLImporter::ValidateHeader_Quake1(const MDL::Header *pcHeader) {
// some values may not be NULL // some values may not be nullptr
if (!pcHeader->num_frames) if (!pcHeader->num_frames)
throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file"); throw DeadlyImportError("[Quake 1 MDL] There are no frames in the file");
@ -359,7 +359,7 @@ void FlipQuakeHeader(BE_NCONST MDL::Header *pcHeader) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a Quake 1 file // Read a Quake 1 file
void MDLImporter::InternReadFile_Quake1() { void MDLImporter::InternReadFile_Quake1() {
ai_assert(NULL != pScene); ai_assert(nullptr != pScene);
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer; BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
@ -548,7 +548,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
delete pScene->mTextures[0]; delete pScene->mTextures[0];
delete[] pScene->mTextures; delete[] pScene->mTextures;
pScene->mTextures = NULL; pScene->mTextures = nullptr;
pScene->mNumTextures = 0; pScene->mNumTextures = 0;
} else { } else {
clr.b = clr.a = clr.g = clr.r = 1.0f; clr.b = clr.a = clr.g = clr.r = 1.0f;
@ -572,7 +572,7 @@ void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a MDL 3,4,5 file // Read a MDL 3,4,5 file
void MDLImporter::InternReadFile_3DGS_MDL345() { void MDLImporter::InternReadFile_3DGS_MDL345() {
ai_assert(NULL != pScene); ai_assert(nullptr != pScene);
// the header of MDL 3/4/5 is nearly identical to the original Quake1 header // the header of MDL 3/4/5 is nearly identical to the original Quake1 header
BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer; BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header *)this->mBuffer;
@ -791,7 +791,7 @@ void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
aiVector3D &vOut, aiVector3D &vOut,
const MDL::TexCoord_MDL3 *pcSrc, const MDL::TexCoord_MDL3 *pcSrc,
unsigned int iIndex) { unsigned int iIndex) {
ai_assert(NULL != pcSrc); ai_assert(nullptr != pcSrc);
const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer; const MDL::Header *const pcHeader = (const MDL::Header *)this->mBuffer;
// validate UV indices // validate UV indices
@ -860,7 +860,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Validate the header of a MDL7 file // Validate the header of a MDL7 file
void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) { void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
ai_assert(NULL != pcHeader); ai_assert(nullptr != pcHeader);
// There are some fixed sizes ... // There are some fixed sizes ...
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) { if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
@ -887,7 +887,7 @@ void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7 *pcHeader) {
void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones) { void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7 **apcOutBones) {
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer; const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1); const MDL::Bone_MDL7 *pcBones = (const MDL::Bone_MDL7 *)(pcHeader + 1);
ai_assert(NULL != apcOutBones); ai_assert(nullptr != apcOutBones);
// first find the bone that has NO parent, calculate the // first find the bone that has NO parent, calculate the
// animation matrix for it, then go on and search for the next parent // animation matrix for it, then go on and search for the next parent
@ -979,7 +979,7 @@ MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size && AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) { AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size) {
ASSIMP_LOG_WARN("Unknown size of bone data structure"); ASSIMP_LOG_WARN("Unknown size of bone data structure");
return NULL; return nullptr;
} }
MDL::IntBone_MDL7 **apcBonesOut = new MDL::IntBone_MDL7 *[pcHeader->bones_num]; MDL::IntBone_MDL7 **apcBonesOut = new MDL::IntBone_MDL7 *[pcHeader->bones_num];
@ -990,7 +990,7 @@ MDL::IntBone_MDL7 **MDLImporter::LoadBones_3DGS_MDL7() {
CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut); CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
return apcBonesOut; return apcBonesOut;
} }
return NULL; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -1014,7 +1014,7 @@ void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7 &groupInfo,
unsigned int iIndex = pcGroupTris->v_index[c]; unsigned int iIndex = pcGroupTris->v_index[c];
if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) { if (iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
// (we might need to read this section a second time - to process frame vertices correctly) // (we might need to read this section a second time - to process frame vertices correctly)
pcGroupTris->v_index[c] = (uint16_t) (iIndex = groupInfo.pcGroup->numverts - 1 ); pcGroupTris->v_index[c] = (uint16_t)(iIndex = groupInfo.pcGroup->numverts - 1);
ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list"); ASSIMP_LOG_WARN("Index overflow in MDL7 vertex list");
} }
@ -1337,7 +1337,7 @@ void MDLImporter::SortByMaterials_3DGS_MDL7(
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read a MDL7 file // Read a MDL7 file
void MDLImporter::InternReadFile_3DGS_MDL7() { void MDLImporter::InternReadFile_3DGS_MDL7() {
ai_assert(NULL != pScene); ai_assert(nullptr != pScene);
MDL::IntSharedData_MDL7 sharedData; MDL::IntSharedData_MDL7 sharedData;
@ -1368,7 +1368,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
// load all bones (they are shared by all groups, so // load all bones (they are shared by all groups, so
// we'll need to add them to all groups/meshes later) // we'll need to add them to all groups/meshes later)
// apcBonesOut is a list of all bones or NULL if they could not been loaded // apcBonesOut is a list of all bones or nullptr if they could not been loaded
szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size; szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size;
sharedData.apcOutBones = this->LoadBones_3DGS_MDL7(); sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
@ -1558,9 +1558,9 @@ void MDLImporter::InternReadFile_3DGS_MDL7() {
if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) { if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
aiNode *pcOldRoot = this->pScene->mRootNode; aiNode *pcOldRoot = this->pScene->mRootNode;
pScene->mRootNode = pcOldRoot->mChildren[0]; pScene->mRootNode = pcOldRoot->mChildren[0];
pcOldRoot->mChildren[0] = NULL; pcOldRoot->mChildren[0] = nullptr;
delete pcOldRoot; delete pcOldRoot;
pScene->mRootNode->mParent = NULL; pScene->mRootNode->mParent = nullptr;
} else } else
pScene->mRootNode->mName.Set("<mesh_root>"); pScene->mRootNode->mName.Set("<mesh_root>");
@ -1665,7 +1665,8 @@ void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
// Attach bones to the output nodegraph // Attach bones to the output nodegraph
void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones, void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBones,
aiNode *pcParent, uint16_t iParentIndex) { aiNode *pcParent, uint16_t iParentIndex) {
ai_assert(NULL != apcBones && NULL != pcParent); ai_assert(nullptr != apcBones);
ai_assert(nullptr != pcParent);
// get a pointer to the header ... // get a pointer to the header ...
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer; const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)this->mBuffer;
@ -1696,7 +1697,7 @@ void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7 **apcBon
// Build output animations // Build output animations
void MDLImporter::BuildOutputAnims_3DGS_MDL7( void MDLImporter::BuildOutputAnims_3DGS_MDL7(
const MDL::IntBone_MDL7 **apcBonesOut) { const MDL::IntBone_MDL7 **apcBonesOut) {
ai_assert(NULL != apcBonesOut); ai_assert(nullptr != apcBonesOut);
const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer; const MDL::Header_MDL7 *const pcHeader = (const MDL::Header_MDL7 *)mBuffer;
// one animation ... // one animation ...
@ -1755,8 +1756,8 @@ void MDLImporter::BuildOutputAnims_3DGS_MDL7(
void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo, void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
const MDL::BoneTransform_MDL7 *pcBoneTransforms, const MDL::BoneTransform_MDL7 *pcBoneTransforms,
MDL::IntBone_MDL7 **apcBonesOut) { MDL::IntBone_MDL7 **apcBonesOut) {
ai_assert(NULL != pcBoneTransforms); ai_assert(nullptr != pcBoneTransforms);
ai_assert(NULL != apcBonesOut); ai_assert(nullptr != apcBonesOut);
// first .. get the transformation matrix // first .. get the transformation matrix
aiMatrix4x4 mTransform; aiMatrix4x4 mTransform;
@ -1920,7 +1921,9 @@ void MDLImporter::JoinSkins_3DGS_MDL7(
aiMaterial *pcMat1, aiMaterial *pcMat1,
aiMaterial *pcMat2, aiMaterial *pcMat2,
aiMaterial *pcMatOut) { aiMaterial *pcMatOut) {
ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut); ai_assert(nullptr != pcMat1);
ai_assert(nullptr != pcMat2);
ai_assert(nullptr != pcMatOut);
// first create a full copy of the first skin property set // first create a full copy of the first skin property set
// and assign it to the output material // and assign it to the output material

View File

@ -320,7 +320,7 @@ protected:
/** Load the bone list of a MDL7 file /** Load the bone list of a MDL7 file
* \return If the bones could be loaded successfully, a valid * \return If the bones could be loaded successfully, a valid
* array containing pointers to a temporary bone * array containing pointers to a temporary bone
* representation. NULL if the bones could not be loaded. * representation. nullptr if the bones could not be loaded.
*/ */
MDL::IntBone_MDL7** LoadBones_3DGS_MDL7(); MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();

View File

@ -364,7 +364,7 @@ void MDLImporter::ParseTextureColorData(const unsigned char *szData,
void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData, void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
unsigned int iType, unsigned int iType,
unsigned int *piSkip) { unsigned int *piSkip) {
ai_assert(NULL != piSkip); ai_assert(nullptr != piSkip);
bool bNoRead = *piSkip == UINT_MAX; bool bNoRead = *piSkip == UINT_MAX;
// allocate a new texture object // allocate a new texture object
@ -428,7 +428,7 @@ void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char *szData,
delete[] pc; delete[] pc;
} }
} else { } else {
pcNew->pcData = NULL; pcNew->pcData = nullptr;
delete pcNew; delete pcNew;
} }
return; return;

View File

@ -134,7 +134,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel, void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
aiScene *pScene) { aiScene *pScene) {
if (pModel == NULL) { if (pModel == nullptr) {
return; return;
} }

View File

@ -131,7 +131,7 @@ namespace pmd
stream->read((char*) &index_count, sizeof(uint32_t)); stream->read((char*) &index_count, sizeof(uint32_t));
stream->read((char*) &buffer, sizeof(char) * 20); stream->read((char*) &buffer, sizeof(char) * 20);
char* pstar = strchr(buffer, '*'); char* pstar = strchr(buffer, '*');
if (NULL == pstar) if (nullptr == pstar)
{ {
texture_filename = std::string(buffer); texture_filename = std::string(buffer);
sphere_filename.clear(); sphere_filename.clear();

View File

@ -657,7 +657,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
} }
// fixup to pass the validation if not a single animation channel is non-trivial // fixup to pass the validation if not a single animation channel is non-trivial
if (!anim->mNumChannels) { if (!anim->mNumChannels) {
anim->mChannels = NULL; anim->mChannels = nullptr;
} }
} }
} }

View File

@ -154,7 +154,7 @@ void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo> &output,
return; return;
} }
ShadingInfo *curShader = NULL; ShadingInfo *curShader = nullptr;
// No read the file line per line // No read the file line per line
char line[4096]; char line[4096];
@ -238,9 +238,9 @@ void NFFImporter::InternReadFile(const std::string &pFile,
bool hasCam = false; bool hasCam = false;
MeshInfo *currentMeshWithNormals = NULL; MeshInfo *currentMeshWithNormals = nullptr;
MeshInfo *currentMesh = NULL; MeshInfo *currentMesh = nullptr;
MeshInfo *currentMeshWithUVCoords = NULL; MeshInfo *currentMeshWithUVCoords = nullptr;
ShadingInfo s; // current material info ShadingInfo s; // current material info
@ -542,7 +542,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// search the list of all shaders we have for this object whether // search the list of all shaders we have for this object whether
// there is an identical one. In this case, we append our mesh // there is an identical one. In this case, we append our mesh
// data to it. // data to it.
MeshInfo *mesh = NULL; MeshInfo *mesh = nullptr;
for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end(); for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end();
it != end; ++it) { it != end; ++it) {
if ((*it).shader == shader && (*it).matIndex == matIdx) { if ((*it).shader == shader && (*it).matIndex == matIdx) {
@ -603,11 +603,11 @@ void NFFImporter::InternReadFile(const std::string &pFile,
while (GetNextLine(buffer, line)) { while (GetNextLine(buffer, line)) {
sz = line; sz = line;
if ('p' == line[0] || TokenMatch(sz, "tpp", 3)) { if ('p' == line[0] || TokenMatch(sz, "tpp", 3)) {
MeshInfo *out = NULL; MeshInfo *out = nullptr;
// 'tpp' - texture polygon patch primitive // 'tpp' - texture polygon patch primitive
if ('t' == line[0]) { if ('t' == line[0]) {
currentMeshWithUVCoords = NULL; currentMeshWithUVCoords = nullptr;
for (auto &mesh : meshesWithUVCoords) { for (auto &mesh : meshesWithUVCoords) {
if (mesh.shader == s) { if (mesh.shader == s) {
currentMeshWithUVCoords = &mesh; currentMeshWithUVCoords = &mesh;
@ -624,7 +624,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
} }
// 'pp' - polygon patch primitive // 'pp' - polygon patch primitive
else if ('p' == line[1]) { else if ('p' == line[1]) {
currentMeshWithNormals = NULL; currentMeshWithNormals = nullptr;
for (auto &mesh : meshesWithNormals) { for (auto &mesh : meshesWithNormals) {
if (mesh.shader == s) { if (mesh.shader == s) {
currentMeshWithNormals = &mesh; currentMeshWithNormals = &mesh;
@ -642,7 +642,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
} }
// 'p' - polygon primitive // 'p' - polygon primitive
else { else {
currentMesh = NULL; currentMesh = nullptr;
for (auto &mesh : meshes) { for (auto &mesh : meshes) {
if (mesh.shader == s) { if (mesh.shader == s) {
currentMesh = &mesh; currentMesh = &mesh;
@ -969,8 +969,8 @@ void NFFImporter::InternReadFile(const std::string &pFile,
root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int)lights.size(); root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int)lights.size();
root->mNumMeshes = pScene->mNumMeshes - numNamed; root->mNumMeshes = pScene->mNumMeshes - numNamed;
aiNode **ppcChildren = NULL; aiNode **ppcChildren = nullptr;
unsigned int *pMeshes = NULL; unsigned int *pMeshes = nullptr;
if (root->mNumMeshes) if (root->mNumMeshes)
pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes]; pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes];
if (root->mNumChildren) if (root->mNumChildren)
@ -1037,7 +1037,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
mesh->mNumFaces = (unsigned int)src.faces.size(); mesh->mNumFaces = (unsigned int)src.faces.size();
// Generate sub nodes for named meshes // Generate sub nodes for named meshes
if (src.name[0] && NULL != ppcChildren) { if (src.name[0] && nullptr != ppcChildren) {
aiNode *const node = *ppcChildren = new aiNode(); aiNode *const node = *ppcChildren = new aiNode();
node->mParent = root; node->mParent = root;
node->mNumMeshes = 1; node->mNumMeshes = 1;

View File

@ -70,14 +70,14 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write both the main OBJ file and the material script // we're still here - export successfully completed. Write both the main OBJ file and the material script
{ {
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile)); throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
} }
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
} }
{ {
std::unique_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName())); throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
} }
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1); outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
@ -97,7 +97,7 @@ void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* p
// we're still here - export successfully completed. Write both the main OBJ file and the material script // we're still here - export successfully completed. Write both the main OBJ file and the material script
{ {
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile)); throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
} }
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1); outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);

View File

@ -41,12 +41,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma once #pragma once
#ifndef OBJ_FILEDATA_H_INC #ifndef OBJ_FILEDATA_H_INC
# define OBJ_FILEDATA_H_INC #define OBJ_FILEDATA_H_INC
# include <assimp/mesh.h> #include <assimp/mesh.h>
# include <assimp/types.h> #include <assimp/types.h>
# include <map> #include <map>
# include <vector> #include <vector>
namespace Assimp { namespace Assimp {
namespace ObjFile { namespace ObjFile {
@ -215,7 +215,11 @@ struct Mesh {
/// Constructor /// Constructor
explicit Mesh(const std::string &name) : explicit Mesh(const std::string &name) :
m_name(name), m_pMaterial(NULL), m_uiNumIndices(0), m_uiMaterialIndex(NoMaterial), m_hasNormals(false) { m_name(name),
m_pMaterial(nullptr),
m_uiNumIndices(0),
m_uiMaterialIndex(NoMaterial),
m_hasNormals(false) {
memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS); memset(m_uiUVCoordinates, 0, sizeof(unsigned int) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
} }
@ -275,13 +279,13 @@ struct Model {
//! \brief The default class constructor //! \brief The default class constructor
Model() : Model() :
m_ModelName(""), m_ModelName(""),
m_pCurrent(NULL), m_pCurrent(nullptr),
m_pCurrentMaterial(NULL), m_pCurrentMaterial(nullptr),
m_pDefaultMaterial(NULL), m_pDefaultMaterial(nullptr),
m_pGroupFaceIDs(NULL), m_pGroupFaceIDs(nullptr),
m_strActiveGroup(""), m_strActiveGroup(""),
m_TextureCoordDim(0), m_TextureCoordDim(0),
m_pCurrentMesh(NULL) { m_pCurrentMesh(nullptr) {
// empty // empty
} }

View File

@ -252,9 +252,9 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model *pModel, aiScene
aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject, aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile::Object *pObject,
aiNode *pParent, aiScene *pScene, aiNode *pParent, aiScene *pScene,
std::vector<aiMesh *> &MeshArray) { std::vector<aiMesh *> &MeshArray) {
ai_assert(NULL != pModel); ai_assert(nullptr != pModel);
if (NULL == pObject) { if (nullptr == pObject) {
return NULL; return nullptr;
} }
// Store older mesh size to be able to computes mesh offsets for new mesh instances // Store older mesh size to be able to computes mesh offsets for new mesh instances
@ -264,7 +264,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
pNode->mName = pObject->m_strObjName; pNode->mName = pObject->m_strObjName;
// If we have a parent node, store it // If we have a parent node, store it
ai_assert(NULL != pParent); ai_assert(nullptr != pParent);
appendChildToParentNode(pParent, pNode); appendChildToParentNode(pParent, pNode);
for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) { for (size_t i = 0; i < pObject->m_Meshes.size(); ++i) {
@ -308,20 +308,20 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model *pModel, const ObjFile
// Create topology data // Create topology data
aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData, unsigned int meshIndex) { aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjFile::Object *pData, unsigned int meshIndex) {
// Checking preconditions // Checking preconditions
ai_assert(NULL != pModel); ai_assert(nullptr != pModel);
if (NULL == pData) { if (nullptr == pData) {
return NULL; return nullptr;
} }
// Create faces // Create faces
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[meshIndex]; ObjFile::Mesh *pObjMesh = pModel->m_Meshes[meshIndex];
if (!pObjMesh) { if (!pObjMesh) {
return NULL; return nullptr;
} }
if (pObjMesh->m_Faces.empty()) { if (pObjMesh->m_Faces.empty()) {
return NULL; return nullptr;
} }
std::unique_ptr<aiMesh> pMesh(new aiMesh); std::unique_ptr<aiMesh> pMesh(new aiMesh);
@ -331,7 +331,7 @@ aiMesh *ObjFileImporter::createTopology(const ObjFile::Model *pModel, const ObjF
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) { for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
ObjFile::Face *const inp = pObjMesh->m_Faces[index]; ObjFile::Face *const inp = pObjMesh->m_Faces[index];
ai_assert(NULL != inp); ai_assert(nullptr != inp);
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1); pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
@ -400,7 +400,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
aiMesh *pMesh, aiMesh *pMesh,
unsigned int numIndices) { unsigned int numIndices) {
// Checking preconditions // Checking preconditions
ai_assert(NULL != pCurrentObject); ai_assert(nullptr != pCurrentObject);
// Break, if no faces are stored in object // Break, if no faces are stored in object
if (pCurrentObject->m_Meshes.empty()) if (pCurrentObject->m_Meshes.empty())
@ -408,7 +408,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model *pModel,
// Get current mesh // Get current mesh
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[uiMeshIndex]; ObjFile::Mesh *pObjMesh = pModel->m_Meshes[uiMeshIndex];
if (NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1) { if (nullptr == pObjMesh || pObjMesh->m_uiNumIndices < 1) {
return; return;
} }
@ -561,7 +561,7 @@ void ObjFileImporter::addTextureMappingModeProperty(aiMaterial *mat, aiTextureTy
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the material // Creates the material
void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pScene) { void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pScene) {
if (NULL == pScene) { if (nullptr == pScene) {
return; return;
} }
@ -717,8 +717,8 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
// Appends this node to the parent node // Appends this node to the parent node
void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) { void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) {
// Checking preconditions // Checking preconditions
ai_assert(NULL != pParent); ai_assert(nullptr != pParent);
ai_assert(NULL != pChild); ai_assert(nullptr != pChild);
// Assign parent to child // Assign parent to child
pChild->mParent = pParent; pChild->mParent = pParent;

View File

@ -200,7 +200,7 @@ void ObjFileMtlImporter::load() {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Loads a color definition // Loads a color definition
void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) { void ObjFileMtlImporter::getColorRGBA(aiColor3D *pColor) {
ai_assert(NULL != pColor); ai_assert(nullptr != pColor);
ai_real r(0.0), g(0.0), b(0.0); ai_real r(0.0), g(0.0), b(0.0);
m_DataIt = getFloat<DataArrayIt>(m_DataIt, m_DataItEnd, r); m_DataIt = getFloat<DataArrayIt>(m_DataIt, m_DataItEnd, r);
@ -274,7 +274,7 @@ void ObjFileMtlImporter::createMaterial() {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Gets a texture name from data. // Gets a texture name from data.
void ObjFileMtlImporter::getTexture() { void ObjFileMtlImporter::getTexture() {
aiString *out(NULL); aiString *out(nullptr);
int clampIndex = -1; int clampIndex = -1;
const char *pPtr(&(*m_DataIt)); const char *pPtr(&(*m_DataIt));
@ -332,7 +332,7 @@ void ObjFileMtlImporter::getTexture() {
std::string texture; std::string texture;
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture); m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, texture);
if (NULL != out) { if (nullptr != out) {
out->Set(texture); out->Set(texture);
} }
} }

View File

@ -494,19 +494,19 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
} }
// Set active material, if one set // Set active material, if one set
if (NULL != m_pModel->m_pCurrentMaterial) { if (nullptr != m_pModel->m_pCurrentMaterial) {
face->m_pMaterial = m_pModel->m_pCurrentMaterial; face->m_pMaterial = m_pModel->m_pCurrentMaterial;
} else { } else {
face->m_pMaterial = m_pModel->m_pDefaultMaterial; face->m_pMaterial = m_pModel->m_pDefaultMaterial;
} }
// Create a default object, if nothing is there // Create a default object, if nothing is there
if (NULL == m_pModel->m_pCurrent) { if (nullptr == m_pModel->m_pCurrent) {
createObject(DefaultObjName); createObject(DefaultObjName);
} }
// Assign face to mesh // Assign face to mesh
if (NULL == m_pModel->m_pCurrentMesh) { if (nullptr == m_pModel->m_pCurrentMesh) {
createMesh(DefaultObjName); createMesh(DefaultObjName);
} }
@ -753,7 +753,7 @@ void ObjFileParser::getObjectName() {
std::string strObjectName(pStart, &(*m_DataIt)); std::string strObjectName(pStart, &(*m_DataIt));
if (!strObjectName.empty()) { if (!strObjectName.empty()) {
// Reset current object // Reset current object
m_pModel->m_pCurrent = NULL; m_pModel->m_pCurrent = nullptr;
// Search for actual object // Search for actual object
for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin(); for (std::vector<ObjFile::Object *>::const_iterator it = m_pModel->m_Objects.begin();
@ -766,7 +766,7 @@ void ObjFileParser::getObjectName() {
} }
// Allocate a new object, if current one was not found before // Allocate a new object, if current one was not found before
if (NULL == m_pModel->m_pCurrent) { if (nullptr == m_pModel->m_pCurrent) {
createObject(strObjectName); createObject(strObjectName);
} }
} }
@ -775,7 +775,7 @@ void ObjFileParser::getObjectName() {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Creates a new object instance // Creates a new object instance
void ObjFileParser::createObject(const std::string &objName) { void ObjFileParser::createObject(const std::string &objName) {
ai_assert(NULL != m_pModel); ai_assert(nullptr != m_pModel);
m_pModel->m_pCurrent = new ObjFile::Object; m_pModel->m_pCurrent = new ObjFile::Object;
m_pModel->m_pCurrent->m_strObjName = objName; m_pModel->m_pCurrent->m_strObjName = objName;
@ -792,11 +792,12 @@ void ObjFileParser::createObject(const std::string &objName) {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Creates a new mesh // Creates a new mesh
void ObjFileParser::createMesh(const std::string &meshName) { void ObjFileParser::createMesh(const std::string &meshName) {
ai_assert(NULL != m_pModel); ai_assert(nullptr != m_pModel);
m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName); m_pModel->m_pCurrentMesh = new ObjFile::Mesh(meshName);
m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh); m_pModel->m_Meshes.push_back(m_pModel->m_pCurrentMesh);
unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1); unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size() - 1);
if (NULL != m_pModel->m_pCurrent) { if (nullptr != m_pModel->m_pCurrent) {
m_pModel->m_pCurrent->m_Meshes.push_back(meshId); m_pModel->m_pCurrent->m_Meshes.push_back(meshId);
} else { } else {
ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance."); ASSIMP_LOG_ERROR("OBJ: No object detected to attach a new mesh instance.");

File diff suppressed because it is too large Load Diff

View File

@ -77,7 +77,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write the file. // we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
} }
@ -91,7 +91,7 @@ void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene*
// we're still here - export successfully completed. Write the file. // we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb")); std::unique_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb"));
if (outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .ply file: " + std::string(pFile)); throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
} }

View File

@ -693,7 +693,7 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avL
unsigned int aiPositions[4], unsigned int aiPositions[4],
PLY::EDataType aiTypes[4], PLY::EDataType aiTypes[4],
aiColor4D *clrOut) { aiColor4D *clrOut) {
ai_assert(NULL != clrOut); ai_assert(nullptr != clrOut);
if (0xFFFFFFFF == aiPositions[0]) if (0xFFFFFFFF == aiPositions[0])
clrOut->r = 0.0f; clrOut->r = 0.0f;
@ -736,7 +736,7 @@ void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance> &avL
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Extract a material from the PLY DOM // Extract a material from the PLY DOM
void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) { void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &defaultTexture, const bool pointsOnly) {
ai_assert(NULL != pvOut); ai_assert(nullptr != pvOut);
// diffuse[4], specular[4], ambient[4] // diffuse[4], specular[4], ambient[4]
// rgba order // rgba order
@ -752,7 +752,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char }, { EDT_Char, EDT_Char, EDT_Char, EDT_Char },
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char } { EDT_Char, EDT_Char, EDT_Char, EDT_Char }
}; };
PLY::ElementInstanceList *pcList = NULL; PLY::ElementInstanceList *pcList = nullptr;
unsigned int iPhong = 0xFFFFFFFF; unsigned int iPhong = 0xFFFFFFFF;
PLY::EDataType ePhong = EDT_Char; PLY::EDataType ePhong = EDT_Char;
@ -835,7 +835,7 @@ void PLYImporter::LoadMaterial(std::vector<aiMaterial *> *pvOut, std::string &de
} }
} }
// check whether we have a valid source for the material data // check whether we have a valid source for the material data
if (NULL != pcList) { if (nullptr != pcList) {
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) { for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) {
aiColor4D clrOut; aiColor4D clrOut;
aiMaterial *pcHelper = new aiMaterial(); aiMaterial *pcHelper = new aiMaterial();

File diff suppressed because it is too large Load Diff

View File

@ -43,27 +43,27 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER #ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
#include "Q3BSPFileImporter.h" #include "Q3BSPFileImporter.h"
#include "Q3BSPFileParser.h"
#include "Q3BSPFileData.h" #include "Q3BSPFileData.h"
#include "Q3BSPFileParser.h"
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h> #include <zlib.h>
#else #else
# include "../contrib/zlib/zlib.h" #include "../contrib/zlib/zlib.h"
#endif #endif
#include <assimp/types.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/StringComparison.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/importerdesc.h>
#include <assimp/mesh.h> #include <assimp/mesh.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/ai_assert.h> #include <assimp/types.h>
#include <assimp/DefaultIOSystem.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/importerdesc.h>
#include <vector>
#include <sstream> #include <sstream>
#include <assimp/StringComparison.h> #include <vector>
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"Quake III BSP Importer", "Quake III BSP Importer",
@ -84,7 +84,7 @@ using namespace Q3BSP;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Local function to create a material key name. // Local function to create a material key name.
static void createKey( int id1, int id2, std::string &key ) { static void createKey(int id1, int id2, std::string &key) {
std::ostringstream str; std::ostringstream str;
str << id1 << "." << id2; str << id1 << "." << id2;
key = str.str(); key = str.str();
@ -92,27 +92,27 @@ static void createKey( int id1, int id2, std::string &key ) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Local function to extract the texture ids from a material key-name. // Local function to extract the texture ids from a material key-name.
static void extractIds( const std::string &key, int &id1, int &id2 ) { static void extractIds(const std::string &key, int &id1, int &id2) {
id1 = -1; id1 = -1;
id2 = -1; id2 = -1;
if (key.empty()) { if (key.empty()) {
return; return;
} }
const std::string::size_type pos = key.find( "." ); const std::string::size_type pos = key.find(".");
if (std::string::npos == pos) { if (std::string::npos == pos) {
return; return;
} }
std::string tmp1 = key.substr( 0, pos ); std::string tmp1 = key.substr(0, pos);
std::string tmp2 = key.substr( pos + 1, key.size() - pos - 1 ); std::string tmp2 = key.substr(pos + 1, key.size() - pos - 1);
id1 = atoi( tmp1.c_str() ); id1 = atoi(tmp1.c_str());
id2 = atoi( tmp2.c_str() ); id2 = atoi(tmp2.c_str());
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Local helper function to normalize filenames. // Local helper function to normalize filenames.
static void normalizePathName( const std::string &rPath, std::string &normalizedPath ) { static void normalizePathName(const std::string &rPath, std::string &normalizedPath) {
normalizedPath = ""; normalizedPath = "";
if (rPath.empty()) { if (rPath.empty()) {
return; return;
@ -125,12 +125,12 @@ static void normalizePathName( const std::string &rPath, std::string &normalized
#endif #endif
static const unsigned int numDelimiters = 2; static const unsigned int numDelimiters = 2;
const char delimiters[ numDelimiters ] = { '/', '\\' }; const char delimiters[numDelimiters] = { '/', '\\' };
normalizedPath = rPath; normalizedPath = rPath;
for (const char delimiter : delimiters) { for (const char delimiter : delimiters) {
for ( size_t j=0; j<normalizedPath.size(); ++j ) { for (size_t j = 0; j < normalizedPath.size(); ++j) {
if ( normalizedPath[j] == delimiter ) { if (normalizedPath[j] == delimiter) {
normalizedPath[ j ] = sep[ 0 ]; normalizedPath[j] = sep[0];
} }
} }
} }
@ -138,11 +138,8 @@ static void normalizePathName( const std::string &rPath, std::string &normalized
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor. // Constructor.
Q3BSPFileImporter::Q3BSPFileImporter() Q3BSPFileImporter::Q3BSPFileImporter() :
: m_pCurrentMesh( nullptr ) m_pCurrentMesh(nullptr), m_pCurrentFace(nullptr), m_MaterialLookupMap(), mTextures() {
, m_pCurrentFace(nullptr)
, m_MaterialLookupMap()
, mTextures() {
// empty // empty
} }
@ -153,9 +150,9 @@ Q3BSPFileImporter::~Q3BSPFileImporter() {
m_pCurrentFace = nullptr; m_pCurrentFace = nullptr;
// Clear face-to-material map // Clear face-to-material map
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()) {
delete it->second; delete it->second;
} }
} }
@ -164,9 +161,9 @@ Q3BSPFileImporter::~Q3BSPFileImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns true, if the loader can read this. // Returns true, if the loader can read this.
bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const { bool Q3BSPFileImporter::CanRead(const std::string &rFile, IOSystem * /*pIOHandler*/, bool checkSig) const {
if(!checkSig) { if (!checkSig) {
return SimpleExtensionCheck( rFile, "pk3", "bsp" ); return SimpleExtensionCheck(rFile, "pk3", "bsp");
} }
return false; return false;
@ -174,69 +171,69 @@ bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandle
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Adds extensions. // Adds extensions.
const aiImporterDesc* Q3BSPFileImporter::GetInfo () const { const aiImporterDesc *Q3BSPFileImporter::GetInfo() const {
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// 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) {
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 + ".");
} }
std::string archiveName( "" ), mapName( "" ); std::string archiveName(""), mapName("");
separateMapName( rFile, archiveName, mapName ); separateMapName(rFile, archiveName, mapName);
if ( mapName.empty() ) { if (mapName.empty()) {
if ( !findFirstMapInArchive( Archive, mapName ) ) { if (!findFirstMapInArchive(Archive, mapName)) {
return; return;
} }
} }
Q3BSPFileParser fileParser( mapName, &Archive ); Q3BSPFileParser fileParser(mapName, &Archive);
Q3BSPModel *pBSPModel = fileParser.getModel(); Q3BSPModel *pBSPModel = fileParser.getModel();
if ( nullptr != pBSPModel ) { if (nullptr != pBSPModel) {
CreateDataFromImport( pBSPModel, scene, &Archive ); CreateDataFromImport(pBSPModel, scene, &Archive);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Separates the map name from the import name. // Separates the map name from the import name.
void Q3BSPFileImporter::separateMapName( const std::string &importName, std::string &archiveName, std::string &mapName ) { void Q3BSPFileImporter::separateMapName(const std::string &importName, std::string &archiveName, std::string &mapName) {
archiveName = ""; archiveName = "";
mapName = ""; mapName = "";
if (importName.empty()) { if (importName.empty()) {
return; return;
} }
const std::string::size_type pos = importName.rfind( "," ); const std::string::size_type pos = importName.rfind(",");
if ( std::string::npos == pos ) { if (std::string::npos == pos) {
archiveName = importName; archiveName = importName;
return; return;
} }
archiveName = importName.substr( 0, pos ); archiveName = importName.substr(0, pos);
mapName = importName.substr( pos, importName.size() - pos - 1 ); mapName = importName.substr(pos, importName.size() - pos - 1);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the first map in the map archive. // Returns the first map in the map archive.
bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, std::string &mapName ) { bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, std::string &mapName) {
mapName = ""; mapName = "";
std::vector<std::string> fileList; std::vector<std::string> fileList;
bspArchive.getFileListExtension( fileList, "bsp" ); bspArchive.getFileListExtension(fileList, "bsp");
if (fileList.empty()) { if (fileList.empty()) {
return false; return false;
} }
std::vector<std::string>::iterator it( fileList.begin() ); std::vector<std::string>::iterator it(fileList.begin());
for ( ; it != fileList.end(); ++it ) { for (; it != fileList.end(); ++it) {
const std::string::size_type pos = (*it).find( "maps/" ); const std::string::size_type pos = (*it).find("maps/");
if ( std::string::npos != pos ) { if (std::string::npos != pos) {
std::string::size_type extPos = (*it).find( ".bsp" ); std::string::size_type extPos = (*it).find(".bsp");
if ( std::string::npos != extPos ) { if (std::string::npos != extPos) {
mapName = *it; mapName = *it;
return true; return true;
} }
@ -248,122 +245,122 @@ bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, st
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the assimp specific data. // Creates the assimp specific data.
void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, void Q3BSPFileImporter::CreateDataFromImport(const Q3BSP::Q3BSPModel *pModel, aiScene *pScene,
ZipArchiveIOSystem *pArchive ) { ZipArchiveIOSystem *pArchive) {
if (nullptr == pModel || nullptr == pScene) { if (nullptr == pModel || nullptr == pScene) {
return; return;
} }
pScene->mRootNode = new aiNode; pScene->mRootNode = new aiNode;
if ( !pModel->m_ModelName.empty() ) { if (!pModel->m_ModelName.empty()) {
pScene->mRootNode->mName.Set( pModel->m_ModelName ); pScene->mRootNode->mName.Set(pModel->m_ModelName);
} }
// Create the face to material relation map // Create the face to material relation map
createMaterialMap( pModel ); createMaterialMap(pModel);
// Create all nodes // Create all nodes
CreateNodes( pModel, pScene, pScene->mRootNode ); CreateNodes(pModel, pScene, pScene->mRootNode);
// Create the assigned materials // Create the assigned materials
createMaterials( pModel, pScene, pArchive ); createMaterials(pModel, pScene, pArchive);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates all assimp nodes. // Creates all assimp nodes.
void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, void Q3BSPFileImporter::CreateNodes(const Q3BSP::Q3BSPModel *pModel, aiScene *pScene,
aiNode *pParent ) { aiNode *pParent) {
if ( nullptr == pModel ) { if (nullptr == pModel) {
return; return;
} }
unsigned int matIdx( 0 ); unsigned int matIdx(0);
std::vector<aiMesh*> MeshArray; std::vector<aiMesh *> MeshArray;
std::vector<aiNode*> NodeArray; std::vector<aiNode *> NodeArray;
for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it ) { for (FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it) {
std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second; std::vector<Q3BSP::sQ3BSPFace *> *pArray = (*it).second;
size_t numVerts = countData( *pArray ); size_t numVerts = countData(*pArray);
if ( 0 != numVerts ) { if (0 != numVerts) {
aiMesh *pMesh( nullptr ); aiMesh *pMesh(nullptr);
aiNode *pNode = CreateTopology( pModel, matIdx, *pArray, &pMesh ); aiNode *pNode = CreateTopology(pModel, matIdx, *pArray, &pMesh);
if ( nullptr != pNode ) { if (nullptr != pNode) {
NodeArray.push_back( pNode ); NodeArray.push_back(pNode);
MeshArray.push_back( pMesh ); MeshArray.push_back(pMesh);
} }
} }
matIdx++; matIdx++;
} }
pScene->mNumMeshes = static_cast<unsigned int>( MeshArray.size() ); pScene->mNumMeshes = static_cast<unsigned int>(MeshArray.size());
if ( pScene->mNumMeshes > 0 ) { if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
for ( size_t i = 0; i < MeshArray.size(); i++ ) { for (size_t i = 0; i < MeshArray.size(); i++) {
aiMesh *pMesh = MeshArray[ i ]; aiMesh *pMesh = MeshArray[i];
if ( nullptr != pMesh ) { if (nullptr != pMesh) {
pScene->mMeshes[ i ] = pMesh; pScene->mMeshes[i] = pMesh;
} }
} }
} }
pParent->mNumChildren = static_cast<unsigned int>(MeshArray.size()); pParent->mNumChildren = static_cast<unsigned int>(MeshArray.size());
pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ]; pParent->mChildren = new aiNode *[pScene->mRootNode->mNumChildren];
for ( size_t i=0; i<NodeArray.size(); i++ ) { for (size_t i = 0; i < NodeArray.size(); i++) {
aiNode *pNode = NodeArray[ i ]; aiNode *pNode = NodeArray[i];
pNode->mParent = pParent; pNode->mParent = pParent;
pParent->mChildren[ i ] = pNode; pParent->mChildren[i] = pNode;
pParent->mChildren[ i ]->mMeshes[ 0 ] = static_cast<unsigned int>(i); pParent->mChildren[i]->mMeshes[0] = static_cast<unsigned int>(i);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the topology. // Creates the topology.
aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx, aiNode *Q3BSPFileImporter::CreateTopology(const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx,
std::vector<sQ3BSPFace*> &rArray, aiMesh **pMesh ) { std::vector<sQ3BSPFace *> &rArray, aiMesh **pMesh) {
size_t numVerts = countData( rArray ); size_t numVerts = countData(rArray);
if ( 0 == numVerts ) { if (0 == numVerts) {
return nullptr; return nullptr;
} }
size_t numFaces = countFaces( rArray ); size_t numFaces = countFaces(rArray);
if ( 0 == numFaces ) { if (0 == numFaces) {
return nullptr; return nullptr;
} }
aiMesh *mesh = new aiMesh; aiMesh *mesh = new aiMesh;
size_t numTriangles = countTriangles( rArray ); size_t numTriangles = countTriangles(rArray);
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
mesh->mFaces = new aiFace[ numTriangles ]; mesh->mFaces = new aiFace[numTriangles];
mesh->mNumFaces = static_cast<unsigned int>(numTriangles); mesh->mNumFaces = static_cast<unsigned int>(numTriangles);
mesh->mNumVertices = static_cast<unsigned int>(numVerts); mesh->mNumVertices = static_cast<unsigned int>(numVerts);
mesh->mVertices = new aiVector3D[ numVerts ]; mesh->mVertices = new aiVector3D[numVerts];
mesh->mNormals = new aiVector3D[ numVerts ]; mesh->mNormals = new aiVector3D[numVerts];
mesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ]; mesh->mTextureCoords[0] = new aiVector3D[numVerts];
mesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ]; mesh->mTextureCoords[1] = new aiVector3D[numVerts];
mesh->mMaterialIndex = materialIdx; mesh->mMaterialIndex = materialIdx;
unsigned int faceIdx = 0; unsigned int faceIdx = 0;
unsigned int vertIdx = 0; unsigned int vertIdx = 0;
mesh->mNumUVComponents[ 0 ] = 2; mesh->mNumUVComponents[0] = 2;
mesh->mNumUVComponents[ 1 ] = 2; mesh->mNumUVComponents[1] = 2;
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); ++it ) { for (std::vector<sQ3BSPFace *>::const_iterator it = rArray.begin(); it != rArray.end(); ++it) {
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
ai_assert( NULL != pQ3BSPFace ); ai_assert(nullptr != pQ3BSPFace);
if ( nullptr == pQ3BSPFace ) { if (nullptr == pQ3BSPFace) {
continue; continue;
} }
if ( pQ3BSPFace->iNumOfFaceVerts > 0 ) { if (pQ3BSPFace->iNumOfFaceVerts > 0) {
if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) { if (pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh) {
createTriangleTopology( pModel, pQ3BSPFace, mesh, faceIdx, vertIdx ); createTriangleTopology(pModel, pQ3BSPFace, mesh, faceIdx, vertIdx);
} }
} }
} }
aiNode *pNode = new aiNode; aiNode *pNode = new aiNode;
pNode->mNumMeshes = 1; pNode->mNumMeshes = 1;
pNode->mMeshes = new unsigned int[ 1 ]; pNode->mMeshes = new unsigned int[1];
*pMesh = mesh; *pMesh = mesh;
return pNode; return pNode;
@ -371,27 +368,27 @@ aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsi
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the triangle topology from a face array. // Creates the triangle topology from a face array.
void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, sQ3BSPFace *pQ3BSPFace, void Q3BSPFileImporter::createTriangleTopology(const Q3BSP::Q3BSPModel *pModel, sQ3BSPFace *pQ3BSPFace,
aiMesh* pMesh, unsigned int &faceIdx, unsigned int &vertIdx ) { aiMesh *pMesh, unsigned int &faceIdx, unsigned int &vertIdx) {
ai_assert( faceIdx < pMesh->mNumFaces ); ai_assert(faceIdx < pMesh->mNumFaces);
m_pCurrentFace = getNextFace( pMesh, faceIdx ); m_pCurrentFace = getNextFace(pMesh, faceIdx);
if ( nullptr == m_pCurrentFace ) { if (nullptr == m_pCurrentFace) {
return; return;
} }
m_pCurrentFace->mNumIndices = 3; m_pCurrentFace->mNumIndices = 3;
m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ]; m_pCurrentFace->mIndices = new unsigned int[m_pCurrentFace->mNumIndices];
size_t idx( 0 ); size_t idx(0);
for ( size_t i = 0; i < (size_t) pQ3BSPFace->iNumOfFaceVerts; ++i ) { for (size_t i = 0; i < (size_t)pQ3BSPFace->iNumOfFaceVerts; ++i) {
const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ]; const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[pQ3BSPFace->iFaceVertexIndex + i];
if ( index >= pModel->m_Vertices.size() ) { if (index >= pModel->m_Vertices.size()) {
continue; continue;
} }
sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ]; sQ3BSPVertex *pVertex = pModel->m_Vertices[index];
if ( nullptr == pVertex ) { if (nullptr == pVertex) {
continue; continue;
} }
if (idx > 2) { if (idx > 2) {
@ -400,15 +397,15 @@ void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel,
if (nullptr != m_pCurrentFace) { if (nullptr != m_pCurrentFace) {
m_pCurrentFace->mNumIndices = 3; m_pCurrentFace->mNumIndices = 3;
m_pCurrentFace->mIndices = new unsigned int[3]; m_pCurrentFace->mIndices = new unsigned int[3];
m_pCurrentFace->mIndices[ idx ] = vertIdx; m_pCurrentFace->mIndices[idx] = vertIdx;
} }
} }
pMesh->mVertices[ vertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z ); pMesh->mVertices[vertIdx].Set(pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z);
pMesh->mNormals[ vertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z ); pMesh->mNormals[vertIdx].Set(pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z);
pMesh->mTextureCoords[ 0 ][ vertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f ); pMesh->mTextureCoords[0][vertIdx].Set(pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f);
pMesh->mTextureCoords[ 1 ][ vertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f ); pMesh->mTextureCoords[1][vertIdx].Set(pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f);
vertIdx++; vertIdx++;
idx++; idx++;
@ -417,65 +414,61 @@ void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates all referenced materials. // Creates all referenced materials.
void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, void Q3BSPFileImporter::createMaterials(const Q3BSP::Q3BSPModel *pModel, aiScene *pScene,
ZipArchiveIOSystem *pArchive ) { ZipArchiveIOSystem *pArchive) {
if ( m_MaterialLookupMap.empty() ) { if (m_MaterialLookupMap.empty()) {
return; return;
} }
pScene->mMaterials = new aiMaterial*[ m_MaterialLookupMap.size() ]; pScene->mMaterials = new aiMaterial *[m_MaterialLookupMap.size()];
aiString aiMatName; aiString aiMatName;
int textureId( -1 ), lightmapId( -1 ); int textureId(-1), lightmapId(-1);
for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); for (FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
++it ) { ++it) {
const std::string matName( it->first ); const std::string matName(it->first);
if ( matName.empty() ) { if (matName.empty()) {
continue; continue;
} }
aiMatName.Set( matName ); aiMatName.Set(matName);
aiMaterial *pMatHelper = new aiMaterial; aiMaterial *pMatHelper = new aiMaterial;
pMatHelper->AddProperty( &aiMatName, AI_MATKEY_NAME ); pMatHelper->AddProperty(&aiMatName, AI_MATKEY_NAME);
extractIds( matName, textureId, lightmapId ); extractIds(matName, textureId, lightmapId);
// Adding the texture // Adding the texture
if ( -1 != textureId ) { if (-1 != textureId) {
sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ]; sQ3BSPTexture *pTexture = pModel->m_Textures[textureId];
if ( nullptr != pTexture ) { if (nullptr != pTexture) {
std::string tmp( "*" ), texName( "" ); std::string tmp("*"), texName("");
tmp += pTexture->strName; tmp += pTexture->strName;
tmp += ".jpg"; tmp += ".jpg";
normalizePathName( tmp, texName ); normalizePathName(tmp, texName);
if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) ) { if (!importTextureFromArchive(pModel, pArchive, pScene, pMatHelper, textureId)) {
ASSIMP_LOG_ERROR("Cannot import texture from archive " + texName); ASSIMP_LOG_ERROR("Cannot import texture from archive " + texName);
} }
} }
} }
if ( -1 != lightmapId ) if (-1 != lightmapId) {
{ importLightmap(pModel, pScene, pMatHelper, lightmapId);
importLightmap( pModel, pScene, pMatHelper, lightmapId );
} }
pScene->mMaterials[ pScene->mNumMaterials ] = pMatHelper; pScene->mMaterials[pScene->mNumMaterials] = pMatHelper;
pScene->mNumMaterials++; pScene->mNumMaterials++;
} }
pScene->mNumTextures = static_cast<unsigned int>(mTextures.size()); pScene->mNumTextures = static_cast<unsigned int>(mTextures.size());
pScene->mTextures = new aiTexture*[ pScene->mNumTextures ]; pScene->mTextures = new aiTexture *[pScene->mNumTextures];
std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures ); std::copy(mTextures.begin(), mTextures.end(), pScene->mTextures);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts the number of referenced vertices. // Counts the number of referenced vertices.
size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &faceArray ) const { size_t Q3BSPFileImporter::countData(const std::vector<sQ3BSPFace *> &faceArray) const {
size_t numVerts( 0 ); size_t numVerts(0);
for ( std::vector<sQ3BSPFace*>::const_iterator it = faceArray.begin(); it != faceArray.end(); for (std::vector<sQ3BSPFace *>::const_iterator it = faceArray.begin(); it != faceArray.end();
++it ) ++it) {
{
sQ3BSPFace *pQ3BSPFace = *it; sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh ) if (pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh) {
{
Q3BSP::sQ3BSPFace *face = *it; Q3BSP::sQ3BSPFace *face = *it;
if (nullptr != face) { if (nullptr != face) {
numVerts += face->iNumOfFaceVerts; numVerts += face->iNumOfFaceVerts;
@ -488,15 +481,12 @@ size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &faceArray )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts the faces with vertices. // Counts the faces with vertices.
size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const size_t Q3BSPFileImporter::countFaces(const std::vector<Q3BSP::sQ3BSPFace *> &rArray) const {
{
size_t numFaces = 0; size_t numFaces = 0;
for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); for (std::vector<sQ3BSPFace *>::const_iterator it = rArray.begin(); it != rArray.end();
++it ) ++it) {
{
Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
if ( pQ3BSPFace->iNumOfFaceVerts > 0 ) if (pQ3BSPFace->iNumOfFaceVerts > 0) {
{
numFaces++; numFaces++;
} }
} }
@ -506,15 +496,12 @@ size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rAr
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts the number of triangles in a Q3-face-array. // Counts the number of triangles in a Q3-face-array.
size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const size_t Q3BSPFileImporter::countTriangles(const std::vector<Q3BSP::sQ3BSPFace *> &rArray) const {
{
size_t numTriangles = 0; size_t numTriangles = 0;
for ( std::vector<Q3BSP::sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); for (std::vector<Q3BSP::sQ3BSPFace *>::const_iterator it = rArray.begin(); it != rArray.end();
++it ) ++it) {
{
const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it; const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
if ( NULL != pQ3BSPFace ) if (nullptr != pQ3BSPFace) {
{
numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3; numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3;
} }
} }
@ -524,38 +511,34 @@ size_t Q3BSPFileImporter::countTriangles( const std::vector<Q3BSP::sQ3BSPFace*>
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Creates the faces-to-material map. // Creates the faces-to-material map.
void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel ) { void Q3BSPFileImporter::createMaterialMap(const Q3BSP::Q3BSPModel *pModel) {
std::string key( "" ); std::string key("");
std::vector<sQ3BSPFace*> *pCurFaceArray = NULL; std::vector<sQ3BSPFace *> *pCurFaceArray = nullptr;
for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ ) for (size_t idx = 0; idx < pModel->m_Faces.size(); idx++) {
{ Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[idx];
Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[ idx ];
const int texId = pQ3BSPFace->iTextureID; const int texId = pQ3BSPFace->iTextureID;
const int lightMapId = pQ3BSPFace->iLightmapID; const int lightMapId = pQ3BSPFace->iLightmapID;
createKey( texId, lightMapId, key ); createKey(texId, lightMapId, key);
FaceMapIt it = m_MaterialLookupMap.find( key ); FaceMapIt it = m_MaterialLookupMap.find(key);
if ( m_MaterialLookupMap.end() == it ) { if (m_MaterialLookupMap.end() == it) {
pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace*>; pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace *>;
m_MaterialLookupMap[ key ] = pCurFaceArray; m_MaterialLookupMap[key] = pCurFaceArray;
} } else {
else
{
pCurFaceArray = (*it).second; pCurFaceArray = (*it).second;
} }
ai_assert( nullptr != pCurFaceArray ); ai_assert(nullptr != pCurFaceArray);
if (nullptr != pCurFaceArray ) if (nullptr != pCurFaceArray) {
{ pCurFaceArray->push_back(pQ3BSPFace);
pCurFaceArray->push_back( pQ3BSPFace );
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the next face. // Returns the next face.
aiFace *Q3BSPFileImporter::getNextFace( aiMesh *mesh, unsigned int &faceIdx ) { aiFace *Q3BSPFileImporter::getNextFace(aiMesh *mesh, unsigned int &faceIdx) {
aiFace *face( nullptr ); aiFace *face(nullptr);
if ( faceIdx < mesh->mNumFaces ) { if (faceIdx < mesh->mNumFaces) {
face = &mesh->mFaces[ faceIdx ]; face = &mesh->mFaces[faceIdx];
++faceIdx; ++faceIdx;
} }
@ -564,31 +547,31 @@ aiFace *Q3BSPFileImporter::getNextFace( aiMesh *mesh, unsigned int &faceIdx ) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports a texture file. // Imports a texture file.
bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model, bool Q3BSPFileImporter::importTextureFromArchive(const Q3BSP::Q3BSPModel *model,
ZipArchiveIOSystem *archive, aiScene*, ZipArchiveIOSystem *archive, aiScene *,
aiMaterial *pMatHelper, int textureId ) { aiMaterial *pMatHelper, int textureId) {
if (nullptr == archive || nullptr == pMatHelper ) { if (nullptr == archive || nullptr == pMatHelper) {
return false; return false;
} }
if ( textureId < 0 || textureId >= static_cast<int>( model->m_Textures.size() ) ) { if (textureId < 0 || textureId >= static_cast<int>(model->m_Textures.size())) {
return false; return false;
} }
bool res = true; bool res = true;
sQ3BSPTexture *pTexture = model->m_Textures[ textureId ]; sQ3BSPTexture *pTexture = model->m_Textures[textureId];
if ( !pTexture ) { if (!pTexture) {
return false; return false;
} }
std::vector<std::string> supportedExtensions; std::vector<std::string> supportedExtensions;
supportedExtensions.push_back( ".jpg" ); supportedExtensions.push_back(".jpg");
supportedExtensions.push_back( ".png" ); supportedExtensions.push_back(".png");
supportedExtensions.push_back( ".tga" ); supportedExtensions.push_back(".tga");
std::string textureName, ext; std::string textureName, ext;
if ( expandFile( archive, pTexture->strName, supportedExtensions, textureName, ext ) ) { if (expandFile(archive, pTexture->strName, supportedExtensions, textureName, ext)) {
IOStream *pTextureStream = archive->Open( textureName.c_str() ); IOStream *pTextureStream = archive->Open(textureName.c_str());
if ( pTextureStream ) { if (pTextureStream) {
size_t texSize = pTextureStream->FileSize(); size_t texSize = pTextureStream->FileSize();
aiTexture *curTexture = new aiTexture; aiTexture *curTexture = new aiTexture;
curTexture->mHeight = 0; curTexture->mHeight = 0;
@ -605,20 +588,20 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model
res = true; res = true;
aiString name; aiString name;
name.data[ 0 ] = '*'; name.data[0] = '*';
name.length = 1 + ASSIMP_itoa10( name.data + 1, static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(mTextures.size()) ); name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(mTextures.size()));
archive->Close( pTextureStream ); archive->Close(pTextureStream);
pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); pMatHelper->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(0));
mTextures.push_back(curTexture); mTextures.push_back(curTexture);
} else { } else {
// If it doesn't exist in the archive, it is probably just a reference to an external file. // If it doesn't exist in the archive, it is probably just a reference to an external file.
// We'll leave it up to the user to figure out which extension the file has. // We'll leave it up to the user to figure out which extension the file has.
aiString name; aiString name;
strncpy( name.data, pTexture->strName, sizeof name.data ); strncpy(name.data, pTexture->strName, sizeof name.data);
name.length = static_cast<ai_uint32>(strlen( name.data )); name.length = static_cast<ai_uint32>(strlen(name.data));
pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) ); pMatHelper->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
} }
@ -627,19 +610,18 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports a light map file. // Imports a light map file.
bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, bool Q3BSPFileImporter::importLightmap(const Q3BSP::Q3BSPModel *pModel, aiScene *pScene,
aiMaterial *pMatHelper, int lightmapId ) aiMaterial *pMatHelper, int lightmapId) {
{ if (nullptr == pModel || nullptr == pScene || nullptr == pMatHelper) {
if (nullptr == pModel || nullptr == pScene || nullptr == pMatHelper ) {
return false; return false;
} }
if ( lightmapId < 0 || lightmapId >= static_cast<int>( pModel->m_Lightmaps.size() ) ) { if (lightmapId < 0 || lightmapId >= static_cast<int>(pModel->m_Lightmaps.size())) {
return false; return false;
} }
sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[ lightmapId ]; sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[lightmapId];
if (nullptr == pLightMap ) { if (nullptr == pLightMap) {
return false; return false;
} }
@ -649,21 +631,21 @@ bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene
pTexture->mHeight = CE_BSP_LIGHTMAPHEIGHT; pTexture->mHeight = CE_BSP_LIGHTMAPHEIGHT;
pTexture->pcData = new aiTexel[CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT]; pTexture->pcData = new aiTexel[CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT];
::memcpy( pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth ); ::memcpy(pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth);
size_t p = 0; size_t p = 0;
for ( size_t i = 0; i < CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT; ++i ) { for (size_t i = 0; i < CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT; ++i) {
pTexture->pcData[ i ].r = pLightMap->bLMapData[ p++ ]; pTexture->pcData[i].r = pLightMap->bLMapData[p++];
pTexture->pcData[ i ].g = pLightMap->bLMapData[ p++ ]; pTexture->pcData[i].g = pLightMap->bLMapData[p++];
pTexture->pcData[ i ].b = pLightMap->bLMapData[ p++ ]; pTexture->pcData[i].b = pLightMap->bLMapData[p++];
pTexture->pcData[ i ].a = 0xFF; pTexture->pcData[i].a = 0xFF;
} }
aiString name; aiString name;
name.data[ 0 ] = '*'; name.data[0] = '*';
name.length = 1 + ASSIMP_itoa10( name.data + 1, static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(mTextures.size()) ); name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(mTextures.size()));
pMatHelper->AddProperty( &name,AI_MATKEY_TEXTURE_LIGHTMAP( 1 ) ); pMatHelper->AddProperty(&name, AI_MATKEY_TEXTURE_LIGHTMAP(1));
mTextures.push_back( pTexture ); mTextures.push_back(pTexture);
return true; return true;
} }
@ -671,25 +653,21 @@ bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Will search for a supported extension. // Will search for a supported extension.
bool Q3BSPFileImporter::expandFile(ZipArchiveIOSystem *pArchive, const std::string &rFilename, bool Q3BSPFileImporter::expandFile(ZipArchiveIOSystem *pArchive, const std::string &rFilename,
const std::vector<std::string> &rExtList, std::string &rFile, const std::vector<std::string> &rExtList, std::string &rFile,
std::string &rExt ) std::string &rExt) {
{ ai_assert(nullptr != pArchive);
ai_assert( NULL != pArchive ); ai_assert(!rFilename.empty());
ai_assert( !rFilename.empty() );
if ( rExtList.empty() ) if (rExtList.empty()) {
{ rFile = rFilename;
rFile = rFilename;
rExt = ""; rExt = "";
return true; return true;
} }
bool found = false; bool found = false;
for ( std::vector<std::string>::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it ) for (std::vector<std::string>::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it) {
{
const std::string textureName = rFilename + *it; const std::string textureName = rFilename + *it;
if ( pArchive->Exists( textureName.c_str() ) ) if (pArchive->Exists(textureName.c_str())) {
{
rExt = *it; rExt = *it;
rFile = textureName; rFile = textureName;
found = true; found = true;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -45,17 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the Q3D importer class * @brief Implementation of the Q3D importer class
*/ */
#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER #ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
// internal headers // internal headers
#include "Q3DLoader.h" #include "Q3DLoader.h"
#include <assimp/StreamReader.h> #include <assimp/StreamReader.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
using namespace Assimp; using namespace Assimp;
@ -74,68 +71,66 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
Q3DImporter::Q3DImporter() Q3DImporter::Q3DImporter() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
Q3DImporter::~Q3DImporter() Q3DImporter::~Q3DImporter() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// 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 Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool Q3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if (extension == "q3s" || extension == "q3o") if (extension == "q3s" || extension == "q3o")
return true; return true;
else if (!extension.length() || checkSig) { else if (!extension.length() || checkSig) {
if (!pIOHandler) if (!pIOHandler)
return true; return true;
const char* tokens[] = {"quick3Do","quick3Ds"}; const char *tokens[] = { "quick3Do", "quick3Ds" };
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 2);
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* Q3DImporter::GetInfo () const const aiImporterDesc *Q3DImporter::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 Q3DImporter::InternReadFile( const std::string& pFile, void Q3DImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene *pScene, IOSystem *pIOHandler) {
{ StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
// The header is 22 bytes large // The header is 22 bytes large
if (stream.GetRemainingSize() < 22) if (stream.GetRemainingSize() < 22)
throw DeadlyImportError("File is either empty or corrupt: " + pFile); throw DeadlyImportError("File is either empty or corrupt: " + pFile);
// Check the file's signature // Check the file's signature
if (ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Do", 8 ) && if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 )) ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
{
throw DeadlyImportError("Not a Quick3D file. Signature string is: " + throw DeadlyImportError("Not a Quick3D file. Signature string is: " +
std::string((const char*)stream.GetPtr(),8)); std::string((const char *)stream.GetPtr(), 8));
} }
// Print the file format version // Print the file format version
ASSIMP_LOG_INFO_F("Quick3D File format version: ", ASSIMP_LOG_INFO_F("Quick3D File format version: ",
std::string(&((const char*)stream.GetPtr())[8],2)); std::string(&((const char *)stream.GetPtr())[8], 2));
// ... an store it // ... an store it
char major = ((const char*)stream.GetPtr())[8]; char major = ((const char *)stream.GetPtr())[8];
char minor = ((const char*)stream.GetPtr())[9]; char minor = ((const char *)stream.GetPtr())[9];
stream.IncPtr(10); stream.IncPtr(10);
unsigned int numMeshes = (unsigned int)stream.GetI4(); unsigned int numMeshes = (unsigned int)stream.GetI4();
unsigned int numMats = (unsigned int)stream.GetI4(); unsigned int numMats = (unsigned int)stream.GetI4();
unsigned int numTextures = (unsigned int)stream.GetI4(); unsigned int numTextures = (unsigned int)stream.GetI4();
std::vector<Material> materials; std::vector<Material> materials;
materials.reserve(numMats); materials.reserve(numMats);
@ -146,124 +141,109 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
// Allocate the scene root node // Allocate the scene root node
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
aiColor3D fgColor (0.6f,0.6f,0.6f); aiColor3D fgColor(0.6f, 0.6f, 0.6f);
// Now read all file chunks // Now read all file chunks
while (true) while (true) {
{ if (stream.GetRemainingSize() < 1) break;
if (stream.GetRemainingSize() < 1)break;
char c = stream.GetI1(); char c = stream.GetI1();
switch (c) switch (c) {
{
// Meshes chunk // Meshes chunk
case 'm': case 'm': {
{ for (unsigned int quak = 0; quak < numMeshes; ++quak) {
for (unsigned int quak = 0; quak < numMeshes; ++quak) meshes.push_back(Mesh());
{ Mesh &mesh = meshes.back();
meshes.push_back(Mesh());
Mesh& mesh = meshes.back();
// read all vertices // read all vertices
unsigned int numVerts = (unsigned int)stream.GetI4(); unsigned int numVerts = (unsigned int)stream.GetI4();
if (!numVerts) if (!numVerts)
throw DeadlyImportError("Quick3D: Found mesh with zero vertices"); throw DeadlyImportError("Quick3D: Found mesh with zero vertices");
std::vector<aiVector3D>& verts = mesh.verts; std::vector<aiVector3D> &verts = mesh.verts;
verts.resize(numVerts); verts.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i) for (unsigned int i = 0; i < numVerts; ++i) {
{ verts[i].x = stream.GetF4();
verts[i].x = stream.GetF4(); verts[i].y = stream.GetF4();
verts[i].y = stream.GetF4(); verts[i].z = stream.GetF4();
verts[i].z = stream.GetF4();
}
// read all faces
numVerts = (unsigned int)stream.GetI4();
if (!numVerts)
throw DeadlyImportError("Quick3D: Found mesh with zero faces");
std::vector<Face >& faces = mesh.faces;
faces.reserve(numVerts);
// number of indices
for (unsigned int i = 0; i < numVerts;++i)
{
faces.push_back(Face(stream.GetI2()) );
if (faces.back().indices.empty())
throw DeadlyImportError("Quick3D: Found face with zero indices");
}
// indices
for (unsigned int i = 0; i < numVerts;++i)
{
Face& vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
vec.indices[a] = stream.GetI4();
}
// material indices
for (unsigned int i = 0; i < numVerts;++i)
{
faces[i].mat = (unsigned int)stream.GetI4();
}
// read all normals
numVerts = (unsigned int)stream.GetI4();
std::vector<aiVector3D>& normals = mesh.normals;
normals.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
normals[i].x = stream.GetF4();
normals[i].y = stream.GetF4();
normals[i].z = stream.GetF4();
}
numVerts = (unsigned int)stream.GetI4();
if (numTextures && numVerts)
{
// read all texture coordinates
std::vector<aiVector3D>& uv = mesh.uv;
uv.resize(numVerts);
for (unsigned int i = 0; i < numVerts;++i)
{
uv[i].x = stream.GetF4();
uv[i].y = stream.GetF4();
}
// UV indices
for (unsigned int i = 0; i < (unsigned int)faces.size();++i)
{
Face& vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
{
vec.uvindices[a] = stream.GetI4();
if (!i && !a)
mesh.prevUVIdx = vec.uvindices[a];
else if (vec.uvindices[a] != mesh.prevUVIdx)
mesh.prevUVIdx = UINT_MAX;
}
}
}
// we don't need the rest, but we need to get to the next chunk
stream.IncPtr(36);
if (minor > '0' && major == '3')
stream.IncPtr(mesh.faces.size());
} }
// stream.IncPtr(4); // unknown value here
// read all faces
numVerts = (unsigned int)stream.GetI4();
if (!numVerts)
throw DeadlyImportError("Quick3D: Found mesh with zero faces");
std::vector<Face> &faces = mesh.faces;
faces.reserve(numVerts);
// number of indices
for (unsigned int i = 0; i < numVerts; ++i) {
faces.push_back(Face(stream.GetI2()));
if (faces.back().indices.empty())
throw DeadlyImportError("Quick3D: Found face with zero indices");
}
// indices
for (unsigned int i = 0; i < numVerts; ++i) {
Face &vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size(); ++a)
vec.indices[a] = stream.GetI4();
}
// material indices
for (unsigned int i = 0; i < numVerts; ++i) {
faces[i].mat = (unsigned int)stream.GetI4();
}
// read all normals
numVerts = (unsigned int)stream.GetI4();
std::vector<aiVector3D> &normals = mesh.normals;
normals.resize(numVerts);
for (unsigned int i = 0; i < numVerts; ++i) {
normals[i].x = stream.GetF4();
normals[i].y = stream.GetF4();
normals[i].z = stream.GetF4();
}
numVerts = (unsigned int)stream.GetI4();
if (numTextures && numVerts) {
// read all texture coordinates
std::vector<aiVector3D> &uv = mesh.uv;
uv.resize(numVerts);
for (unsigned int i = 0; i < numVerts; ++i) {
uv[i].x = stream.GetF4();
uv[i].y = stream.GetF4();
}
// UV indices
for (unsigned int i = 0; i < (unsigned int)faces.size(); ++i) {
Face &vec = faces[i];
for (unsigned int a = 0; a < (unsigned int)vec.indices.size(); ++a) {
vec.uvindices[a] = stream.GetI4();
if (!i && !a)
mesh.prevUVIdx = vec.uvindices[a];
else if (vec.uvindices[a] != mesh.prevUVIdx)
mesh.prevUVIdx = UINT_MAX;
}
}
}
// we don't need the rest, but we need to get to the next chunk
stream.IncPtr(36);
if (minor > '0' && major == '3')
stream.IncPtr(mesh.faces.size());
} }
break; // stream.IncPtr(4); // unknown value here
} break;
// materials chunk // materials chunk
case 'c': case 'c':
for (unsigned int i = 0; i < numMats; ++i) for (unsigned int i = 0; i < numMats; ++i) {
{
materials.push_back(Material()); materials.push_back(Material());
Material& mat = materials.back(); Material &mat = materials.back();
// read the material name // read the material name
c = stream.GetI1(); c = stream.GetI1();
@ -308,17 +288,18 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
if (!numTextures) { if (!numTextures) {
break; break;
} }
pScene->mTextures = new aiTexture*[pScene->mNumTextures]; pScene->mTextures = new aiTexture *[pScene->mNumTextures];
// to make sure we won't crash if we leave through an exception // to make sure we won't crash if we leave through an exception
::memset(pScene->mTextures,0,sizeof(void*)*pScene->mNumTextures); ::memset(pScene->mTextures, 0, sizeof(void *) * pScene->mNumTextures);
for (unsigned int i = 0; i < pScene->mNumTextures; ++i) { for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {
aiTexture* tex = pScene->mTextures[i] = new aiTexture; aiTexture *tex = pScene->mTextures[i] = new aiTexture;
// skip the texture name // skip the texture name
while (stream.GetI1()); while (stream.GetI1())
;
// read texture width and height // read texture width and height
tex->mWidth = (unsigned int)stream.GetI4(); tex->mWidth = (unsigned int)stream.GetI4();
tex->mHeight = (unsigned int)stream.GetI4(); tex->mHeight = (unsigned int)stream.GetI4();
if (!tex->mWidth || !tex->mHeight) { if (!tex->mWidth || !tex->mHeight) {
@ -326,11 +307,10 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
} }
unsigned int mul = tex->mWidth * tex->mHeight; unsigned int mul = tex->mWidth * tex->mHeight;
aiTexel* begin = tex->pcData = new aiTexel[mul]; aiTexel *begin = tex->pcData = new aiTexel[mul];
aiTexel* const end = & begin[mul-1] +1; aiTexel *const end = &begin[mul - 1] + 1;
for (; begin != end; ++begin) {
for (;begin != end; ++begin) {
begin->r = stream.GetI1(); begin->r = stream.GetI1();
begin->g = stream.GetI1(); begin->g = stream.GetI1();
begin->b = stream.GetI1(); begin->b = stream.GetI1();
@ -341,68 +321,66 @@ void Q3DImporter::InternReadFile( const std::string& pFile,
break; break;
// scene chunk // scene chunk
case 's': case 's': {
{ // skip position and rotation
// skip position and rotation stream.IncPtr(12);
stream.IncPtr(12);
for (unsigned int i = 0; i < 4;++i) for (unsigned int i = 0; i < 4; ++i)
for (unsigned int a = 0; a < 4;++a) for (unsigned int a = 0; a < 4; ++a)
pScene->mRootNode->mTransformation[i][a] = stream.GetF4(); pScene->mRootNode->mTransformation[i][a] = stream.GetF4();
stream.IncPtr(16); stream.IncPtr(16);
// now setup a single camera // now setup a single camera
pScene->mNumCameras = 1; pScene->mNumCameras = 1;
pScene->mCameras = new aiCamera*[1]; pScene->mCameras = new aiCamera *[1];
aiCamera* cam = pScene->mCameras[0] = new aiCamera(); aiCamera *cam = pScene->mCameras[0] = new aiCamera();
cam->mPosition.x = stream.GetF4(); cam->mPosition.x = stream.GetF4();
cam->mPosition.y = stream.GetF4(); cam->mPosition.y = stream.GetF4();
cam->mPosition.z = stream.GetF4(); cam->mPosition.z = stream.GetF4();
cam->mName.Set("Q3DCamera"); cam->mName.Set("Q3DCamera");
// skip eye rotation for the moment // skip eye rotation for the moment
stream.IncPtr(12); stream.IncPtr(12);
// read the default material color // read the default material color
fgColor .r = stream.GetF4(); fgColor.r = stream.GetF4();
fgColor .g = stream.GetF4(); fgColor.g = stream.GetF4();
fgColor .b = stream.GetF4(); fgColor.b = stream.GetF4();
// skip some unimportant properties // skip some unimportant properties
stream.IncPtr(29); stream.IncPtr(29);
// setup a single point light with no attenuation // setup a single point light with no attenuation
pScene->mNumLights = 1; pScene->mNumLights = 1;
pScene->mLights = new aiLight*[1]; pScene->mLights = new aiLight *[1];
aiLight* light = pScene->mLights[0] = new aiLight(); aiLight *light = pScene->mLights[0] = new aiLight();
light->mName.Set("Q3DLight"); light->mName.Set("Q3DLight");
light->mType = aiLightSource_POINT; light->mType = aiLightSource_POINT;
light->mAttenuationConstant = 1; light->mAttenuationConstant = 1;
light->mAttenuationLinear = 0; light->mAttenuationLinear = 0;
light->mAttenuationQuadratic = 0; light->mAttenuationQuadratic = 0;
light->mColorDiffuse.r = stream.GetF4(); light->mColorDiffuse.r = stream.GetF4();
light->mColorDiffuse.g = stream.GetF4(); light->mColorDiffuse.g = stream.GetF4();
light->mColorDiffuse.b = stream.GetF4(); light->mColorDiffuse.b = stream.GetF4();
light->mColorSpecular = light->mColorDiffuse; light->mColorSpecular = light->mColorDiffuse;
// We don't need the rest, but we need to know where this chunk ends.
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4());
// We don't need the rest, but we need to know where this chunk ends. // skip the background file name
unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4()); while (stream.GetI1())
;
// skip the background file name // skip background texture data + the remaining fields
while (stream.GetI1()); stream.IncPtr(temp * 3 + 20); // 4 bytes of unknown data here
// skip background texture data + the remaining fields // TODO
stream.IncPtr(temp*3 + 20); // 4 bytes of unknown data here goto outer;
} break;
// TODO
goto outer;
}
break;
default: default:
throw DeadlyImportError("Quick3D: Unknown chunk"); throw DeadlyImportError("Quick3D: Unknown chunk");
@ -416,55 +394,50 @@ outer:
throw DeadlyImportError("Quick3D: No meshes loaded"); throw DeadlyImportError("Quick3D: No meshes loaded");
// If we have no materials loaded - generate a default mat // If we have no materials loaded - generate a default mat
if (materials.empty()) if (materials.empty()) {
{
ASSIMP_LOG_INFO("Quick3D: No material found, generating one"); ASSIMP_LOG_INFO("Quick3D: No material found, generating one");
materials.push_back(Material()); materials.push_back(Material());
materials.back().diffuse = fgColor ; materials.back().diffuse = fgColor;
} }
// find out which materials we'll need // find out which materials we'll need
typedef std::pair<unsigned int, unsigned int> FaceIdx; typedef std::pair<unsigned int, unsigned int> FaceIdx;
typedef std::vector< FaceIdx > FaceIdxArray; typedef std::vector<FaceIdx> FaceIdxArray;
FaceIdxArray* fidx = new FaceIdxArray[materials.size()]; FaceIdxArray *fidx = new FaceIdxArray[materials.size()];
unsigned int p = 0; unsigned int p = 0;
for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end(); for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end();
it != end; ++it,++p) it != end; ++it, ++p) {
{
unsigned int q = 0; unsigned int q = 0;
for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end(); for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end();
fit != fend; ++fit,++q) fit != fend; ++fit, ++q) {
{ if ((*fit).mat >= materials.size()) {
if ((*fit).mat >= materials.size())
{
ASSIMP_LOG_WARN("Quick3D: Material index overflow"); ASSIMP_LOG_WARN("Quick3D: Material index overflow");
(*fit).mat = 0; (*fit).mat = 0;
} }
if (fidx[(*fit).mat].empty())++pScene->mNumMeshes; if (fidx[(*fit).mat].empty()) ++pScene->mNumMeshes;
fidx[(*fit).mat].push_back( FaceIdx(p,q) ); fidx[(*fit).mat].push_back(FaceIdx(p, q));
} }
} }
pScene->mNumMaterials = pScene->mNumMeshes; pScene->mNumMaterials = pScene->mNumMeshes;
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
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();
aiMaterial* mat = new aiMaterial(); aiMaterial *mat = new aiMaterial();
pScene->mMaterials[real] = mat; pScene->mMaterials[real] = mat;
mesh->mMaterialIndex = real; mesh->mMaterialIndex = real;
// Build the output material // Build the output material
Material& srcMat = materials[i]; Material &srcMat = materials[i];
mat->AddProperty(&srcMat.diffuse, 1,AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&srcMat.diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty(&srcMat.specular, 1,AI_MATKEY_COLOR_SPECULAR); mat->AddProperty(&srcMat.specular, 1, AI_MATKEY_COLOR_SPECULAR);
mat->AddProperty(&srcMat.ambient, 1,AI_MATKEY_COLOR_AMBIENT); mat->AddProperty(&srcMat.ambient, 1, AI_MATKEY_COLOR_AMBIENT);
// NOTE: Ignore transparency for the moment - it seems // NOTE: Ignore transparency for the moment - it seems
// unclear how to interpret the data // unclear how to interpret the data
@ -482,57 +455,48 @@ outer:
mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL); mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL);
if (srcMat.name.length) if (srcMat.name.length)
mat->AddProperty(&srcMat.name,AI_MATKEY_NAME); mat->AddProperty(&srcMat.name, AI_MATKEY_NAME);
// Add a texture // Add a texture
if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures) if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures) {
{
srcMat.name.data[0] = '*'; srcMat.name.data[0] = '*';
srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1],1000, srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1], 1000,
(srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real)); (srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real));
mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0)); mat->AddProperty(&srcMat.name, AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
mesh->mNumFaces = (unsigned int)fidx[i].size(); mesh->mNumFaces = (unsigned int)fidx[i].size();
aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; aiFace *faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
// Now build the output mesh. First find out how many // Now build the output mesh. First find out how many
// vertices we'll need // vertices we'll need
for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end(); for (FaceIdxArray::const_iterator it = fidx[i].begin(), end = fidx[i].end();
it != end; ++it) it != end; ++it) {
{ mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[(*it).second].indices.size();
mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[
(*it).second].indices.size();
} }
aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; aiVector3D *verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
aiVector3D* norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices]; aiVector3D *norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
aiVector3D* uv; aiVector3D *uv = nullptr;
if (real < pScene->mNumTextures) if (real < pScene->mNumTextures) {
{ uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; mesh->mNumUVComponents[0] = 2;
mesh->mNumUVComponents[0] = 2;
} }
else uv = NULL;
// Build the final array // Build the final array
unsigned int cnt = 0; unsigned int cnt = 0;
for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end(); for (FaceIdxArray::const_iterator it = fidx[i].begin(), end = fidx[i].end();
it != end; ++it, ++faces) it != end; ++it, ++faces) {
{ Mesh &curMesh = meshes[(*it).first];
Mesh& curMesh = meshes[(*it).first];
Face &face = curMesh.faces[(*it).second]; Face &face = curMesh.faces[(*it).second];
faces->mNumIndices = (unsigned int)face.indices.size(); faces->mNumIndices = (unsigned int)face.indices.size();
faces->mIndices = new unsigned int [faces->mNumIndices]; faces->mIndices = new unsigned int[faces->mNumIndices];
aiVector3D faceNormal; aiVector3D faceNormal;
bool fnOK = false; bool fnOK = false;
for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts) for (unsigned int n = 0; n < faces->mNumIndices; ++n, ++cnt, ++norms, ++verts) {
{ if (face.indices[n] >= curMesh.verts.size()) {
if (face.indices[n] >= curMesh.verts.size())
{
ASSIMP_LOG_WARN("Quick3D: Vertex index overflow"); ASSIMP_LOG_WARN("Quick3D: Vertex index overflow");
face.indices[n] = 0; face.indices[n] = 0;
} }
@ -540,11 +504,9 @@ outer:
// copy vertices // copy vertices
*verts = curMesh.verts[face.indices[n]]; *verts = curMesh.verts[face.indices[n]];
if (face.indices[n] >= curMesh.normals.size() && faces->mNumIndices >= 3) if (face.indices[n] >= curMesh.normals.size() && faces->mNumIndices >= 3) {
{
// we have no normal here - assign the face normal // we have no normal here - assign the face normal
if (!fnOK) if (!fnOK) {
{
const aiVector3D &pV1 = curMesh.verts[face.indices[0]]; const aiVector3D &pV1 = curMesh.verts[face.indices[0]];
const aiVector3D &pV2 = curMesh.verts[face.indices[1]]; const aiVector3D &pV2 = curMesh.verts[face.indices[1]];
const aiVector3D &pV3 = curMesh.verts[face.indices.size() - 1]; const aiVector3D &pV3 = curMesh.verts[face.indices.size() - 1];
@ -557,16 +519,12 @@ outer:
} }
// copy texture coordinates // copy texture coordinates
if (uv && curMesh.uv.size()) if (uv && curMesh.uv.size()) {
{
if (curMesh.prevUVIdx != 0xffffffff && curMesh.uv.size() >= curMesh.verts.size()) // workaround if (curMesh.prevUVIdx != 0xffffffff && curMesh.uv.size() >= curMesh.verts.size()) // workaround
{ {
*uv = curMesh.uv[face.indices[n]]; *uv = curMesh.uv[face.indices[n]];
} } else {
else if (face.uvindices[n] >= curMesh.uv.size()) {
{
if (face.uvindices[n] >= curMesh.uv.size())
{
ASSIMP_LOG_WARN("Quick3D: Texture coordinate index overflow"); ASSIMP_LOG_WARN("Quick3D: Texture coordinate index overflow");
face.uvindices[n] = 0; face.uvindices[n] = 0;
} }
@ -579,7 +537,6 @@ outer:
// setup the new vertex index // setup the new vertex index
faces->mIndices[n] = cnt; faces->mIndices[n] = cnt;
} }
} }
++real; ++real;
} }
@ -589,8 +546,8 @@ 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( /*pScene->mRootNode->mTransformation *= aiMatrix4x4(
@ -600,13 +557,12 @@ outer:
0.f, 0.f, 0.f, 1.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;
if (pScene->mRootNode->mNumChildren) if (pScene->mRootNode->mNumChildren) {
{ pScene->mRootNode->mChildren = new aiNode *[pScene->mRootNode->mNumChildren];
pScene->mRootNode->mChildren = new aiNode* [ pScene->mRootNode->mNumChildren ];
// the light source // the light source
aiNode* nd = pScene->mRootNode->mChildren[0] = new aiNode(); aiNode *nd = pScene->mRootNode->mChildren[0] = new aiNode();
nd->mParent = pScene->mRootNode; nd->mParent = pScene->mRootNode;
nd->mName.Set("Q3DLight"); nd->mName.Set("Q3DLight");
nd->mTransformation = pScene->mRootNode->mTransformation; nd->mTransformation = pScene->mRootNode->mTransformation;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -45,18 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the RAW importer class * @brief Implementation of the RAW importer class
*/ */
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER #ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
// internal headers // internal headers
#include "RawLoader.h" #include "RawLoader.h"
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
using namespace Assimp; using namespace Assimp;
@ -75,146 +72,129 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
RAWImporter::RAWImporter() RAWImporter::RAWImporter() {
{} // empty
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
RAWImporter::~RAWImporter()
{}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
{
return SimpleExtensionCheck(pFile,"raw");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* RAWImporter::GetInfo () const // Destructor, private as well
{ RAWImporter::~RAWImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool RAWImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "raw");
}
// ------------------------------------------------------------------------------------------------
const aiImporterDesc *RAWImporter::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 RAWImporter::InternReadFile( const std::string& pFile, void RAWImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler) 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.get() == NULL) { if (file.get() == nullptr) {
throw DeadlyImportError( "Failed to open RAW file " + pFile + "."); throw DeadlyImportError("Failed to open RAW 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
// (terminate it with zero) // (terminate it with zero)
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];
// list of groups loaded from the file // list of groups loaded from the file
std::vector< GroupInformation > outGroups(1,GroupInformation("<default>")); std::vector<GroupInformation> outGroups(1, GroupInformation("<default>"));
std::vector< GroupInformation >::iterator curGroup = outGroups.begin(); std::vector<GroupInformation>::iterator curGroup = outGroups.begin();
// now read all lines // now read all lines
char line[4096]; char line[4096];
while (GetNextLine(buffer,line)) while (GetNextLine(buffer, line)) {
{
// if the line starts with a non-numeric identifier, it marks // if the line starts with a non-numeric identifier, it marks
// the beginning of a new group // the beginning of a new group
const char* sz = line;SkipSpaces(&sz); const char *sz = line;
if (IsLineEnd(*sz))continue; SkipSpaces(&sz);
if (!IsNumeric(*sz)) if (IsLineEnd(*sz)) continue;
{ if (!IsNumeric(*sz)) {
const char* sz2 = sz; const char *sz2 = sz;
while (!IsSpaceOrNewLine(*sz2))++sz2; while (!IsSpaceOrNewLine(*sz2))
const unsigned int length = (unsigned int)(sz2-sz); ++sz2;
const unsigned int length = (unsigned int)(sz2 - sz);
// find an existing group with this name // find an existing group with this name
for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end(); for (std::vector<GroupInformation>::iterator it = outGroups.begin(), end = outGroups.end();
it != end;++it) it != end; ++it) {
{ if (length == (*it).name.length() && !::strcmp(sz, (*it).name.c_str())) {
if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str())) curGroup = it;
{ sz2 = nullptr;
curGroup = it;sz2 = NULL;
break; break;
} }
} }
if (sz2) if (sz2) {
{ outGroups.push_back(GroupInformation(std::string(sz, length)));
outGroups.push_back(GroupInformation(std::string(sz,length))); curGroup = outGroups.end() - 1;
curGroup = outGroups.end()-1;
} }
} } else {
else
{
// there can be maximally 12 floats plus an extra texture file name // there can be maximally 12 floats plus an extra texture file name
float data[12]; float data[12];
unsigned int num; unsigned int num;
for (num = 0; num < 12;++num) for (num = 0; num < 12; ++num) {
{ if (!SkipSpaces(&sz) || !IsNumeric(*sz)) break;
if(!SkipSpaces(&sz) || !IsNumeric(*sz))break; sz = fast_atoreal_move<float>(sz, data[num]);
sz = fast_atoreal_move<float>(sz,data[num]);
} }
if (num != 12 && num != 9) if (num != 12 && num != 9) {
{
ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture"); ASSIMP_LOG_ERROR("A line may have either 9 or 12 floats and an optional texture");
continue; continue;
} }
MeshInformation* output = NULL; MeshInformation *output = nullptr;
const char* sz2 = sz; const char *sz2 = sz;
unsigned int length; unsigned int length;
if (!IsLineEnd(*sz)) if (!IsLineEnd(*sz)) {
{ while (!IsSpaceOrNewLine(*sz2))
while (!IsSpaceOrNewLine(*sz2))++sz2; ++sz2;
length = (unsigned int)(sz2-sz); length = (unsigned int)(sz2 - sz);
} } else if (9 == num) {
else if (9 == num)
{
sz = "%default%"; sz = "%default%";
length = 9; length = 9;
} } else {
else
{
sz = ""; sz = "";
length = 0; length = 0;
} }
// search in the list of meshes whether we have one with this texture // search in the list of meshes whether we have one with this texture
for (auto &mesh : (*curGroup).meshes) for (auto &mesh : (*curGroup).meshes) {
{ if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true)) {
if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true))
{
output = &mesh; output = &mesh;
break; break;
} }
} }
// if we don't have the mesh, create it // if we don't have the mesh, create it
if (!output) if (!output) {
{ (*curGroup).meshes.push_back(MeshInformation(std::string(sz, length)));
(*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
output = &((*curGroup).meshes.back()); output = &((*curGroup).meshes.back());
} }
if (12 == num) if (12 == num) {
{ aiColor4D v(data[0], data[1], data[2], 1.0f);
aiColor4D v(data[0],data[1],data[2],1.0f);
output->colors.push_back(v); output->colors.push_back(v);
output->colors.push_back(v); output->colors.push_back(v);
output->colors.push_back(v); output->colors.push_back(v);
output->vertices.push_back(aiVector3D(data[3],data[4],data[5])); output->vertices.push_back(aiVector3D(data[3], data[4], data[5]));
output->vertices.push_back(aiVector3D(data[6],data[7],data[8])); output->vertices.push_back(aiVector3D(data[6], data[7], data[8]));
output->vertices.push_back(aiVector3D(data[9],data[10],data[11])); output->vertices.push_back(aiVector3D(data[9], data[10], data[11]));
} } else {
else output->vertices.push_back(aiVector3D(data[0], data[1], data[2]));
{ output->vertices.push_back(aiVector3D(data[3], data[4], data[5]));
output->vertices.push_back(aiVector3D(data[0],data[1],data[2])); output->vertices.push_back(aiVector3D(data[6], data[7], data[8]));
output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
} }
} }
} }
@ -224,105 +204,96 @@ void RAWImporter::InternReadFile( const std::string& pFile,
// count the number of valid groups // count the number of valid groups
// (meshes can't be empty) // (meshes can't be empty)
for (auto & outGroup : outGroups) for (auto &outGroup : outGroups) {
{ if (!outGroup.meshes.empty()) {
if (!outGroup.meshes.empty())
{
++pScene->mRootNode->mNumChildren; ++pScene->mRootNode->mNumChildren;
pScene->mNumMeshes += (unsigned int) outGroup.meshes.size(); pScene->mNumMeshes += (unsigned int)outGroup.meshes.size();
} }
} }
if (!pScene->mNumMeshes) if (!pScene->mNumMeshes) {
{
throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty."); throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
} }
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
aiNode** cc; aiNode **cc;
if (1 == pScene->mRootNode->mNumChildren) if (1 == pScene->mRootNode->mNumChildren) {
{
cc = &pScene->mRootNode; cc = &pScene->mRootNode;
pScene->mRootNode->mNumChildren = 0; pScene->mRootNode->mNumChildren = 0;
} else { } else {
cc = new aiNode*[pScene->mRootNode->mNumChildren]; cc = new aiNode *[pScene->mRootNode->mNumChildren];
memset(cc, 0, sizeof(aiNode*) * pScene->mRootNode->mNumChildren); memset(cc, 0, sizeof(aiNode *) * pScene->mRootNode->mNumChildren);
pScene->mRootNode->mChildren = cc; pScene->mRootNode->mChildren = cc;
} }
pScene->mNumMaterials = pScene->mNumMeshes; pScene->mNumMaterials = pScene->mNumMeshes;
aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; aiMaterial **mats = pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
unsigned int meshIdx = 0; unsigned int meshIdx = 0;
for (auto & outGroup : outGroups) for (auto &outGroup : outGroups) {
{ if (outGroup.meshes.empty()) continue;
if (outGroup.meshes.empty())continue;
aiNode* node; aiNode *node;
if (pScene->mRootNode->mNumChildren) if (pScene->mRootNode->mNumChildren) {
{
node = *cc = new aiNode(); node = *cc = new aiNode();
node->mParent = pScene->mRootNode; node->mParent = pScene->mRootNode;
} } else
else node = *cc; node = *cc;
node->mName.Set(outGroup.name); node->mName.Set(outGroup.name);
// add all meshes // add all meshes
node->mNumMeshes = (unsigned int) outGroup.meshes.size(); node->mNumMeshes = (unsigned int)outGroup.meshes.size();
unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ]; unsigned int *pi = node->mMeshes = new unsigned int[node->mNumMeshes];
for (std::vector< MeshInformation >::iterator it2 = outGroup.meshes.begin(), for (std::vector<MeshInformation>::iterator it2 = outGroup.meshes.begin(),
end2 = outGroup.meshes.end(); it2 != end2; ++it2) end2 = outGroup.meshes.end();
{ it2 != end2; ++it2) {
ai_assert(!(*it2).vertices.empty()); ai_assert(!(*it2).vertices.empty());
// allocate the mesh // allocate the mesh
*pi++ = meshIdx; *pi++ = meshIdx;
aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh(); aiMesh *mesh = pScene->mMeshes[meshIdx] = new aiMesh();
mesh->mMaterialIndex = meshIdx++; mesh->mMaterialIndex = meshIdx++;
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE; mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// allocate storage for the vertex components and copy them // allocate storage for the vertex components and copy them
mesh->mNumVertices = (unsigned int)(*it2).vertices.size(); mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
mesh->mVertices = new aiVector3D[ mesh->mNumVertices ]; mesh->mVertices = new aiVector3D[mesh->mNumVertices];
::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices); ::memcpy(mesh->mVertices, &(*it2).vertices[0], sizeof(aiVector3D) * mesh->mNumVertices);
if ((*it2).colors.size()) if ((*it2).colors.size()) {
{
ai_assert((*it2).colors.size() == mesh->mNumVertices); ai_assert((*it2).colors.size() == mesh->mNumVertices);
mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ]; mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices); ::memcpy(mesh->mColors[0], &(*it2).colors[0], sizeof(aiColor4D) * mesh->mNumVertices);
} }
// generate triangles // generate triangles
ai_assert(0 == mesh->mNumVertices % 3); ai_assert(0 == mesh->mNumVertices % 3);
aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ]; aiFace *fc = mesh->mFaces = new aiFace[mesh->mNumFaces = mesh->mNumVertices / 3];
aiFace* const fcEnd = fc + mesh->mNumFaces; aiFace *const fcEnd = fc + mesh->mNumFaces;
unsigned int n = 0; unsigned int n = 0;
while (fc != fcEnd) while (fc != fcEnd) {
{ aiFace &f = *fc++;
aiFace& f = *fc++;
f.mIndices = new unsigned int[f.mNumIndices = 3]; f.mIndices = new unsigned int[f.mNumIndices = 3];
for (unsigned int m = 0; m < 3;++m) for (unsigned int m = 0; m < 3; ++m)
f.mIndices[m] = n++; f.mIndices[m] = n++;
} }
// generate a material for the mesh // generate a material for the mesh
aiMaterial* mat = new aiMaterial(); aiMaterial *mat = new aiMaterial();
aiColor4D clr(1.0f,1.0f,1.0f,1.0f); aiColor4D clr(1.0f, 1.0f, 1.0f, 1.0f);
if ("%default%" == (*it2).name) // a gray default material if ("%default%" == (*it2).name) // a gray default material
{ {
clr.r = clr.g = clr.b = 0.6f; clr.r = clr.g = clr.b = 0.6f;
} } else if ((*it2).name.length() > 0) // a texture
else if ((*it2).name.length() > 0) // a texture
{ {
aiString s; aiString s;
s.Set((*it2).name); s.Set((*it2).name);
mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0)); mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
} }
mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty<aiColor4D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
*mats++ = mat; *mats++ = mat;
} }
} }

View File

@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Nevertheless, this implementation is reasonably complete. * Nevertheless, this implementation is reasonably complete.
*/ */
#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER #ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
// internal headers // internal headers
@ -60,15 +59,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StreamReader.h> #include <assimp/StreamReader.h>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#ifdef ASSIMP_USE_HUNTER #ifdef ASSIMP_USE_HUNTER
# include <utf8/utf8.h> #include <utf8/utf8.h>
#else #else
//# include "../contrib/ConvertUTF/ConvertUTF.h" //# include "../contrib/ConvertUTF/ConvertUTF.h"
# include "../contrib/utf8cpp/source/utf8.h" #include "../contrib/utf8cpp/source/utf8.h"
#endif #endif
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <map> #include <map>
@ -86,14 +85,14 @@ static const aiImporterDesc desc = {
}; };
struct SIBChunk { struct SIBChunk {
uint32_t Tag; uint32_t Tag;
uint32_t Size; uint32_t Size;
} PACK_STRUCT; } PACK_STRUCT;
enum { enum {
POS, POS,
NRM, NRM,
UV, UV,
N N
}; };
@ -122,14 +121,14 @@ struct SIBObject {
}; };
struct SIB { struct SIB {
std::vector<aiMaterial*> mtls; std::vector<aiMaterial *> mtls;
std::vector<aiMesh*> meshes; std::vector<aiMesh *> meshes;
std::vector<aiLight*> lights; std::vector<aiLight *> lights;
std::vector<SIBObject> objs, insts; std::vector<SIBObject> objs, insts;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) { static SIBEdge &GetEdge(SIBMesh *mesh, uint32_t posA, uint32_t posB) {
SIBPair pair = (posA < posB) ? SIBPair(posA, posB) : SIBPair(posB, posA); SIBPair pair = (posA < posB) ? SIBPair(posA, posB) : SIBPair(posB, posA);
std::map<SIBPair, uint32_t>::iterator it = mesh->edgeMap.find(pair); std::map<SIBPair, uint32_t>::iterator it = mesh->edgeMap.find(pair);
if (it != mesh->edgeMap.end()) if (it != mesh->edgeMap.end())
@ -146,10 +145,9 @@ static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Helpers for reading chunked data. // Helpers for reading chunked data.
#define TAG(A,B,C,D) ((A << 24) | (B << 16) | (C << 8) | D) #define TAG(A, B, C, D) ((A << 24) | (B << 16) | (C << 8) | D)
static SIBChunk ReadChunk(StreamReaderLE* stream) static SIBChunk ReadChunk(StreamReaderLE *stream) {
{
SIBChunk chunk; SIBChunk chunk;
chunk.Tag = stream->GetU4(); chunk.Tag = stream->GetU4();
chunk.Size = stream->GetU4(); chunk.Size = stream->GetU4();
@ -159,8 +157,7 @@ static SIBChunk ReadChunk(StreamReaderLE* stream)
return chunk; return chunk;
} }
static aiColor3D ReadColor(StreamReaderLE* stream) static aiColor3D ReadColor(StreamReaderLE *stream) {
{
float r = stream->GetF4(); float r = stream->GetF4();
float g = stream->GetF4(); float g = stream->GetF4();
float b = stream->GetF4(); float b = stream->GetF4();
@ -168,37 +165,36 @@ static aiColor3D ReadColor(StreamReaderLE* stream)
return aiColor3D(r, g, b); return aiColor3D(r, g, b);
} }
static void UnknownChunk(StreamReaderLE* /*stream*/, const SIBChunk& chunk) static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) {
{
char temp[5] = { char temp[5] = {
static_cast<char>(( chunk.Tag>>24 ) & 0xff), static_cast<char>((chunk.Tag >> 24) & 0xff),
static_cast<char>(( chunk.Tag>>16 ) & 0xff), static_cast<char>((chunk.Tag >> 16) & 0xff),
static_cast<char>(( chunk.Tag>>8 ) & 0xff), static_cast<char>((chunk.Tag >> 8) & 0xff),
static_cast<char>(chunk.Tag & 0xff), '\0' static_cast<char>(chunk.Tag & 0xff), '\0'
}; };
ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '",temp,"' chunk.")); ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", temp, "' chunk."));
} }
// Reads a UTF-16LE string and returns it at UTF-8. // Reads a UTF-16LE string and returns it at UTF-8.
static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) { static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) {
if ( nullptr == stream || 0 == numWChars ) { if (nullptr == stream || 0 == numWChars) {
static const aiString empty; static const aiString empty;
return empty; return empty;
} }
// Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8) // Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
std::vector<unsigned char> str; std::vector<unsigned char> str;
str.reserve( numWChars * 4 + 1 ); str.reserve(numWChars * 4 + 1);
uint16_t *temp = new uint16_t[ numWChars ]; uint16_t *temp = new uint16_t[numWChars];
for ( uint32_t n = 0; n < numWChars; ++n ) { for (uint32_t n = 0; n < numWChars; ++n) {
temp[ n ] = stream->GetU2(); temp[n] = stream->GetU2();
} }
// Convert it and NUL-terminate. // Convert it and NUL-terminate.
const uint16_t *start( temp ), *end( temp + numWChars ); const uint16_t *start(temp), *end(temp + numWChars);
utf8::utf16to8( start, end, back_inserter( str ) ); utf8::utf16to8(start, end, back_inserter(str));
str[ str.size() - 1 ] = '\0'; str[str.size() - 1] = '\0';
// Return the final string. // Return the final string.
aiString result = aiString((const char *)&str[0]); aiString result = aiString((const char *)&str[0]);
@ -221,52 +217,49 @@ SIBImporter::~SIBImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// 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& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const { bool SIBImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "sib"); return SimpleExtensionCheck(pFile, "sib");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* SIBImporter::GetInfo () const { const aiImporterDesc *SIBImporter::GetInfo() const {
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) { static void ReadVerts(SIBMesh *mesh, StreamReaderLE *stream, uint32_t count) {
if ( nullptr == mesh || nullptr == stream ) { if (nullptr == mesh || nullptr == stream) {
return; return;
} }
mesh->pos.resize(count); mesh->pos.resize(count);
for ( uint32_t n=0; n<count; ++n ) { for (uint32_t n = 0; n < count; ++n) {
mesh->pos[ n ].x = stream->GetF4(); mesh->pos[n].x = stream->GetF4();
mesh->pos[ n ].y = stream->GetF4(); mesh->pos[n].y = stream->GetF4();
mesh->pos[ n ].z = stream->GetF4(); mesh->pos[n].z = stream->GetF4();
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream) static void ReadFaces(SIBMesh *mesh, StreamReaderLE *stream) {
{
uint32_t ptIdx = 0; uint32_t ptIdx = 0;
while (stream->GetRemainingSizeToLimit() > 0) while (stream->GetRemainingSizeToLimit() > 0) {
{
uint32_t numPoints = stream->GetU4(); uint32_t numPoints = stream->GetU4();
// Store room for the N index channels, plus the point count. // Store room for the N index channels, plus the point count.
size_t pos = mesh->idx.size() + 1; size_t pos = mesh->idx.size() + 1;
mesh->idx.resize(pos + numPoints*N); mesh->idx.resize(pos + numPoints * N);
mesh->idx[pos-1] = numPoints; mesh->idx[pos - 1] = numPoints;
uint32_t *idx = &mesh->idx[pos]; uint32_t *idx = &mesh->idx[pos];
mesh->faceStart.push_back(static_cast<uint32_t>(pos-1)); mesh->faceStart.push_back(static_cast<uint32_t>(pos - 1));
mesh->mtls.push_back(0); mesh->mtls.push_back(0);
// Read all the position data. // Read all the position data.
// UV/normals will be supplied later. // UV/normals will be supplied later.
// Positions are supplied indexed already, so we preserve that // Positions are supplied indexed already, so we preserve that
// mapping. UVs are supplied uniquely, so we allocate unique indices. // mapping. UVs are supplied uniquely, so we allocate unique indices.
for (uint32_t n=0;n<numPoints;n++,idx+=N,ptIdx++) for (uint32_t n = 0; n < numPoints; n++, idx += N, ptIdx++) {
{
uint32_t p = stream->GetU4(); uint32_t p = stream->GetU4();
if (p >= mesh->pos.size()) if (p >= mesh->pos.size())
throw DeadlyImportError("Vertex index is out of range."); throw DeadlyImportError("Vertex index is out of range.");
@ -277,17 +270,15 @@ static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream)
} }
// Allocate data channels for normals/UVs. // Allocate data channels for normals/UVs.
mesh->nrm.resize(ptIdx, aiVector3D(0,0,0)); mesh->nrm.resize(ptIdx, aiVector3D(0, 0, 0));
mesh->uv.resize(ptIdx, aiVector3D(0,0,0)); mesh->uv.resize(ptIdx, aiVector3D(0, 0, 0));
mesh->numPts = ptIdx; mesh->numPts = ptIdx;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream) static void ReadUVs(SIBMesh *mesh, StreamReaderLE *stream) {
{ while (stream->GetRemainingSizeToLimit() > 0) {
while (stream->GetRemainingSizeToLimit() > 0)
{
uint32_t faceIdx = stream->GetU4(); uint32_t faceIdx = stream->GetU4();
uint32_t numPoints = stream->GetU4(); uint32_t numPoints = stream->GetU4();
@ -297,8 +288,7 @@ static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream)
uint32_t pos = mesh->faceStart[faceIdx]; uint32_t pos = mesh->faceStart[faceIdx];
uint32_t *idx = &mesh->idx[pos + 1]; uint32_t *idx = &mesh->idx[pos + 1];
for (uint32_t n=0;n<numPoints;n++,idx+=N) for (uint32_t n = 0; n < numPoints; n++, idx += N) {
{
uint32_t id = idx[UV]; uint32_t id = idx[UV];
mesh->uv[id].x = stream->GetF4(); mesh->uv[id].x = stream->GetF4();
mesh->uv[id].y = stream->GetF4(); mesh->uv[id].y = stream->GetF4();
@ -307,19 +297,16 @@ static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadMtls(SIBMesh* mesh, StreamReaderLE* stream) static void ReadMtls(SIBMesh *mesh, StreamReaderLE *stream) {
{
// Material assignments are stored run-length encoded. // Material assignments are stored run-length encoded.
// Also, we add 1 to each material so that we can use mtl #0 // Also, we add 1 to each material so that we can use mtl #0
// as the default material. // as the default material.
uint32_t prevFace = stream->GetU4(); uint32_t prevFace = stream->GetU4();
uint32_t prevMtl = stream->GetU4() + 1; uint32_t prevMtl = stream->GetU4() + 1;
while (stream->GetRemainingSizeToLimit() > 0) while (stream->GetRemainingSizeToLimit() > 0) {
{
uint32_t face = stream->GetU4(); uint32_t face = stream->GetU4();
uint32_t mtl = stream->GetU4() + 1; uint32_t mtl = stream->GetU4() + 1;
while (prevFace < face) while (prevFace < face) {
{
if (prevFace >= mesh->mtls.size()) if (prevFace >= mesh->mtls.size())
throw DeadlyImportError("Invalid face index."); throw DeadlyImportError("Invalid face index.");
mesh->mtls[prevFace++] = prevMtl; mesh->mtls[prevFace++] = prevMtl;
@ -334,8 +321,7 @@ static void ReadMtls(SIBMesh* mesh, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadAxis(aiMatrix4x4& axis, StreamReaderLE* stream) static void ReadAxis(aiMatrix4x4 &axis, StreamReaderLE *stream) {
{
axis.a4 = stream->GetF4(); axis.a4 = stream->GetF4();
axis.b4 = stream->GetF4(); axis.b4 = stream->GetF4();
axis.c4 = stream->GetF4(); axis.c4 = stream->GetF4();
@ -355,10 +341,8 @@ static void ReadAxis(aiMatrix4x4& axis, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadEdges(SIBMesh* mesh, StreamReaderLE* stream) static void ReadEdges(SIBMesh *mesh, StreamReaderLE *stream) {
{ while (stream->GetRemainingSizeToLimit() > 0) {
while (stream->GetRemainingSizeToLimit() > 0)
{
uint32_t posA = stream->GetU4(); uint32_t posA = stream->GetU4();
uint32_t posB = stream->GetU4(); uint32_t posB = stream->GetU4();
GetEdge(mesh, posA, posB); GetEdge(mesh, posA, posB);
@ -366,10 +350,8 @@ static void ReadEdges(SIBMesh* mesh, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadCreases(SIBMesh* mesh, StreamReaderLE* stream) static void ReadCreases(SIBMesh *mesh, StreamReaderLE *stream) {
{ while (stream->GetRemainingSizeToLimit() > 0) {
while (stream->GetRemainingSizeToLimit() > 0)
{
uint32_t edge = stream->GetU4(); uint32_t edge = stream->GetU4();
if (edge >= mesh->edges.size()) if (edge >= mesh->edges.size())
throw DeadlyImportError("SIB: Invalid edge index."); throw DeadlyImportError("SIB: Invalid edge index.");
@ -378,22 +360,19 @@ static void ReadCreases(SIBMesh* mesh, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ConnectFaces(SIBMesh* mesh) static void ConnectFaces(SIBMesh *mesh) {
{
// Find faces connected to each edge. // Find faces connected to each edge.
size_t numFaces = mesh->faceStart.size(); size_t numFaces = mesh->faceStart.size();
for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++) for (size_t faceIdx = 0; faceIdx < numFaces; faceIdx++) {
{
uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]]; uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++; uint32_t numPoints = *idx++;
uint32_t prev = idx[(numPoints-1)*N+POS]; uint32_t prev = idx[(numPoints - 1) * N + POS];
for (uint32_t i=0;i<numPoints;i++,idx+=N) for (uint32_t i = 0; i < numPoints; i++, idx += N) {
{
uint32_t next = idx[POS]; uint32_t next = idx[POS];
// Find this edge. // Find this edge.
SIBEdge& edge = GetEdge(mesh, prev, next); SIBEdge &edge = GetEdge(mesh, prev, next);
// Link this face onto it. // Link this face onto it.
// This gives potentially undesirable normals when used // This gives potentially undesirable normals when used
@ -409,45 +388,39 @@ static void ConnectFaces(SIBMesh* mesh)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_t pos, static aiVector3D CalculateVertexNormal(SIBMesh *mesh, uint32_t faceIdx, uint32_t pos,
const std::vector<aiVector3D>& faceNormals) const std::vector<aiVector3D> &faceNormals) {
{
// Creased edges complicate this. We need to find the start/end range of the // Creased edges complicate this. We need to find the start/end range of the
// ring of faces that touch this position. // ring of faces that touch this position.
// We do this in two passes. The first pass is to find the end of the range, // We do this in two passes. The first pass is to find the end of the range,
// the second is to work backwards to the start and calculate the final normal. // the second is to work backwards to the start and calculate the final normal.
aiVector3D vtxNormal; aiVector3D vtxNormal;
for (int pass=0;pass<2;pass++) for (int pass = 0; pass < 2; pass++) {
{
vtxNormal = aiVector3D(0, 0, 0); vtxNormal = aiVector3D(0, 0, 0);
uint32_t startFaceIdx = faceIdx; uint32_t startFaceIdx = faceIdx;
uint32_t prevFaceIdx = faceIdx; uint32_t prevFaceIdx = faceIdx;
// Process each connected face. // Process each connected face.
while (true) while (true) {
{
// Accumulate the face normal. // Accumulate the face normal.
vtxNormal += faceNormals[faceIdx]; vtxNormal += faceNormals[faceIdx];
uint32_t nextFaceIdx = 0xffffffff; uint32_t nextFaceIdx = 0xffffffff;
// Move to the next edge sharing this position. // Move to the next edge sharing this position.
uint32_t* idx = &mesh->idx[mesh->faceStart[faceIdx]]; uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++; uint32_t numPoints = *idx++;
uint32_t posA = idx[(numPoints-1)*N+POS]; uint32_t posA = idx[(numPoints - 1) * N + POS];
for (uint32_t n=0;n<numPoints;n++,idx+=N) for (uint32_t n = 0; n < numPoints; n++, idx += N) {
{
uint32_t posB = idx[POS]; uint32_t posB = idx[POS];
// Test if this edge shares our target position. // Test if this edge shares our target position.
if (posA == pos || posB == pos) if (posA == pos || posB == pos) {
{ SIBEdge &edge = GetEdge(mesh, posA, posB);
SIBEdge& edge = GetEdge(mesh, posA, posB);
// Non-manifold meshes can produce faces which share // Non-manifold meshes can produce faces which share
// positions but have no edge entry, so check it. // positions but have no edge entry, so check it.
if (edge.faceA == faceIdx || edge.faceB == faceIdx) if (edge.faceA == faceIdx || edge.faceB == faceIdx) {
{
// Move to whichever side we didn't just come from. // Move to whichever side we didn't just come from.
if (!edge.creased) { if (!edge.creased) {
if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff) if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff)
@ -479,24 +452,21 @@ static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void CalculateNormals(SIBMesh* mesh) static void CalculateNormals(SIBMesh *mesh) {
{
size_t numFaces = mesh->faceStart.size(); size_t numFaces = mesh->faceStart.size();
// Calculate face normals. // Calculate face normals.
std::vector<aiVector3D> faceNormals(numFaces); std::vector<aiVector3D> faceNormals(numFaces);
for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++) for (size_t faceIdx = 0; faceIdx < numFaces; faceIdx++) {
{ uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t* idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++; uint32_t numPoints = *idx++;
aiVector3D faceNormal(0, 0, 0); aiVector3D faceNormal(0, 0, 0);
uint32_t *prev = &idx[(numPoints-1)*N]; uint32_t *prev = &idx[(numPoints - 1) * N];
for (uint32_t i=0;i<numPoints;i++) for (uint32_t i = 0; i < numPoints; i++) {
{ uint32_t *next = &idx[i * N];
uint32_t *next = &idx[i*N];
faceNormal += mesh->pos[prev[POS]] ^ mesh->pos[next[POS]]; faceNormal += mesh->pos[prev[POS]] ^ mesh->pos[next[POS]];
prev = next; prev = next;
@ -506,15 +476,13 @@ static void CalculateNormals(SIBMesh* mesh)
} }
// Calculate vertex normals. // Calculate vertex normals.
for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++) for (size_t faceIdx = 0; faceIdx < numFaces; faceIdx++) {
{ uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t* idx = &mesh->idx[mesh->faceStart[faceIdx]];
uint32_t numPoints = *idx++; uint32_t numPoints = *idx++;
for (uint32_t i=0;i<numPoints;i++) for (uint32_t i = 0; i < numPoints; i++) {
{ uint32_t pos = idx[i * N + POS];
uint32_t pos = idx[i*N+POS]; uint32_t nrm = idx[i * N + NRM];
uint32_t nrm = idx[i*N+NRM];
aiVector3D vtxNorm = CalculateVertexNormal(mesh, static_cast<uint32_t>(faceIdx), pos, faceNormals); aiVector3D vtxNorm = CalculateVertexNormal(mesh, static_cast<uint32_t>(faceIdx), pos, faceNormals);
mesh->nrm[nrm] = vtxNorm; mesh->nrm[nrm] = vtxNorm;
} }
@ -522,43 +490,39 @@ static void CalculateNormals(SIBMesh* mesh)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct TempMesh struct TempMesh {
{
std::vector<aiVector3D> vtx; std::vector<aiVector3D> vtx;
std::vector<aiVector3D> nrm; std::vector<aiVector3D> nrm;
std::vector<aiVector3D> uv; std::vector<aiVector3D> uv;
std::vector<aiFace> faces; std::vector<aiFace> faces;
}; };
static void ReadShape(SIB* sib, StreamReaderLE* stream) static void ReadShape(SIB *sib, StreamReaderLE *stream) {
{
SIBMesh smesh; SIBMesh smesh;
aiString name; aiString name;
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
{
SIBChunk chunk = ReadChunk(stream); SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size); unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag) switch (chunk.Tag) {
{ case TAG('M', 'I', 'R', 'P'): break; // mirror plane maybe?
case TAG('M','I','R','P'): break; // mirror plane maybe? case TAG('I', 'M', 'R', 'P'): break; // instance mirror? (not supported here yet)
case TAG('I','M','R','P'): break; // instance mirror? (not supported here yet) case TAG('D', 'I', 'N', 'F'): break; // display info, not needed
case TAG('D','I','N','F'): break; // display info, not needed case TAG('P', 'I', 'N', 'F'): break; // ?
case TAG('P','I','N','F'): break; // ? case TAG('V', 'M', 'I', 'R'): break; // ?
case TAG('V','M','I','R'): break; // ? case TAG('F', 'M', 'I', 'R'): break; // ?
case TAG('F','M','I','R'): break; // ? case TAG('T', 'X', 'S', 'M'): break; // ?
case TAG('T','X','S','M'): break; // ? case TAG('F', 'A', 'H', 'S'): break; // ?
case TAG('F','A','H','S'): break; // ? case TAG('V', 'R', 'T', 'S'): ReadVerts(&smesh, stream, chunk.Size / 12); break;
case TAG('V','R','T','S'): ReadVerts(&smesh, stream, chunk.Size/12); break; case TAG('F', 'A', 'C', 'S'): ReadFaces(&smesh, stream); break;
case TAG('F','A','C','S'): ReadFaces(&smesh, stream); break; case TAG('F', 'T', 'V', 'S'): ReadUVs(&smesh, stream); break;
case TAG('F','T','V','S'): ReadUVs(&smesh, stream); break; case TAG('S', 'N', 'A', 'M'): name = ReadString(stream, chunk.Size / 2); break;
case TAG('S','N','A','M'): name = ReadString(stream, chunk.Size/2); break; case TAG('F', 'A', 'M', 'A'): ReadMtls(&smesh, stream); break;
case TAG('F','A','M','A'): ReadMtls(&smesh, stream); break; case TAG('A', 'X', 'I', 'S'): ReadAxis(smesh.axis, stream); break;
case TAG('A','X','I','S'): ReadAxis(smesh.axis, stream); break; case TAG('E', 'D', 'G', 'S'): ReadEdges(&smesh, stream); break;
case TAG('E','D','G','S'): ReadEdges(&smesh, stream); break; case TAG('E', 'C', 'R', 'S'): ReadCreases(&smesh, stream); break;
case TAG('E','C','R','S'): ReadCreases(&smesh, stream); break; default: UnknownChunk(stream, chunk); break;
default: UnknownChunk(stream, chunk); break;
} }
stream->SetCurrentPos(stream->GetReadLimit()); stream->SetCurrentPos(stream->GetReadLimit());
@ -585,25 +549,22 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
std::vector<TempMesh> meshes(sib->mtls.size()); std::vector<TempMesh> meshes(sib->mtls.size());
// Un-index the source data and apply to each vertex. // Un-index the source data and apply to each vertex.
for (unsigned fi=0;fi<smesh.faceStart.size();fi++) for (unsigned fi = 0; fi < smesh.faceStart.size(); fi++) {
{
uint32_t start = smesh.faceStart[fi]; uint32_t start = smesh.faceStart[fi];
uint32_t mtl = smesh.mtls[fi]; uint32_t mtl = smesh.mtls[fi];
uint32_t *idx = &smesh.idx[start]; uint32_t *idx = &smesh.idx[start];
if (mtl >= meshes.size()) if (mtl >= meshes.size()) {
{
ASSIMP_LOG_ERROR("SIB: Face material index is invalid."); ASSIMP_LOG_ERROR("SIB: Face material index is invalid.");
mtl = 0; mtl = 0;
} }
TempMesh& dest = meshes[mtl]; TempMesh &dest = meshes[mtl];
aiFace face; aiFace face;
face.mNumIndices = *idx++; face.mNumIndices = *idx++;
face.mIndices = new unsigned[face.mNumIndices]; face.mIndices = new unsigned[face.mNumIndices];
for (unsigned pt=0;pt<face.mNumIndices;pt++,idx+=N) for (unsigned pt = 0; pt < face.mNumIndices; pt++, idx += N) {
{
size_t vtxIdx = dest.vtx.size(); size_t vtxIdx = dest.vtx.size();
face.mIndices[pt] = static_cast<unsigned int>(vtxIdx); face.mIndices[pt] = static_cast<unsigned int>(vtxIdx);
@ -611,7 +572,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
// we did it when creating the data. // we did it when creating the data.
aiVector3D pos = smesh.pos[idx[POS]]; aiVector3D pos = smesh.pos[idx[POS]];
aiVector3D nrm = smesh.nrm[idx[NRM]]; aiVector3D nrm = smesh.nrm[idx[NRM]];
aiVector3D uv = smesh.uv[idx[UV]]; aiVector3D uv = smesh.uv[idx[UV]];
// The verts are supplied in world-space, so let's // The verts are supplied in world-space, so let's
// transform them back into the local space of this mesh: // transform them back into the local space of this mesh:
@ -632,13 +593,12 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
// Now that we know the size of everything, // Now that we know the size of everything,
// we can build the final one-material-per-mesh data. // we can build the final one-material-per-mesh data.
for (size_t n=0;n<meshes.size();n++) for (size_t n = 0; n < meshes.size(); n++) {
{ TempMesh &src = meshes[n];
TempMesh& src = meshes[n];
if (src.faces.empty()) if (src.faces.empty())
continue; continue;
aiMesh* mesh = new aiMesh; aiMesh *mesh = new aiMesh;
mesh->mName = name; mesh->mName = name;
mesh->mNumFaces = static_cast<unsigned int>(src.faces.size()); mesh->mNumFaces = static_cast<unsigned int>(src.faces.size());
mesh->mFaces = new aiFace[mesh->mNumFaces]; mesh->mFaces = new aiFace[mesh->mNumFaces];
@ -649,14 +609,12 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
mesh->mNumUVComponents[0] = 2; mesh->mNumUVComponents[0] = 2;
mesh->mMaterialIndex = static_cast<unsigned int>(n); mesh->mMaterialIndex = static_cast<unsigned int>(n);
for (unsigned i=0;i<mesh->mNumVertices;i++) for (unsigned i = 0; i < mesh->mNumVertices; i++) {
{
mesh->mVertices[i] = src.vtx[i]; mesh->mVertices[i] = src.vtx[i];
mesh->mNormals[i] = src.nrm[i]; mesh->mNormals[i] = src.nrm[i];
mesh->mTextureCoords[0][i] = src.uv[i]; mesh->mTextureCoords[0][i] = src.uv[i];
} }
for (unsigned i=0;i<mesh->mNumFaces;i++) for (unsigned i = 0; i < mesh->mNumFaces; i++) {
{
mesh->mFaces[i] = src.faces[i]; mesh->mFaces[i] = src.faces[i];
} }
@ -668,8 +626,7 @@ static void ReadShape(SIB* sib, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadMaterial(SIB* sib, StreamReaderLE* stream) static void ReadMaterial(SIB *sib, StreamReaderLE *stream) {
{
aiColor3D diff = ReadColor(stream); aiColor3D diff = ReadColor(stream);
aiColor3D ambi = ReadColor(stream); aiColor3D ambi = ReadColor(stream);
aiColor3D spec = ReadColor(stream); aiColor3D spec = ReadColor(stream);
@ -677,11 +634,11 @@ static void ReadMaterial(SIB* sib, StreamReaderLE* stream)
float shiny = (float)stream->GetU4(); float shiny = (float)stream->GetU4();
uint32_t nameLen = stream->GetU4(); uint32_t nameLen = stream->GetU4();
aiString name = ReadString(stream, nameLen/2); aiString name = ReadString(stream, nameLen / 2);
uint32_t texLen = stream->GetU4(); uint32_t texLen = stream->GetU4();
aiString tex = ReadString(stream, texLen/2); aiString tex = ReadString(stream, texLen / 2);
aiMaterial* mtl = new aiMaterial(); aiMaterial *mtl = new aiMaterial();
mtl->AddProperty(&diff, 1, AI_MATKEY_COLOR_DIFFUSE); mtl->AddProperty(&diff, 1, AI_MATKEY_COLOR_DIFFUSE);
mtl->AddProperty(&ambi, 1, AI_MATKEY_COLOR_AMBIENT); mtl->AddProperty(&ambi, 1, AI_MATKEY_COLOR_AMBIENT);
mtl->AddProperty(&spec, 1, AI_MATKEY_COLOR_SPECULAR); mtl->AddProperty(&spec, 1, AI_MATKEY_COLOR_SPECULAR);
@ -697,8 +654,7 @@ static void ReadMaterial(SIB* sib, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadLightInfo(aiLight* light, StreamReaderLE* stream) static void ReadLightInfo(aiLight *light, StreamReaderLE *stream) {
{
uint32_t type = stream->GetU4(); uint32_t type = stream->GetU4();
switch (type) { switch (type) {
case 0: light->mType = aiLightSource_POINT; break; case 0: light->mType = aiLightSource_POINT; break;
@ -728,7 +684,7 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
// 99% and 1% percentiles. // 99% and 1% percentiles.
// OpenGL: I = cos(angle)^E // OpenGL: I = cos(angle)^E
// Solving: angle = acos(I^(1/E)) // Solving: angle = acos(I^(1/E))
ai_real E = ai_real( 1.0 ) / std::max(spotExponent, (ai_real)0.00001); ai_real E = ai_real(1.0) / std::max(spotExponent, (ai_real)0.00001);
ai_real inner = std::acos(std::pow((ai_real)0.99, E)); ai_real inner = std::acos(std::pow((ai_real)0.99, E));
ai_real outer = std::acos(std::pow((ai_real)0.01, E)); ai_real outer = std::acos(std::pow((ai_real)0.01, E));
@ -739,20 +695,17 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
light->mAngleOuterCone = outer; light->mAngleOuterCone = outer;
} }
static void ReadLight(SIB* sib, StreamReaderLE* stream) static void ReadLight(SIB *sib, StreamReaderLE *stream) {
{ aiLight *light = new aiLight();
aiLight* light = new aiLight();
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
{
SIBChunk chunk = ReadChunk(stream); SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size); unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag) switch (chunk.Tag) {
{ case TAG('L', 'N', 'F', 'O'): ReadLightInfo(light, stream); break;
case TAG('L','N','F','O'): ReadLightInfo(light, stream); break; case TAG('S', 'N', 'A', 'M'): light->mName = ReadString(stream, chunk.Size / 2); break;
case TAG('S','N','A','M'): light->mName = ReadString(stream, chunk.Size/2); break; default: UnknownChunk(stream, chunk); break;
default: UnknownChunk(stream, chunk); break;
} }
stream->SetCurrentPos(stream->GetReadLimit()); stream->SetCurrentPos(stream->GetReadLimit());
@ -763,8 +716,7 @@ static void ReadLight(SIB* sib, StreamReaderLE* stream)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void ReadScale(aiMatrix4x4& axis, StreamReaderLE* stream) static void ReadScale(aiMatrix4x4 &axis, StreamReaderLE *stream) {
{
aiMatrix4x4 scale; aiMatrix4x4 scale;
scale.a1 = stream->GetF4(); scale.a1 = stream->GetF4();
scale.b1 = stream->GetF4(); scale.b1 = stream->GetF4();
@ -786,68 +738,61 @@ static void ReadScale(aiMatrix4x4& axis, StreamReaderLE* stream)
axis = axis * scale; axis = axis * scale;
} }
static void ReadInstance(SIB* sib, StreamReaderLE* stream) static void ReadInstance(SIB *sib, StreamReaderLE *stream) {
{
SIBObject inst; SIBObject inst;
uint32_t shapeIndex = 0; uint32_t shapeIndex = 0;
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
{
SIBChunk chunk = ReadChunk(stream); SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size); unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag) switch (chunk.Tag) {
{ case TAG('D', 'I', 'N', 'F'): break; // display info, not needed
case TAG('D','I','N','F'): break; // display info, not needed case TAG('P', 'I', 'N', 'F'): break; // ?
case TAG('P','I','N','F'): break; // ? case TAG('A', 'X', 'I', 'S'): ReadAxis(inst.axis, stream); break;
case TAG('A','X','I','S'): ReadAxis(inst.axis, stream); break; case TAG('I', 'N', 'S', 'I'): shapeIndex = stream->GetU4(); break;
case TAG('I','N','S','I'): shapeIndex = stream->GetU4(); break; case TAG('S', 'M', 'T', 'X'): ReadScale(inst.axis, stream); break;
case TAG('S','M','T','X'): ReadScale(inst.axis, stream); break; case TAG('S', 'N', 'A', 'M'): inst.name = ReadString(stream, chunk.Size / 2); break;
case TAG('S','N','A','M'): inst.name = ReadString(stream, chunk.Size/2); break; default: UnknownChunk(stream, chunk); break;
default: UnknownChunk(stream, chunk); break;
} }
stream->SetCurrentPos(stream->GetReadLimit()); stream->SetCurrentPos(stream->GetReadLimit());
stream->SetReadLimit(oldLimit); stream->SetReadLimit(oldLimit);
} }
if ( shapeIndex >= sib->objs.size() ) { if (shapeIndex >= sib->objs.size()) {
throw DeadlyImportError( "SIB: Invalid shape index." ); throw DeadlyImportError("SIB: Invalid shape index.");
} }
const SIBObject& src = sib->objs[shapeIndex]; const SIBObject &src = sib->objs[shapeIndex];
inst.meshIdx = src.meshIdx; inst.meshIdx = src.meshIdx;
inst.meshCount = src.meshCount; inst.meshCount = src.meshCount;
sib->insts.push_back(inst); sib->insts.push_back(inst);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
static void CheckVersion(StreamReaderLE* stream) static void CheckVersion(StreamReaderLE *stream) {
{
uint32_t version = stream->GetU4(); uint32_t version = stream->GetU4();
if ( version < 1 || version > 2 ) { if (version < 1 || version > 2) {
throw DeadlyImportError( "SIB: Unsupported file version." ); throw DeadlyImportError("SIB: Unsupported file version.");
} }
} }
static void ReadScene(SIB* sib, StreamReaderLE* stream) static void ReadScene(SIB *sib, StreamReaderLE *stream) {
{
// Parse each chunk in turn. // Parse each chunk in turn.
while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk)) {
{
SIBChunk chunk = ReadChunk(stream); SIBChunk chunk = ReadChunk(stream);
unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size); unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
switch (chunk.Tag) switch (chunk.Tag) {
{ case TAG('H', 'E', 'A', 'D'): CheckVersion(stream); break;
case TAG('H','E','A','D'): CheckVersion(stream); break; case TAG('S', 'H', 'A', 'P'): ReadShape(sib, stream); break;
case TAG('S','H','A','P'): ReadShape(sib, stream); break; case TAG('G', 'R', 'P', 'S'): break; // group assignment, we don't import this
case TAG('G','R','P','S'): break; // group assignment, we don't import this case TAG('T', 'E', 'X', 'P'): break; // ?
case TAG('T','E','X','P'): break; // ? case TAG('I', 'N', 'S', 'T'): ReadInstance(sib, stream); break;
case TAG('I','N','S','T'): ReadInstance(sib, stream); break; case TAG('M', 'A', 'T', 'R'): ReadMaterial(sib, stream); break;
case TAG('M','A','T','R'): ReadMaterial(sib, stream); break; case TAG('L', 'G', 'H', 'T'): ReadLight(sib, stream); break;
case TAG('L','G','H','T'): ReadLight(sib, stream); break; default: UnknownChunk(stream, chunk); break;
default: UnknownChunk(stream, chunk); break;
} }
stream->SetCurrentPos(stream->GetReadLimit()); stream->SetCurrentPos(stream->GetReadLimit());
@ -857,9 +802,8 @@ static void ReadScene(SIB* sib, StreamReaderLE* stream)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void SIBImporter::InternReadFile(const std::string& pFile, void SIBImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene *pScene, IOSystem *pIOHandler) {
{
StreamReaderLE stream(pIOHandler->Open(pFile, "rb")); StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
// We should have at least one chunk // We should have at least one chunk
@ -869,7 +813,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
SIB sib; SIB sib;
// Default material. // Default material.
aiMaterial* defmtl = new aiMaterial; aiMaterial *defmtl = new aiMaterial;
aiString defname = aiString(AI_DEFAULT_MATERIAL_NAME); aiString defname = aiString(AI_DEFAULT_MATERIAL_NAME);
defmtl->AddProperty(&defname, AI_MATKEY_NAME); defmtl->AddProperty(&defname, AI_MATKEY_NAME);
sib.mtls.push_back(defmtl); sib.mtls.push_back(defmtl);
@ -886,57 +830,54 @@ void SIBImporter::InternReadFile(const std::string& pFile,
pScene->mNumMaterials = static_cast<unsigned int>(sib.mtls.size()); pScene->mNumMaterials = static_cast<unsigned int>(sib.mtls.size());
pScene->mNumMeshes = static_cast<unsigned int>(sib.meshes.size()); pScene->mNumMeshes = static_cast<unsigned int>(sib.meshes.size());
pScene->mNumLights = static_cast<unsigned int>(sib.lights.size()); pScene->mNumLights = static_cast<unsigned int>(sib.lights.size());
pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial*[pScene->mNumMaterials] : NULL; pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial *[pScene->mNumMaterials] : nullptr;
pScene->mMeshes = pScene->mNumMeshes ? new aiMesh*[pScene->mNumMeshes] : NULL; pScene->mMeshes = pScene->mNumMeshes ? new aiMesh *[pScene->mNumMeshes] : nullptr;
pScene->mLights = pScene->mNumLights ? new aiLight*[pScene->mNumLights] : NULL; pScene->mLights = pScene->mNumLights ? new aiLight *[pScene->mNumLights] : nullptr;
if (pScene->mNumMaterials) if (pScene->mNumMaterials)
memcpy(pScene->mMaterials, &sib.mtls[0], sizeof(aiMaterial*) * pScene->mNumMaterials); memcpy(pScene->mMaterials, &sib.mtls[0], sizeof(aiMaterial *) * pScene->mNumMaterials);
if (pScene->mNumMeshes) if (pScene->mNumMeshes)
memcpy(pScene->mMeshes, &sib.meshes[0], sizeof(aiMesh*) * pScene->mNumMeshes); memcpy(pScene->mMeshes, &sib.meshes[0], sizeof(aiMesh *) * pScene->mNumMeshes);
if (pScene->mNumLights) if (pScene->mNumLights)
memcpy(pScene->mLights, &sib.lights[0], sizeof(aiLight*) * pScene->mNumLights); memcpy(pScene->mLights, &sib.lights[0], sizeof(aiLight *) * pScene->mNumLights);
// Construct the root node. // Construct the root node.
size_t childIdx = 0; size_t childIdx = 0;
aiNode *root = new aiNode(); aiNode *root = new aiNode();
root->mName.Set("<SIBRoot>"); root->mName.Set("<SIBRoot>");
root->mNumChildren = static_cast<unsigned int>(sib.objs.size() + sib.lights.size()); root->mNumChildren = static_cast<unsigned int>(sib.objs.size() + sib.lights.size());
root->mChildren = root->mNumChildren ? new aiNode*[root->mNumChildren] : NULL; root->mChildren = root->mNumChildren ? new aiNode *[root->mNumChildren] : nullptr;
pScene->mRootNode = root; pScene->mRootNode = root;
// Add nodes for each object. // Add nodes for each object.
for (size_t n=0;n<sib.objs.size();n++) for (size_t n = 0; n < sib.objs.size(); n++) {
{
ai_assert(root->mChildren); ai_assert(root->mChildren);
SIBObject& obj = sib.objs[n]; SIBObject &obj = sib.objs[n];
aiNode* node = new aiNode; aiNode *node = new aiNode;
root->mChildren[childIdx++] = node; root->mChildren[childIdx++] = node;
node->mName = obj.name; node->mName = obj.name;
node->mParent = root; node->mParent = root;
node->mTransformation = obj.axis; node->mTransformation = obj.axis;
node->mNumMeshes = static_cast<unsigned int>(obj.meshCount); node->mNumMeshes = static_cast<unsigned int>(obj.meshCount);
node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : NULL; node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : nullptr;
for (unsigned i=0;i<node->mNumMeshes;i++) for (unsigned i = 0; i < node->mNumMeshes; i++)
node->mMeshes[i] = static_cast<unsigned int>(obj.meshIdx + i); node->mMeshes[i] = static_cast<unsigned int>(obj.meshIdx + i);
// Mark instanced objects as being so. // Mark instanced objects as being so.
if (n >= firstInst) if (n >= firstInst) {
{ node->mMetaData = aiMetadata::Alloc(1);
node->mMetaData = aiMetadata::Alloc( 1 ); node->mMetaData->Set(0, "IsInstance", true);
node->mMetaData->Set( 0, "IsInstance", true );
} }
} }
// Add nodes for each light. // Add nodes for each light.
// (no transformation as the light is already in world space) // (no transformation as the light is already in world space)
for (size_t n=0;n<sib.lights.size();n++) for (size_t n = 0; n < sib.lights.size(); n++) {
{
ai_assert(root->mChildren); ai_assert(root->mChildren);
aiLight* light = sib.lights[n]; aiLight *light = sib.lights[n];
if ( nullptr != light ) { if (nullptr != light) {
aiNode* node = new aiNode; aiNode *node = new aiNode;
root->mChildren[ childIdx++ ] = node; root->mChildren[childIdx++] = node;
node->mName = light->mName; node->mName = light->mName;
node->mParent = root; node->mParent = root;
} }

View File

@ -577,7 +577,7 @@ void SMDImporter::GetAnimationFileList(const std::string &pFile, IOSystem* pIOHa
char *context1, *context2; char *context1, *context2;
tok1 = strtok_s(&buf[0], "\r\n", &context1); tok1 = strtok_s(&buf[0], "\r\n", &context1);
while (tok1 != NULL) { while (tok1 != nullptr) {
tok2 = strtok_s(tok1, " \t", &context2); tok2 = strtok_s(tok1, " \t", &context2);
if (tok2) { if (tok2) {
char *p = tok2; char *p = tok2;

View File

@ -299,7 +299,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= NULL*/) std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/)
{ {
const char* cur = inout; const char* cur = inout;
SkipSpaces(&cur); SkipSpaces(&cur);
@ -422,7 +422,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= NULL*/) { std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= nullptr*/) {
const std::shared_ptr<EXPRESS::LIST> list = std::make_shared<EXPRESS::LIST>(); const std::shared_ptr<EXPRESS::LIST> list = std::make_shared<EXPRESS::LIST>();
EXPRESS::LIST::MemberList& members = list->members; EXPRESS::LIST::MemberList& members = list->members;
@ -540,9 +540,9 @@ void STEP::LazyObject::LazyInit() const {
const char* acopy = args; const char* acopy = args;
std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema()); std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,(uint64_t)STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
delete[] args; delete[] args;
args = NULL; args = nullptr;
// if the converter fails, it should throw an exception, but it should never return NULL // if the converter fails, it should throw an exception, but it should never return nullptr
try { try {
obj = proc(db,*conv_args); obj = proc(db,*conv_args);
} }

View File

@ -72,7 +72,7 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
// we're still here - export successfully completed. Write the file. // we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile)); throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
} }
@ -91,7 +91,7 @@ void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene*
// we're still here - export successfully completed. Write the file. // we're still here - export successfully completed. Write the file.
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .stl file: " + std::string(pFile)); throw DeadlyExportError("could not open output .stl file: " + std::string(pFile));
} }

View File

@ -54,7 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#ifdef _WIN32 #if _MSC_VER > 1920
# pragma warning(push) # pragma warning(push)
# pragma warning(disable : 4127 4456 4245 4512 ) # pragma warning(disable : 4127 4456 4245 4512 )
#endif // _WIN32 #endif // _WIN32
@ -727,7 +727,7 @@ struct InternGenericConvert<Maybe<T>> {
} }
}; };
#ifdef _WIN32 #if _MSC_VER > 1920
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4127) #pragma warning(disable : 4127)
#endif // _WIN32 #endif // _WIN32
@ -960,7 +960,7 @@ private:
const EXPRESS::ConversionSchema *schema; const EXPRESS::ConversionSchema *schema;
}; };
#ifdef _WIN32 #if _MSC_VER > 1920
#pragma warning(pop) #pragma warning(pop)
#endif // _WIN32 #endif // _WIN32

View File

@ -108,7 +108,7 @@ void ExportSceneStep(const char* pFile,IOSystem* pIOSystem, const aiScene* pScen
// we're still here - export successfully completed. Write result to the given IOSYstem // we're still here - export successfully completed. Write result to the given IOSYstem
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .stp file: " + std::string(pFile)); throw DeadlyExportError("could not open output .stp file: " + std::string(pFile));
} }
@ -204,7 +204,7 @@ void StepExporter::WriteFile()
static const unsigned int date_nb_chars = 20; static const unsigned int date_nb_chars = 20;
char date_str[date_nb_chars]; char date_str[date_nb_chars];
std::time_t date = std::time(NULL); std::time_t date = std::time(nullptr);
std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date)); std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date));
// write the header // write the header

View File

@ -87,12 +87,16 @@ bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, b
if (!extension.length() || checkSig) { if (!extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we /* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler * support a specific file extension in general pIOHandler
* might be NULL and it's our duty to return true here. * might be nullptr and it's our duty to return true here.
*/ */
if (!pIOHandler) return true; if (!pIOHandler) {
return true;
}
const char *tokens[] = { "terragen" }; const char *tokens[] = { "terragen" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
} }
return false; return false;
} }
@ -116,7 +120,7 @@ void TerragenImporter::InternReadFile(const std::string &pFile,
IOStream *file = pIOHandler->Open(pFile, "rb"); IOStream *file = pIOHandler->Open(pFile, "rb");
// Check whether we can read from the file // Check whether we can read from the file
if (file == NULL) if (file == nullptr)
throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file " + pFile + "."); throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file " + pFile + ".");
// Construct a stream reader to read all data in the correct endianness // Construct a stream reader to read all data in the correct endianness
@ -199,7 +203,7 @@ void TerragenImporter::InternReadFile(const std::string &pFile,
aiFace *f = m->mFaces = new aiFace[m->mNumFaces = (x - 1) * (y - 1)]; aiFace *f = m->mFaces = new aiFace[m->mNumFaces = (x - 1) * (y - 1)];
aiVector3D *pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces * 4]; aiVector3D *pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces * 4];
aiVector3D *uv(NULL); aiVector3D *uv(nullptr);
float step_y(0.0f), step_x(0.0f); float step_y(0.0f), step_x(0.0f);
if (configComputeUVs) { if (configComputeUVs) {
uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices]; uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];

View File

@ -89,7 +89,7 @@ void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pSce
// we're still here - export successfully completed. Write result to the given IOSYstem // we're still here - export successfully completed. Write result to the given IOSYstem
std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt")); std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
if(outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output .x file: " + std::string(pFile)); throw DeadlyExportError("could not open output .x file: " + std::string(pFile));
} }

View File

@ -113,7 +113,7 @@ const aiImporterDesc* XFileImporter::GetInfo () const {
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.get() == NULL ) { if ( file.get() == nullptr ) {
throw DeadlyImportError( "Failed to open file " + pFile + "." ); throw DeadlyImportError( "Failed to open file " + pFile + "." );
} }

File diff suppressed because it is too large Load Diff

View File

@ -104,7 +104,7 @@ protected:
//! reads header of data object including the opening brace. //! reads header of data object including the opening brace.
//! returns false if error happened, and writes name of object //! returns false if error happened, and writes name of object
//! if there is one //! if there is one
void readHeadOfDataObject( std::string* poName = NULL); void readHeadOfDataObject(std::string *poName = nullptr);
//! checks for closing curly brace, throws exception if not there //! checks for closing curly brace, throws exception if not there
void CheckForClosingBrace(); void CheckForClosingBrace();

View File

@ -64,8 +64,8 @@ namespace Assimp
// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model." // A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
// </Shape> // </Shape>
// A Shape node is unlit if either of the following is true: // A Shape node is unlit if either of the following is true:
// The shape's appearance field is NULL (default). // The shape's appearance field is nullptr (default).
// The material field in the Appearance node is NULL (default). // The material field in the Appearance node is nullptr (default).
// NOTE Geometry nodes that represent lines or points do not support lighting. // NOTE Geometry nodes that represent lines or points do not support lighting.
void X3DImporter::ParseNode_Shape_Shape() void X3DImporter::ParseNode_Shape_Shape()
{ {

View File

@ -43,18 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the XGL/ZGL importer class */ /** @file Implementation of the XGL/ZGL importer class */
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER #ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
#include "XGLLoader.h" #include "XGLLoader.h"
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/StreamReader.h>
#include <assimp/MemoryIOWrapper.h> #include <assimp/MemoryIOWrapper.h>
#include <assimp/StreamReader.h>
#include <assimp/importerdesc.h>
#include <assimp/mesh.h> #include <assimp/mesh.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <cctype> #include <cctype>
#include <memory> #include <memory>
@ -64,21 +63,20 @@ using namespace irr::io;
// zlib is needed for compressed XGL files // zlib is needed for compressed XGL files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL #ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h> #include <zlib.h>
# else #else
# include <contrib/zlib/zlib.h> #include <contrib/zlib/zlib.h>
# endif #endif
#endif #endif
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
template<> const char* LogFunctions<XGLImporter>::Prefix() template <>
{ const char *LogFunctions<XGLImporter>::Prefix() {
static auto prefix = "XGL: "; static auto prefix = "XGL: ";
return prefix; return prefix;
}
} }
} // namespace Assimp
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"XGL Importer", "XGL Importer",
@ -93,12 +91,10 @@ static const aiImporterDesc desc = {
"xgl zgl" "xgl zgl"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
XGLImporter::XGLImporter() XGLImporter::XGLImporter() :
: m_reader( nullptr ) m_reader(nullptr), m_scene(nullptr) {
, m_scene( nullptr ) {
// empty // empty
} }
@ -110,8 +106,7 @@ XGLImporter::~XGLImporter() {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// 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 XGLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool XGLImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
{
/* NOTE: A simple check for the file extension is not enough /* NOTE: A simple check for the file extension is not enough
* here. XGL and ZGL are ok, but xml is too generic * here. XGL and ZGL are ok, but xml is too generic
* and might be collada as well. So open the file and * and might be collada as well. So open the file and
@ -121,38 +116,35 @@ bool XGLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
if (extension == "xgl" || extension == "zgl") { if (extension == "xgl" || extension == "zgl") {
return true; return true;
} } else if (extension == "xml" || checkSig) {
else if (extension == "xml" || checkSig) { ai_assert(pIOHandler != nullptr);
ai_assert(pIOHandler != NULL);
const char* tokens[] = {"<world>","<World>","<WORLD>"}; const char *tokens[] = { "<world>", "<World>", "<WORLD>" };
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,3); return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 3);
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get a list of all file extensions which are handled by this class // 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. // Imports the given file into the given scene structure.
void XGLImporter::InternReadFile( const std::string& pFile, void XGLImporter::InternReadFile(const std::string &pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene *pScene, IOSystem *pIOHandler) {
{
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL #ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
std::vector<Bytef> uncompressed; std::vector<Bytef> uncompressed;
#endif #endif
m_scene = pScene; m_scene = pScene;
std::shared_ptr<IOStream> stream( pIOHandler->Open( pFile, "rb")); std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
// check whether we can read from the file // check whether we can read from the file
if( stream.get() == NULL) { if (stream.get() == nullptr) {
throw DeadlyImportError( "Failed to open XGL/ZGL file " + pFile + ""); throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile + "");
} }
// see if its compressed, if so uncompress it // see if its compressed, if so uncompress it
@ -166,7 +158,7 @@ void XGLImporter::InternReadFile( const std::string& pFile,
z_stream zstream; z_stream zstream;
zstream.opaque = Z_NULL; zstream.opaque = Z_NULL;
zstream.zalloc = Z_NULL; zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL; zstream.zfree = Z_NULL;
zstream.data_type = Z_BINARY; zstream.data_type = Z_BINARY;
// raw decompression without a zlib or gzip header // raw decompression without a zlib or gzip header
@ -175,14 +167,14 @@ void XGLImporter::InternReadFile( const std::string& pFile,
// skip two extra bytes, zgl files do carry a crc16 upfront (I think) // skip two extra bytes, zgl files do carry a crc16 upfront (I think)
raw_reader->IncPtr(2); raw_reader->IncPtr(2);
zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() ); zstream.next_in = reinterpret_cast<Bytef *>(raw_reader->GetPtr());
zstream.avail_in = (uInt) raw_reader->GetRemainingSize(); zstream.avail_in = (uInt)raw_reader->GetRemainingSize();
size_t total = 0l; size_t total = 0l;
// TODO: be smarter about this, decompress directly into heap buffer // TODO: be smarter about this, decompress directly into heap buffer
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
#define MYBLOCK 1024 #define MYBLOCK 1024
Bytef block[MYBLOCK]; Bytef block[MYBLOCK];
int ret; int ret;
do { do {
@ -196,51 +188,49 @@ void XGLImporter::InternReadFile( const std::string& pFile,
const size_t have = MYBLOCK - zstream.avail_out; const size_t have = MYBLOCK - zstream.avail_out;
total += have; total += have;
uncompressed.resize(total); uncompressed.resize(total);
memcpy(uncompressed.data() + total - have,block,have); memcpy(uncompressed.data() + total - have, block, have);
} } while (ret != Z_STREAM_END);
while (ret != Z_STREAM_END);
// terminate zlib // terminate zlib
inflateEnd(&zstream); inflateEnd(&zstream);
// replace the input stream with a memory stream // replace the input stream with a memory stream
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(uncompressed.data()),total)); stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
#endif #endif
} }
// construct the irrXML parser // construct the irrXML parser
CIrrXML_IOStreamReader st(stream.get()); CIrrXML_IOStreamReader st(stream.get());
m_reader.reset( createIrrXMLReader( ( IFileReadCallBack* ) &st ) ); m_reader.reset(createIrrXMLReader((IFileReadCallBack *)&st));
// parse the XML file // parse the XML file
TempScope scope; TempScope scope;
while (ReadElement()) { while (ReadElement()) {
if (!ASSIMP_stricmp(m_reader->getNodeName(),"world")) { if (!ASSIMP_stricmp(m_reader->getNodeName(), "world")) {
ReadWorld(scope); ReadWorld(scope);
} }
} }
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.size() || !materials.size()) {
ThrowException("failed to extract data from XGL file, no meshes loaded"); ThrowException("failed to extract data from XGL file, no meshes loaded");
} }
// copy meshes // copy meshes
m_scene->mNumMeshes = static_cast<unsigned int>(meshes.size()); m_scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
m_scene->mMeshes = new aiMesh*[m_scene->mNumMeshes](); m_scene->mMeshes = new aiMesh *[m_scene->mNumMeshes]();
std::copy(meshes.begin(),meshes.end(),m_scene->mMeshes); std::copy(meshes.begin(), meshes.end(), m_scene->mMeshes);
// copy materials // copy materials
m_scene->mNumMaterials = static_cast<unsigned int>(materials.size()); m_scene->mNumMaterials = static_cast<unsigned int>(materials.size());
m_scene->mMaterials = new aiMaterial*[m_scene->mNumMaterials](); m_scene->mMaterials = new aiMaterial *[m_scene->mNumMaterials]();
std::copy(materials.begin(),materials.end(),m_scene->mMaterials); std::copy(materials.begin(), materials.end(), m_scene->mMaterials);
if (scope.light) { if (scope.light) {
m_scene->mNumLights = 1; m_scene->mNumLights = 1;
m_scene->mLights = new aiLight*[1]; m_scene->mLights = new aiLight *[1];
m_scene->mLights[0] = scope.light; m_scene->mLights[0] = scope.light;
scope.light->mName = m_scene->mRootNode->mName; scope.light->mName = m_scene->mRootNode->mName;
@ -250,9 +240,8 @@ void XGLImporter::InternReadFile( const std::string& pFile,
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadElement() bool XGLImporter::ReadElement() {
{ while (m_reader->read()) {
while(m_reader->read()) {
if (m_reader->getNodeType() == EXN_ELEMENT) { if (m_reader->getNodeType() == EXN_ELEMENT) {
return true; return true;
} }
@ -261,13 +250,11 @@ bool XGLImporter::ReadElement()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadElementUpToClosing(const char* closetag) bool XGLImporter::ReadElementUpToClosing(const char *closetag) {
{ while (m_reader->read()) {
while(m_reader->read()) {
if (m_reader->getNodeType() == EXN_ELEMENT) { if (m_reader->getNodeType() == EXN_ELEMENT) {
return true; return true;
} } else if (m_reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(m_reader->getNodeName(), closetag)) {
else if (m_reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(m_reader->getNodeName(),closetag)) {
return false; return false;
} }
} }
@ -276,13 +263,11 @@ bool XGLImporter::ReadElementUpToClosing(const char* closetag)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool XGLImporter::SkipToText() bool XGLImporter::SkipToText() {
{ while (m_reader->read()) {
while(m_reader->read()) {
if (m_reader->getNodeType() == EXN_TEXT) { if (m_reader->getNodeType() == EXN_TEXT) {
return true; return true;
} } else if (m_reader->getNodeType() == EXN_ELEMENT || m_reader->getNodeType() == EXN_ELEMENT_END) {
else if (m_reader->getNodeType() == EXN_ELEMENT || m_reader->getNodeType() == EXN_ELEMENT_END) {
ThrowException("expected text contents but found another element (or element end)"); ThrowException("expected text contents but found another element (or element end)");
} }
} }
@ -290,9 +275,8 @@ bool XGLImporter::SkipToText()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
std::string XGLImporter::GetElementName() std::string XGLImporter::GetElementName() {
{ const char *s = m_reader->getNodeName();
const char* s = m_reader->getNodeName();
size_t len = strlen(s); size_t len = strlen(s);
std::string ret; std::string ret;
@ -302,26 +286,23 @@ std::string XGLImporter::GetElementName()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XGLImporter::ReadWorld(TempScope& scope) void XGLImporter::ReadWorld(TempScope &scope) {
{
while (ReadElementUpToClosing("world")) { while (ReadElementUpToClosing("world")) {
const std::string& s = GetElementName(); const std::string &s = GetElementName();
// XXX right now we'd skip <lighting> if it comes after // XXX right now we'd skip <lighting> if it comes after
// <object> or <mesh> // <object> or <mesh>
if (s == "lighting") { if (s == "lighting") {
ReadLighting(scope); ReadLighting(scope);
} } else if (s == "object" || s == "mesh" || s == "mat") {
else if (s == "object" || s == "mesh" || s == "mat") {
break; break;
} }
} }
aiNode *const nd = ReadObject(scope, true, "world");
aiNode* const nd = ReadObject(scope,true,"world"); if (!nd) {
if(!nd) {
ThrowException("failure reading <world>"); ThrowException("failure reading <world>");
} }
if(!nd->mName.length) { if (!nd->mName.length) {
nd->mName.Set("WORLD"); nd->mName.Set("WORLD");
} }
@ -329,37 +310,31 @@ void XGLImporter::ReadWorld(TempScope& scope)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XGLImporter::ReadLighting(TempScope& scope) void XGLImporter::ReadLighting(TempScope &scope) {
{ while (ReadElementUpToClosing("lighting")) {
while (ReadElementUpToClosing("lighting")) { const std::string &s = GetElementName();
const std::string& s = GetElementName();
if (s == "directionallight") { if (s == "directionallight") {
scope.light = ReadDirectionalLight(); scope.light = ReadDirectionalLight();
} } else if (s == "ambient") {
else if (s == "ambient") {
LogWarn("ignoring <ambient> tag"); LogWarn("ignoring <ambient> tag");
} } else if (s == "spheremap") {
else if (s == "spheremap") {
LogWarn("ignoring <spheremap> tag"); LogWarn("ignoring <spheremap> tag");
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiLight* XGLImporter::ReadDirectionalLight() aiLight *XGLImporter::ReadDirectionalLight() {
{
std::unique_ptr<aiLight> l(new aiLight()); std::unique_ptr<aiLight> l(new aiLight());
l->mType = aiLightSource_DIRECTIONAL; l->mType = aiLightSource_DIRECTIONAL;
while (ReadElementUpToClosing("directionallight")) { while (ReadElementUpToClosing("directionallight")) {
const std::string& s = GetElementName(); const std::string &s = GetElementName();
if (s == "direction") { if (s == "direction") {
l->mDirection = ReadVec3(); l->mDirection = ReadVec3();
} } else if (s == "diffuse") {
else if (s == "diffuse") {
l->mColorDiffuse = ReadCol3(); l->mColorDiffuse = ReadCol3();
} } else if (s == "specular") {
else if (s == "specular") {
l->mColorSpecular = ReadCol3(); l->mColorSpecular = ReadCol3();
} }
} }
@ -367,49 +342,44 @@ aiLight* XGLImporter::ReadDirectionalLight()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* closetag) aiNode *XGLImporter::ReadObject(TempScope &scope, bool skipFirst, const char *closetag) {
{
aiNode *nd = new aiNode; aiNode *nd = new aiNode;
std::vector<aiNode*> children; std::vector<aiNode *> children;
std::vector<unsigned int> meshes; std::vector<unsigned int> meshes;
try { try {
while (skipFirst || ReadElementUpToClosing(closetag)) { while (skipFirst || ReadElementUpToClosing(closetag)) {
skipFirst = false; skipFirst = false;
const std::string& s = GetElementName(); const std::string &s = GetElementName();
if (s == "mesh") { if (s == "mesh") {
const size_t prev = scope.meshes_linear.size(); const size_t prev = scope.meshes_linear.size();
if(ReadMesh(scope)) { if (ReadMesh(scope)) {
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(scope); ReadMaterial(scope);
} } else if (s == "object") {
else if (s == "object") {
children.push_back(ReadObject(scope)); children.push_back(ReadObject(scope));
} } else if (s == "objectref") {
else if (s == "objectref") {
// XXX // XXX
} } else if (s == "meshref") {
else if (s == "meshref") { const unsigned int id = static_cast<unsigned int>(ReadIndexFromText());
const unsigned int id = static_cast<unsigned int>( ReadIndexFromText() );
std::multimap<unsigned int, aiMesh*>::iterator it = scope.meshes.find(id), end = scope.meshes.end(); std::multimap<unsigned int, aiMesh *>::iterator it = scope.meshes.find(id), end = scope.meshes.end();
if (it == end) { if (it == end) {
ThrowException("<meshref> index out of range"); ThrowException("<meshref> index out of range");
} }
for(; it != end && (*it).first == id; ++it) { for (; it != end && (*it).first == id; ++it) {
// ok, this is n^2 and should get optimized one day // ok, this is n^2 and should get optimized one day
aiMesh* const m = (*it).second; aiMesh *const m = (*it).second;
unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size()); unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size());
for(; i < mcount; ++i) { for (; i < mcount; ++i) {
if (scope.meshes_linear[i] == m) { if (scope.meshes_linear[i] == m) {
meshes.push_back(i); meshes.push_back(i);
break; break;
@ -418,14 +388,13 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl
ai_assert(i < mcount); ai_assert(i < mcount);
} }
} } else if (s == "transform") {
else if (s == "transform") {
nd->mTransformation = ReadTrafo(); nd->mTransformation = ReadTrafo();
} }
} }
} catch(...) { } catch (...) {
for(aiNode* ch : children) { for (aiNode *ch : children) {
delete ch; delete ch;
} }
throw; throw;
@ -441,7 +410,7 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl
nd->mNumMeshes = static_cast<unsigned int>(meshes.size()); nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
if (nd->mNumMeshes) { if (nd->mNumMeshes) {
nd->mMeshes = new unsigned int[nd->mNumMeshes](); nd->mMeshes = new unsigned int[nd->mNumMeshes]();
for(unsigned int i = 0; i < nd->mNumMeshes; ++i) { for (unsigned int i = 0; i < nd->mNumMeshes; ++i) {
nd->mMeshes[i] = meshes[i]; nd->mMeshes[i] = meshes[i];
} }
} }
@ -449,8 +418,8 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl
// link children to parent // link children to parent
nd->mNumChildren = static_cast<unsigned int>(children.size()); nd->mNumChildren = static_cast<unsigned int>(children.size());
if (nd->mNumChildren) { if (nd->mNumChildren) {
nd->mChildren = new aiNode*[nd->mNumChildren](); nd->mChildren = new aiNode *[nd->mNumChildren]();
for(unsigned int i = 0; i < nd->mNumChildren; ++i) { for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
nd->mChildren[i] = children[i]; nd->mChildren[i] = children[i];
children[i]->mParent = nd; children[i]->mParent = nd;
} }
@ -460,25 +429,22 @@ aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* cl
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMatrix4x4 XGLImporter::ReadTrafo() aiMatrix4x4 XGLImporter::ReadTrafo() {
{
aiVector3D forward, up, right, position; aiVector3D forward, up, right, position;
float scale = 1.0f; float scale = 1.0f;
while (ReadElementUpToClosing("transform")) { while (ReadElementUpToClosing("transform")) {
const std::string& s = GetElementName(); const std::string &s = GetElementName();
if (s == "forward") { if (s == "forward") {
forward = ReadVec3(); forward = ReadVec3();
} } else if (s == "up") {
else if (s == "up") {
up = ReadVec3(); up = ReadVec3();
} } else if (s == "position") {
else if (s == "position") {
position = ReadVec3(); position = ReadVec3();
} }
if (s == "scale") { if (s == "scale") {
scale = ReadFloat(); scale = ReadFloat();
if(scale < 0.f) { if (scale < 0.f) {
// this is wrong, but we can leave the value and pass it to the caller // this is wrong, but we can leave the value and pass it to the caller
LogError("found negative scaling in <transform>, ignoring"); LogError("found negative scaling in <transform>, ignoring");
} }
@ -486,7 +452,7 @@ aiMatrix4x4 XGLImporter::ReadTrafo()
} }
aiMatrix4x4 m; aiMatrix4x4 m;
if(forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) { if (forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
LogError("A direction vector in <transform> is zero, ignoring trafo"); LogError("A direction vector in <transform> is zero, ignoring trafo");
return m; return m;
} }
@ -526,37 +492,36 @@ aiMatrix4x4 XGLImporter::ReadTrafo()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* XGLImporter::ToOutputMesh(const TempMaterialMesh& m) aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
{
std::unique_ptr<aiMesh> mesh(new aiMesh()); std::unique_ptr<aiMesh> mesh(new aiMesh());
mesh->mNumVertices = static_cast<unsigned int>(m.positions.size()); mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
mesh->mVertices = new aiVector3D[mesh->mNumVertices]; mesh->mVertices = new aiVector3D[mesh->mNumVertices];
std::copy(m.positions.begin(),m.positions.end(),mesh->mVertices); std::copy(m.positions.begin(), m.positions.end(), mesh->mVertices);
if(m.normals.size()) { if (m.normals.size()) {
mesh->mNormals = new aiVector3D[mesh->mNumVertices]; mesh->mNormals = new aiVector3D[mesh->mNumVertices];
std::copy(m.normals.begin(),m.normals.end(),mesh->mNormals); std::copy(m.normals.begin(), m.normals.end(), mesh->mNormals);
} }
if(m.uvs.size()) { if (m.uvs.size()) {
mesh->mNumUVComponents[0] = 2; mesh->mNumUVComponents[0] = 2;
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
for(unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x,m.uvs[i].y,0.f); mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x, m.uvs[i].y, 0.f);
} }
} }
mesh->mNumFaces = static_cast<unsigned int>(m.vcounts.size()); mesh->mNumFaces = static_cast<unsigned int>(m.vcounts.size());
mesh->mFaces = new aiFace[m.vcounts.size()]; mesh->mFaces = new aiFace[m.vcounts.size()];
unsigned int idx = 0; unsigned int idx = 0;
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) { for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
aiFace& f = mesh->mFaces[i]; aiFace &f = mesh->mFaces[i];
f.mNumIndices = m.vcounts[i]; f.mNumIndices = m.vcounts[i];
f.mIndices = new unsigned int[f.mNumIndices]; f.mIndices = new unsigned int[f.mNumIndices];
for(unsigned int c = 0; c < f.mNumIndices; ++c) { for (unsigned int c = 0; c < f.mNumIndices; ++c) {
f.mIndices[c] = idx++; f.mIndices[c] = idx++;
} }
} }
@ -569,57 +534,49 @@ aiMesh* XGLImporter::ToOutputMesh(const TempMaterialMesh& m)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadMesh(TempScope& scope) bool XGLImporter::ReadMesh(TempScope &scope) {
{
TempMesh t; TempMesh t;
std::map<unsigned int, TempMaterialMesh> bymat; std::map<unsigned int, TempMaterialMesh> bymat;
const unsigned int mesh_id = ReadIDAttr(); const unsigned int mesh_id = ReadIDAttr();
while (ReadElementUpToClosing("mesh")) { while (ReadElementUpToClosing("mesh")) {
const std::string& s = GetElementName(); const std::string &s = GetElementName();
if (s == "mat") { if (s == "mat") {
ReadMaterial(scope); ReadMaterial(scope);
} } else if (s == "p") {
else if (s == "p") {
if (!m_reader->getAttributeValue("ID")) { if (!m_reader->getAttributeValue("ID")) {
LogWarn("no ID attribute on <p>, ignoring"); LogWarn("no ID attribute on <p>, ignoring");
} } else {
else {
int id = m_reader->getAttributeValueAsInt("ID"); int id = m_reader->getAttributeValueAsInt("ID");
t.points[id] = ReadVec3(); t.points[id] = ReadVec3();
} }
} } else if (s == "n") {
else if (s == "n") {
if (!m_reader->getAttributeValue("ID")) { if (!m_reader->getAttributeValue("ID")) {
LogWarn("no ID attribute on <n>, ignoring"); LogWarn("no ID attribute on <n>, ignoring");
} } else {
else {
int id = m_reader->getAttributeValueAsInt("ID"); int id = m_reader->getAttributeValueAsInt("ID");
t.normals[id] = ReadVec3(); t.normals[id] = ReadVec3();
} }
} } else if (s == "tc") {
else if (s == "tc") {
if (!m_reader->getAttributeValue("ID")) { if (!m_reader->getAttributeValue("ID")) {
LogWarn("no ID attribute on <tc>, ignoring"); LogWarn("no ID attribute on <tc>, ignoring");
} } else {
else {
int id = m_reader->getAttributeValueAsInt("ID"); int id = m_reader->getAttributeValueAsInt("ID");
t.uvs[id] = ReadVec2(); t.uvs[id] = ReadVec2();
} }
} } 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 mid = ~0u;
TempFace tf[3]; TempFace tf[3];
bool has[3] = {0}; bool has[3] = { 0 };
while (ReadElementUpToClosing(s.c_str())) { while (ReadElementUpToClosing(s.c_str())) {
const std::string& elemName = GetElementName(); const std::string &elemName = GetElementName();
if (elemName == "fv1" || elemName == "lv1" || elemName == "pv1") { if (elemName == "fv1" || elemName == "lv1" || elemName == "pv1") {
ReadFaceVertex(t,tf[0]); ReadFaceVertex(t, tf[0]);
has[0] = true; has[0] = true;
} else if (elemName == "fv2" || elemName == "lv2") { } else if (elemName == "fv2" || elemName == "lv2") {
ReadFaceVertex(t, tf[1]); ReadFaceVertex(t, tf[1]);
@ -646,7 +603,7 @@ bool XGLImporter::ReadMesh(TempScope& scope)
bool nor = false; bool nor = false;
bool 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");
} }
@ -655,24 +612,24 @@ bool XGLImporter::ReadMesh(TempScope& scope)
uv = uv || tf[i].has_uv; uv = uv || tf[i].has_uv;
} }
if (mid >= (1<<30)) { if (mid >= (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); unsigned int meshId = mid | ((nor ? 1 : 0) << 31) | ((uv ? 1 : 0) << 30);
TempMaterialMesh& mesh = bymat[meshId]; TempMaterialMesh &mesh = bymat[meshId];
mesh.matid = mid; mesh.matid = mid;
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(tf[i].pos);
if(nor) { if (nor) {
mesh.normals.push_back(tf[i].normal); mesh.normals.push_back(tf[i].normal);
} }
if(uv) { if (uv) {
mesh.uvs.push_back(tf[i].uv); mesh.uvs.push_back(tf[i].uv);
} }
mesh.pflags |= 1 << (vcount-1); mesh.pflags |= 1 << (vcount - 1);
} }
mesh.vcounts.push_back(vcount); mesh.vcounts.push_back(vcount);
@ -681,13 +638,13 @@ bool XGLImporter::ReadMesh(TempScope& scope)
// finally extract output meshes and add them to the scope // finally extract output meshes and add them to the scope
typedef std::pair<const unsigned int, TempMaterialMesh> pairt; typedef std::pair<const unsigned int, TempMaterialMesh> pairt;
for(const pairt& p : bymat) { for (const pairt &p : bymat) {
aiMesh* const m = ToOutputMesh(p.second); aiMesh *const m = ToOutputMesh(p.second);
scope.meshes_linear.push_back(m); scope.meshes_linear.push_back(m);
// if this is a definition, keep it on the stack // if this is a definition, keep it on the stack
if(mesh_id != ~0u) { if (mesh_id != ~0u) {
scope.meshes.insert(std::pair<unsigned int, aiMesh*>(mesh_id,m)); scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
} }
} }
@ -696,26 +653,25 @@ bool XGLImporter::ReadMesh(TempScope& scope)
} }
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
unsigned int XGLImporter::ResolveMaterialRef(TempScope& scope) unsigned int XGLImporter::ResolveMaterialRef(TempScope &scope) {
{ const std::string &s = GetElementName();
const std::string& s = GetElementName();
if (s == "mat") { if (s == "mat") {
ReadMaterial(scope); ReadMaterial(scope);
return static_cast<unsigned int>(scope.materials_linear.size()-1); return static_cast<unsigned int>(scope.materials_linear.size() - 1);
} }
const int id = ReadIndexFromText(); const int id = ReadIndexFromText();
std::map<unsigned int, aiMaterial*>::iterator it = scope.materials.find(id), end = scope.materials.end(); std::map<unsigned int, aiMaterial *>::iterator it = scope.materials.find(id), end = scope.materials.end();
if (it == end) { if (it == end) {
ThrowException("<matref> index out of range"); ThrowException("<matref> index out of range");
} }
// ok, this is n^2 and should get optimized one day // ok, this is n^2 and should get optimized one day
aiMaterial* const m = (*it).second; aiMaterial *const m = (*it).second;
unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size()); unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size());
for(; i < mcount; ++i) { for (; i < mcount; ++i) {
if (scope.materials_linear[i] == m) { if (scope.materials_linear[i] == m) {
return i; return i;
} }
@ -726,35 +682,30 @@ unsigned int XGLImporter::ResolveMaterialRef(TempScope& scope)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void XGLImporter::ReadMaterial(TempScope& scope) { void XGLImporter::ReadMaterial(TempScope &scope) {
const unsigned int mat_id = ReadIDAttr(); const unsigned int mat_id = ReadIDAttr();
aiMaterial *mat(new aiMaterial ); aiMaterial *mat(new aiMaterial);
while (ReadElementUpToClosing("mat")) { while (ReadElementUpToClosing("mat")) {
const std::string& s = GetElementName(); const std::string &s = GetElementName();
if (s == "amb") { if (s == "amb") {
const aiColor3D c = ReadCol3(); const aiColor3D c = ReadCol3();
mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT); mat->AddProperty(&c, 1, AI_MATKEY_COLOR_AMBIENT);
} } else if (s == "diff") {
else if (s == "diff") {
const aiColor3D c = ReadCol3(); const aiColor3D c = ReadCol3();
mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE); mat->AddProperty(&c, 1, AI_MATKEY_COLOR_DIFFUSE);
} } else if (s == "spec") {
else if (s == "spec") {
const aiColor3D c = ReadCol3(); const aiColor3D c = ReadCol3();
mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR); mat->AddProperty(&c, 1, AI_MATKEY_COLOR_SPECULAR);
} } else if (s == "emiss") {
else if (s == "emiss") {
const aiColor3D c = ReadCol3(); const aiColor3D c = ReadCol3();
mat->AddProperty(&c,1,AI_MATKEY_COLOR_EMISSIVE); mat->AddProperty(&c, 1, AI_MATKEY_COLOR_EMISSIVE);
} } else if (s == "alpha") {
else if (s == "alpha") {
const float f = ReadFloat(); const float f = ReadFloat();
mat->AddProperty(&f,1,AI_MATKEY_OPACITY); mat->AddProperty(&f, 1, AI_MATKEY_OPACITY);
} } else if (s == "shine") {
else if (s == "shine") {
const float f = ReadFloat(); const float f = ReadFloat();
mat->AddProperty(&f,1,AI_MATKEY_SHININESS); mat->AddProperty(&f, 1, AI_MATKEY_SHININESS);
} }
} }
@ -763,13 +714,12 @@ void XGLImporter::ReadMaterial(TempScope& scope) {
} }
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out) void XGLImporter::ReadFaceVertex(const TempMesh &t, TempFace &out) {
{ const std::string &end = GetElementName();
const std::string& end = GetElementName();
bool havep = false; bool havep = false;
while (ReadElementUpToClosing(end.c_str())) { while (ReadElementUpToClosing(end.c_str())) {
const std::string& s = GetElementName(); const std::string &s = GetElementName();
if (s == "pref") { if (s == "pref") {
const unsigned int id = ReadIndexFromText(); const unsigned int id = ReadIndexFromText();
std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id); std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id);
@ -779,8 +729,7 @@ void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
out.pos = (*it).second; out.pos = (*it).second;
havep = true; havep = true;
} } else if (s == "nref") {
else if (s == "nref") {
const unsigned int id = ReadIndexFromText(); const unsigned int id = ReadIndexFromText();
std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id); std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id);
if (it == t.normals.end()) { if (it == t.normals.end()) {
@ -789,8 +738,7 @@ void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
out.normal = (*it).second; out.normal = (*it).second;
out.has_normal = true; out.has_normal = true;
} } else if (s == "tcref") {
else if (s == "tcref") {
const unsigned int id = ReadIndexFromText(); const unsigned int id = ReadIndexFromText();
std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id); std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id);
if (it == t.uvs.end()) { if (it == t.uvs.end()) {
@ -799,14 +747,11 @@ void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
out.uv = (*it).second; out.uv = (*it).second;
out.has_uv = true; out.has_uv = true;
} } else if (s == "p") {
else if (s == "p") {
out.pos = ReadVec3(); out.pos = ReadVec3();
} } else if (s == "n") {
else if (s == "n") {
out.normal = ReadVec3(); out.normal = ReadVec3();
} } else if (s == "tc") {
else if (s == "tc") {
out.uv = ReadVec2(); out.uv = ReadVec2();
} }
} }
@ -817,11 +762,10 @@ void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadIDAttr() unsigned int XGLImporter::ReadIDAttr() {
{ for (int i = 0, e = m_reader->getAttributeCount(); i < e; ++i) {
for(int i = 0, e = m_reader->getAttributeCount(); i < e; ++i) {
if(!ASSIMP_stricmp(m_reader->getAttributeName(i),"id")) { if (!ASSIMP_stricmp(m_reader->getAttributeName(i), "id")) {
return m_reader->getAttributeValueAsInt(i); return m_reader->getAttributeValueAsInt(i);
} }
} }
@ -829,21 +773,20 @@ unsigned int XGLImporter::ReadIDAttr()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
float XGLImporter::ReadFloat() float XGLImporter::ReadFloat() {
{ if (!SkipToText()) {
if(!SkipToText()) {
LogError("unexpected EOF reading float element contents"); LogError("unexpected EOF reading float element contents");
return 0.f; return 0.f;
} }
const char* s = m_reader->getNodeData(), *se; const char *s = m_reader->getNodeData(), *se;
if(!SkipSpaces(&s)) { if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse float"); LogError("unexpected EOL, failed to parse float");
return 0.f; return 0.f;
} }
float t; float t;
se = fast_atoreal_move(s,t); se = fast_atoreal_move(s, t);
if (se == s) { if (se == s) {
LogError("failed to read float text"); LogError("failed to read float text");
@ -854,19 +797,18 @@ float XGLImporter::ReadFloat()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int XGLImporter::ReadIndexFromText() unsigned int XGLImporter::ReadIndexFromText() {
{ if (!SkipToText()) {
if(!SkipToText()) {
LogError("unexpected EOF reading index element contents"); LogError("unexpected EOF reading index element contents");
return ~0u; return ~0u;
} }
const char* s = m_reader->getNodeData(), *se; const char *s = m_reader->getNodeData(), *se;
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 ~0u;
} }
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");
@ -877,23 +819,22 @@ unsigned int XGLImporter::ReadIndexFromText()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiVector2D XGLImporter::ReadVec2() aiVector2D XGLImporter::ReadVec2() {
{
aiVector2D vec; aiVector2D vec;
if(!SkipToText()) { if (!SkipToText()) {
LogError("unexpected EOF reading vec2 contents"); LogError("unexpected EOF reading vec2 contents");
return vec; return vec;
} }
const char* s = m_reader->getNodeData(); const char *s = m_reader->getNodeData();
ai_real v[2]; ai_real v[2];
for(int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
if(!SkipSpaces(&s)) { if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse vec2"); LogError("unexpected EOL, failed to parse vec2");
return vec; return vec;
} }
v[i] = fast_atof(&s); v[i] = fast_atof(&s);
SkipSpaces(&s); SkipSpaces(&s);
@ -903,25 +844,24 @@ aiVector2D XGLImporter::ReadVec2()
} }
++s; ++s;
} }
vec.x = v[0]; vec.x = v[0];
vec.y = v[1]; vec.y = v[1];
return vec; return vec;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiVector3D XGLImporter::ReadVec3() aiVector3D XGLImporter::ReadVec3() {
{
aiVector3D vec; aiVector3D vec;
if(!SkipToText()) { if (!SkipToText()) {
LogError("unexpected EOF reading vec3 contents"); LogError("unexpected EOF reading vec3 contents");
return vec; return vec;
} }
const char* s = m_reader->getNodeData(); const char *s = m_reader->getNodeData();
for(int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if(!SkipSpaces(&s)) { if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse vec3"); LogError("unexpected EOL, failed to parse vec3");
return vec; return vec;
} }
@ -939,13 +879,12 @@ aiVector3D XGLImporter::ReadVec3()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiColor3D XGLImporter::ReadCol3() aiColor3D XGLImporter::ReadCol3() {
{ const aiVector3D &v = ReadVec3();
const aiVector3D& v = ReadVec3();
if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) { if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) {
LogWarn("color values out of range, ignoring"); LogWarn("color values out of range, ignoring");
} }
return aiColor3D(v.x,v.y,v.z); return aiColor3D(v.x, v.y, v.z);
} }
#endif #endif

View File

@ -47,69 +47,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_XGLLOADER_H_INCLUDED #define AI_XGLLOADER_H_INCLUDED
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/irrXMLWrapper.h>
#include <assimp/LogAux.h> #include <assimp/LogAux.h>
#include <assimp/material.h> #include <assimp/irrXMLWrapper.h>
#include <assimp/Importer.hpp>
#include <assimp/mesh.h>
#include <assimp/light.h> #include <assimp/light.h>
#include <memory> #include <assimp/material.h>
#include <assimp/mesh.h>
#include <assimp/Importer.hpp>
#include <map> #include <map>
#include <memory>
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** XGL/ZGL importer. /** XGL/ZGL importer.
* *
* Spec: http://vizstream.aveva.com/release/vsplatform/XGLSpec.htm * Spec: http://vizstream.aveva.com/release/vsplatform/XGLSpec.htm
*/ */
class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter> class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter> {
{
public: public:
XGLImporter(); XGLImporter();
~XGLImporter(); ~XGLImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** 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; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details */ * See #BaseImporter::GetInfo for the details */
const aiImporterDesc* GetInfo () const; const aiImporterDesc *GetInfo() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details */ * See BaseImporter::InternReadFile() for details */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem* pIOHandler); IOSystem *pIOHandler);
private: private:
struct TempScope {
TempScope() :
light() {}
~TempScope() {
struct TempScope for (aiMesh *m : meshes_linear) {
{
TempScope()
: light()
{}
~TempScope()
{
for(aiMesh* m : meshes_linear) {
delete m; delete m;
} }
for(aiMaterial* m : materials_linear) { for (aiMaterial *m : materials_linear) {
delete m; delete m;
} }
@ -117,45 +107,41 @@ private:
} }
void dismiss() { void dismiss() {
light = NULL; light = nullptr;
meshes_linear.clear(); meshes_linear.clear();
materials_linear.clear(); materials_linear.clear();
meshes.clear(); meshes.clear();
materials.clear(); materials.clear();
} }
std::multimap<unsigned int, aiMesh*> meshes; std::multimap<unsigned int, aiMesh *> meshes;
std::map<unsigned int, aiMaterial*> materials; std::map<unsigned int, aiMaterial *> materials;
std::vector<aiMesh*> meshes_linear; std::vector<aiMesh *> meshes_linear;
std::vector<aiMaterial*> materials_linear; std::vector<aiMaterial *> materials_linear;
aiLight* light; aiLight *light;
}; };
struct SortMeshByMaterialId { struct SortMeshByMaterialId {
SortMeshByMaterialId(const TempScope& scope) : scope(scope) {} SortMeshByMaterialId(const TempScope &scope) :
scope(scope) {}
bool operator()(unsigned int a, unsigned int b) const { bool operator()(unsigned int a, unsigned int b) const {
return scope.meshes_linear[a]->mMaterialIndex < scope.meshes_linear[b]->mMaterialIndex; return scope.meshes_linear[a]->mMaterialIndex < scope.meshes_linear[b]->mMaterialIndex;
}; };
const TempScope& scope; const TempScope &scope;
}; };
struct TempMesh struct TempMesh {
{
std::map<unsigned int, aiVector3D> points; std::map<unsigned int, aiVector3D> points;
std::map<unsigned int, aiVector3D> normals; std::map<unsigned int, aiVector3D> normals;
std::map<unsigned int, aiVector2D> uvs; std::map<unsigned int, aiVector2D> uvs;
}; };
struct TempMaterialMesh struct TempMaterialMesh {
{ TempMaterialMesh() :
TempMaterialMesh() pflags(), matid() {}
: pflags()
, matid()
{}
std::vector<aiVector3D> positions, normals; std::vector<aiVector3D> positions, normals;
std::vector<aiVector2D> uvs; std::vector<aiVector2D> uvs;
@ -165,12 +151,9 @@ private:
unsigned int matid; unsigned int matid;
}; };
struct TempFace struct TempFace {
{ TempFace() :
TempFace() has_uv(), has_normal() {}
: has_uv()
, has_normal()
{}
aiVector3D pos; aiVector3D pos;
aiVector3D normal; aiVector3D normal;
@ -180,21 +163,20 @@ 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(); unsigned int ReadIDAttr();
void ReadWorld(TempScope& scope); void ReadWorld(TempScope &scope);
void ReadLighting(TempScope& scope); void ReadLighting(TempScope &scope);
aiLight* ReadDirectionalLight(); aiLight *ReadDirectionalLight();
aiNode* ReadObject(TempScope& scope,bool skipFirst = false,const char* closetag = "object"); aiNode *ReadObject(TempScope &scope, bool skipFirst = false, const char *closetag = "object");
bool ReadMesh(TempScope& scope); bool ReadMesh(TempScope &scope);
void ReadMaterial(TempScope& scope); void ReadMaterial(TempScope &scope);
aiVector2D ReadVec2(); aiVector2D ReadVec2();
aiVector3D ReadVec3(); aiVector3D ReadVec3();
aiColor3D ReadCol3(); aiColor3D ReadCol3();
@ -202,13 +184,13 @@ private:
unsigned int ReadIndexFromText(); unsigned int ReadIndexFromText();
float ReadFloat(); float ReadFloat();
aiMesh* ToOutputMesh(const TempMaterialMesh& m); aiMesh *ToOutputMesh(const TempMaterialMesh &m);
void ReadFaceVertex(const TempMesh& t, TempFace& out); void ReadFaceVertex(const TempMesh &t, TempFace &out);
unsigned int ResolveMaterialRef(TempScope& scope); unsigned int ResolveMaterialRef(TempScope &scope);
private: private:
std::shared_ptr<irr::io::IrrXMLReader> m_reader; std::shared_ptr<irr::io::IrrXMLReader> m_reader;
aiScene* m_scene; aiScene *m_scene;
}; };
} // end of namespace Assimp } // end of namespace Assimp

Some files were not shown because too many files have changed in this diff Show More