From 48e5b948e3d1c408f22fb0fa853dfd29c277084a Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Wed, 24 Apr 2019 09:03:59 +0200 Subject: [PATCH 1/5] Update ColladaExporter.cpp Some reformattings --- code/ColladaExporter.cpp | 102 ++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/code/ColladaExporter.cpp b/code/ColladaExporter.cpp index e7cc6907d..7c21dde43 100644 --- a/code/ColladaExporter.cpp +++ b/code/ColladaExporter.cpp @@ -64,13 +64,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; -namespace Assimp -{ +namespace Assimp { // ------------------------------------------------------------------------------------------------ // Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp -void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) -{ +void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) { std::string path = DefaultIOSystem::absolutePath(std::string(pFile)); std::string file = DefaultIOSystem::completeBaseName(std::string(pFile)); @@ -93,12 +91,12 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p } // end of namespace Assimp - - // ------------------------------------------------------------------------------------------------ // Constructor for a specific scene to export -ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file) -{ +ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) +: mIOSystem(pIOSystem) +, mPath(path) +, mFile(file) { // make sure that all formatting happens using the standard, C locale and not the user's current locale mOutput.imbue( std::locale("C") ); mOutput.precision(16); @@ -115,17 +113,15 @@ ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, co // ------------------------------------------------------------------------------------------------ // Destructor -ColladaExporter::~ColladaExporter() -{ - if(mSceneOwned) { +ColladaExporter::~ColladaExporter() { + if ( mSceneOwned ) { delete mScene; } } // ------------------------------------------------------------------------------------------------ // Starts writing the contents -void ColladaExporter::WriteFile() -{ +void ColladaExporter::WriteFile() { // write the DTD mOutput << "" << endstr; // COLLADA element start @@ -158,8 +154,7 @@ void ColladaExporter::WriteFile() // ------------------------------------------------------------------------------------------------ // Writes the asset header -void ColladaExporter::WriteHeader() -{ +void ColladaExporter::WriteHeader() { static const ai_real epsilon = ai_real( 0.00001 ); static const aiQuaternion x_rot(aiMatrix3x3( 0, -1, 0, @@ -240,51 +235,60 @@ void ColladaExporter::WriteHeader() // If no Scene metadata, use root node metadata aiMetadata* meta = mScene->mMetaData; - if (!meta) + if (nullptr == meta) { meta = mScene->mRootNode->mMetaData; + } aiString value; - if (!meta || !meta->Get("Author", value)) + if (!meta || !meta->Get("Author", value)) { mOutput << startstr << "" << "Assimp" << "" << endstr; - else + } else { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; + } - if (!meta || !meta->Get("AuthoringTool", value)) + if (nullptr == meta || !meta->Get("AuthoringTool", value)) { mOutput << startstr << "" << "Assimp Exporter" << "" << endstr; - else + } else { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; + } - if (meta) - { - if (meta->Get("Comments", value)) + if (meta) { + if (meta->Get("Comments", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; - if (meta->Get("Copyright", value)) + } + if (meta->Get("Copyright", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; - if (meta->Get("SourceData", value)) + } + if (meta->Get("SourceData", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; + } } PopTag(); mOutput << startstr << "" << endstr; - if (!meta || !meta->Get("Created", value)) + if (nullptr == meta || !meta->Get("Created", value)) { mOutput << startstr << "" << date_str << "" << endstr; - else + } else { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; + } // Modified date is always the date saved mOutput << startstr << "" << date_str << "" << endstr; - if (meta) - { - if (meta->Get("Keywords", value)) + if (meta) { + if (meta->Get("Keywords", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; - if (meta->Get("Revision", value)) + } + if (meta->Get("Revision", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; - if (meta->Get("Subject", value)) + } + if (meta->Get("Subject", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; - if (meta->Get("Title", value)) + } + if (meta->Get("Title", value)) { mOutput << startstr << "" << XMLEscape(value.C_Str()) << "" << endstr; + } } mOutput << startstr << "" << endstr; @@ -299,12 +303,15 @@ void ColladaExporter::WriteTextures() { static const unsigned int buffer_size = 1024; char str[buffer_size]; - if(mScene->HasTextures()) { + if (mScene->HasTextures()) { for(unsigned int i = 0; i < mScene->mNumTextures; i++) { // It would be great to be able to create a directory in portable standard C++, but it's not the case, // so we just write the textures in the current directory. aiTexture* texture = mScene->mTextures[i]; + if ( nullptr == texture ) { + continue; + } ASSIMP_itoa10(str, buffer_size, i + 1); @@ -458,6 +465,7 @@ void ColladaExporter::WritePointLight(const aiLight *const light){ mOutput << startstr << "" << endstr; } + void ColladaExporter::WriteDirectionalLight(const aiLight *const light){ const aiColor3D &color= light->mColorDiffuse; mOutput << startstr << "" << endstr; @@ -470,6 +478,7 @@ void ColladaExporter::WriteDirectionalLight(const aiLight *const light){ mOutput << startstr << "" << endstr; } + void ColladaExporter::WriteSpotLight(const aiLight *const light){ const aiColor3D &color= light->mColorDiffuse; @@ -526,18 +535,16 @@ void ColladaExporter::WriteAmbienttLight(const aiLight *const light){ // ------------------------------------------------------------------------------------------------ // Reads a single surface entry from the given material keys -void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) -{ - if( pSrcMat->GetTextureCount( pTexture) > 0 ) - { +void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, + aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) { + if( pSrcMat->GetTextureCount( pTexture) > 0 ) { aiString texfile; unsigned int uvChannel = 0; pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel); std::string index_str(texfile.C_Str()); - if(index_str.size() != 0 && index_str[0] == '*') - { + if(index_str.size() != 0 && index_str[0] == '*') { unsigned int index; index_str = index_str.substr(1, std::string::npos); @@ -555,15 +562,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* } else { throw DeadlyExportError("could not find embedded texture at index " + index_str); } - } else - { + } else { poSurface.texture = texfile.C_Str(); } poSurface.channel = uvChannel; poSurface.exist = true; - } else - { + } else { if( pKey ) poSurface.exist = pSrcMat->Get( pKey, static_cast(pType), static_cast(pIndex), poSurface.color) == aiReturn_SUCCESS; } @@ -571,15 +576,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* // ------------------------------------------------------------------------------------------------ // Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version. -static bool isalnum_C(char c) -{ +static bool isalnum_C(char c) { return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) ); } // ------------------------------------------------------------------------------------------------ // Writes an image entry for the given surface -void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd) -{ +void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd) { if( !pSurface.texture.empty() ) { mOutput << startstr << "" << endstr; @@ -833,8 +836,9 @@ void ColladaExporter::WriteControllerLibrary() mOutput << startstr << "" << endstr; PushTag(); - for( size_t a = 0; a < mScene->mNumMeshes; ++a) + for( size_t a = 0; a < mScene->mNumMeshes; ++a) { WriteController( a); + } PopTag(); mOutput << startstr << "" << endstr; From e83671f494247501793c9631fe2816e6c0357464 Mon Sep 17 00:00:00 2001 From: Martin Vorbrodt Date: Wed, 24 Apr 2019 18:35:14 -0400 Subject: [PATCH 2/5] Generate attenuation constants if non are privded in the Blender file. Using: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/ --- code/BlenderLoader.cpp | 27 +++++++++++++++++++++++++++ code/BlenderScene.cpp | 5 ++++- code/BlenderScene.h | 4 ++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/code/BlenderLoader.cpp b/code/BlenderLoader.cpp index 90065ceee..d39cb9699 100644 --- a/code/BlenderLoader.cpp +++ b/code/BlenderLoader.cpp @@ -1225,6 +1225,16 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c case Lamp::Type_Local: out->mType = aiLightSource_POINT; break; + case Lamp::Type_Spot: + out->mType = aiLightSource_SPOT; + + // blender orients directional lights as facing toward -z + out->mDirection = aiVector3D(0.f, 0.f, -1.f); + out->mUp = aiVector3D(0.f, 1.f, 0.f); + + out->mAngleInnerCone = lamp->spotsize * (1.0f - lamp->spotblend); + out->mAngleOuterCone = lamp->spotsize; + break; case Lamp::Type_Sun: out->mType = aiLightSource_DIRECTIONAL; @@ -1255,6 +1265,23 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy; + + // If default values are supplied, compute the coefficients from light's max distance + // Read this: https://imdoingitwrong.wordpress.com/2011/01/31/light-attenuation/ + // + if (lamp->constant_coefficient == 1.0f && lamp->linear_coefficient == 0.0f && lamp->quadratic_coefficient == 0.0f && lamp->dist > 0.0f) + { + out->mAttenuationConstant = 1.0f; + out->mAttenuationLinear = 2.0f / lamp->dist; + out->mAttenuationQuadratic = 1.0f / (lamp->dist * lamp->dist); + } + else + { + out->mAttenuationConstant = lamp->constant_coefficient; + out->mAttenuationLinear = lamp->linear_coefficient; + out->mAttenuationQuadratic = lamp->quadratic_coefficient; + } + return out.release(); } diff --git a/code/BlenderScene.cpp b/code/BlenderScene.cpp index 4fc353b15..39c2793d5 100644 --- a/code/BlenderScene.cpp +++ b/code/BlenderScene.cpp @@ -211,9 +211,12 @@ template <> void Structure :: Convert ( ReadField(dest.b,"b",db); ReadField(dest.k,"k",db); ReadField(dest.energy,"energy",db); - ReadField(dest.dist,"dist",db); + ReadField(dest.dist,"dist",db); ReadField(dest.spotsize,"spotsize",db); ReadField(dest.spotblend,"spotblend",db); + ReadField(dest.constant_coefficient, "coeff_const", db); + ReadField(dest.linear_coefficient, "coeff_lin", db); + ReadField(dest.quadratic_coefficient, "coeff_quad", db); ReadField(dest.att1,"att1",db); ReadField(dest.att2,"att2",db); ReadField(temp,"falloff_type",db); diff --git a/code/BlenderScene.h b/code/BlenderScene.h index 8e4223eb1..dd3f1444c 100644 --- a/code/BlenderScene.h +++ b/code/BlenderScene.h @@ -538,6 +538,10 @@ struct Lamp : ElemBase { float energy, dist, spotsize, spotblend; //float haint; + float constant_coefficient; + float linear_coefficient; + float quadratic_coefficient; + float att1, att2; //struct CurveMapping *curfalloff; FalloffType falloff_type; From fd0e0d05e657ec56fab61282f5f50bd2c9049092 Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Sat, 11 May 2019 13:02:07 +0200 Subject: [PATCH 3/5] Inno: fix ArchitecturesInstallIn64BitMode for x86 platforms. --- packaging/windows-innosetup/script_x86.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/windows-innosetup/script_x86.iss b/packaging/windows-innosetup/script_x86.iss index 29ab5c011..d22d23b64 100644 --- a/packaging/windows-innosetup/script_x86.iss +++ b/packaging/windows-innosetup/script_x86.iss @@ -16,7 +16,7 @@ OutputBaseFileName=assimp-sdk-5.0.0-setup VersionInfoVersion=4.1.0.0 VersionInfoTextVersion=4.1.0 VersionInfoCompany=Assimp Development Team -ArchitecturesInstallIn64BitMode=x86 +;ArchitecturesInstallIn64BitMode=x64 [Types] Name: "full"; Description: "Full installation" From 461e21f66dd331f5d6d47b4abbf9f15525ddfaec Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sun, 12 May 2019 10:56:59 -1000 Subject: [PATCH 4/5] Fix Windows build with external zlib assimp.rc contains an include with a double-parent header search. In a default build configuration, this is resolved via the configuration header path generated for in-tree zlib. When external zlib is used, this header search path is not provided to the RC compiler, therefore fails to find revision.h. This is solved by simply including "revision.h" since the root of the binary directory is already used as a search path. --- code/res/assimp.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/res/assimp.rc b/code/res/assimp.rc index ae0c87b8a..14ffdf4f5 100644 --- a/code/res/assimp.rc +++ b/code/res/assimp.rc @@ -1,7 +1,7 @@ // Microsoft Visual C++ generated resource script. // #include "resource.h" -#include "..\..\revision.h" +#include "revision.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// From adbdbf2be6b1ecf25cbc92f1c6fc61a7d818bf2f Mon Sep 17 00:00:00 2001 From: Kim Kulling Date: Mon, 13 May 2019 21:41:37 +0200 Subject: [PATCH 5/5] closes https://github.com/assimp/assimp/issues/2459: fix duplicated fbx-type propertry. --- code/FBXExportNode.h | 9 +- code/FBXExportProperty.cpp | 259 +++++++++++++++++++--------------- code/FBXExportProperty.h | 49 ++++--- code/FBXExporter.cpp | 6 +- test/models/PLY/cube_test.ply | 2 +- 5 files changed, 174 insertions(+), 151 deletions(-) diff --git a/code/FBXExportNode.h b/code/FBXExportNode.h index b388a4f86..ef3bc781a 100644 --- a/code/FBXExportNode.h +++ b/code/FBXExportNode.h @@ -59,12 +59,11 @@ namespace FBX { class Node; } -class FBX::Node -{ -public: // public data members +class FBX::Node { +public: // TODO: accessors std::string name; // node name - std::vector properties; // node properties + std::vector properties; // node properties std::vector children; // child nodes // some nodes always pretend they have children... @@ -215,7 +214,7 @@ public: // static member functions Assimp::StreamWriterLE& s, bool binary, int indent ) { - FBX::Property p(value); + FBX::FBXExportProperty p(value); FBX::Node node(name, p); node.Dump(s, binary, indent); } diff --git a/code/FBXExportProperty.cpp b/code/FBXExportProperty.cpp index ac464c806..f8593e629 100644 --- a/code/FBXExportProperty.cpp +++ b/code/FBXExportProperty.cpp @@ -53,186 +53,209 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include // ostringstream namespace Assimp { +namespace FBX { + // constructors for single element properties -FBX::Property::Property(bool v) - : type('C'), data(1) -{ - data = {uint8_t(v)}; +FBXExportProperty::FBXExportProperty(bool v) +: type('C') +, data(1) { + data = { + uint8_t(v) + }; } -FBX::Property::Property(int16_t v) : type('Y'), data(2) -{ +FBXExportProperty::FBXExportProperty(int16_t v) +: type('Y') +, data(2) { uint8_t* d = data.data(); (reinterpret_cast(d))[0] = v; } -FBX::Property::Property(int32_t v) : type('I'), data(4) -{ +FBXExportProperty::FBXExportProperty(int32_t v) +: type('I') +, data(4) { uint8_t* d = data.data(); (reinterpret_cast(d))[0] = v; } -FBX::Property::Property(float v) : type('F'), data(4) -{ +FBXExportProperty::FBXExportProperty(float v) +: type('F') +, data(4) { uint8_t* d = data.data(); (reinterpret_cast(d))[0] = v; } -FBX::Property::Property(double v) : type('D'), data(8) -{ +FBXExportProperty::FBXExportProperty(double v) +: type('D') +, data(8) { uint8_t* d = data.data(); (reinterpret_cast(d))[0] = v; } -FBX::Property::Property(int64_t v) : type('L'), data(8) -{ +FBXExportProperty::FBXExportProperty(int64_t v) +: type('L') +, data(8) { uint8_t* d = data.data(); (reinterpret_cast(d))[0] = v; } - // constructors for array-type properties -FBX::Property::Property(const char* c, bool raw) - : Property(std::string(c), raw) -{} +FBXExportProperty::FBXExportProperty(const char* c, bool raw) +: FBXExportProperty(std::string(c), raw) { + // empty +} // strings can either be saved as "raw" (R) data, or "string" (S) data -FBX::Property::Property(const std::string& s, bool raw) - : type(raw ? 'R' : 'S'), data(s.size()) -{ +FBXExportProperty::FBXExportProperty(const std::string& s, bool raw) +: type(raw ? 'R' : 'S') +, data(s.size()) { for (size_t i = 0; i < s.size(); ++i) { data[i] = uint8_t(s[i]); } } -FBX::Property::Property(const std::vector& r) - : type('R'), data(r) -{} +FBXExportProperty::FBXExportProperty(const std::vector& r) +: type('R') +, data(r) { + // empty +} -FBX::Property::Property(const std::vector& va) - : type('i'), data(4*va.size()) -{ +FBXExportProperty::FBXExportProperty(const std::vector& va) +: type('i') +, data(4 * va.size() ) { int32_t* d = reinterpret_cast(data.data()); - for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; } + for (size_t i = 0; i < va.size(); ++i) { + d[i] = va[i]; + } } -FBX::Property::Property(const std::vector& va) - : type('l'), data(8*va.size()) -{ +FBXExportProperty::FBXExportProperty(const std::vector& va) +: type('l') +, data(8 * va.size()) { int64_t* d = reinterpret_cast(data.data()); - for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; } + for (size_t i = 0; i < va.size(); ++i) { + d[i] = va[i]; + } } -FBX::Property::Property(const std::vector& va) - : type('f'), data(4*va.size()) -{ +FBXExportProperty::FBXExportProperty(const std::vector& va) +: type('f') +, data(4 * va.size()) { float* d = reinterpret_cast(data.data()); - for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; } + for (size_t i = 0; i < va.size(); ++i) { + d[i] = va[i]; + } } -FBX::Property::Property(const std::vector& va) - : type('d'), data(8*va.size()) -{ +FBXExportProperty::FBXExportProperty(const std::vector& va) +: type('d') +, data(8 * va.size()) { double* d = reinterpret_cast(data.data()); - for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; } + for (size_t i = 0; i < va.size(); ++i) { + d[i] = va[i]; + } } -FBX::Property::Property(const aiMatrix4x4& vm) - : type('d'), data(8*16) -{ +FBXExportProperty::FBXExportProperty(const aiMatrix4x4& vm) +: type('d') +, data(8 * 16) { double* d = reinterpret_cast(data.data()); for (unsigned int c = 0; c < 4; ++c) { for (unsigned int r = 0; r < 4; ++r) { - d[4*c+r] = vm[r][c]; + d[4 * c + r] = vm[r][c]; } } } // public member functions -size_t FBX::Property::size() -{ +size_t FBXExportProperty::size() { switch (type) { - case 'C': case 'Y': case 'I': case 'F': case 'D': case 'L': - return data.size() + 1; - case 'S': case 'R': - return data.size() + 5; - case 'i': case 'd': - return data.size() + 13; - default: - throw DeadlyExportError("Requested size on property of unknown type"); + case 'C': + case 'Y': + case 'I': + case 'F': + case 'D': + case 'L': + return data.size() + 1; + case 'S': + case 'R': + return data.size() + 5; + case 'i': + case 'd': + return data.size() + 13; + default: + throw DeadlyExportError("Requested size on property of unknown type"); } } -void FBX::Property::DumpBinary(Assimp::StreamWriterLE &s) -{ +void FBXExportProperty::DumpBinary(Assimp::StreamWriterLE& s) { s.PutU1(type); uint8_t* d = data.data(); size_t N; switch (type) { - case 'C': s.PutU1(*(reinterpret_cast(d))); return; - case 'Y': s.PutI2(*(reinterpret_cast(d))); return; - case 'I': s.PutI4(*(reinterpret_cast(d))); return; - case 'F': s.PutF4(*(reinterpret_cast(d))); return; - case 'D': s.PutF8(*(reinterpret_cast(d))); return; - case 'L': s.PutI8(*(reinterpret_cast(d))); return; - case 'S': - case 'R': - s.PutU4(uint32_t(data.size())); - for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); } - return; - case 'i': - N = data.size() / 4; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutI4((reinterpret_cast(d))[i]); - } - return; - case 'l': - N = data.size() / 8; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutI8((reinterpret_cast(d))[i]); - } - return; - case 'f': - N = data.size() / 4; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutF4((reinterpret_cast(d))[i]); - } - return; - case 'd': - N = data.size() / 8; - s.PutU4(uint32_t(N)); // number of elements - s.PutU4(0); // no encoding (1 would be zip-compressed) - // TODO: compress if large? - s.PutU4(uint32_t(data.size())); // data size - for (size_t i = 0; i < N; ++i) { - s.PutF8((reinterpret_cast(d))[i]); - } - return; - default: - std::ostringstream err; - err << "Tried to dump property with invalid type '"; - err << type << "'!"; - throw DeadlyExportError(err.str()); + case 'C': s.PutU1(*(reinterpret_cast(d))); return; + case 'Y': s.PutI2(*(reinterpret_cast(d))); return; + case 'I': s.PutI4(*(reinterpret_cast(d))); return; + case 'F': s.PutF4(*(reinterpret_cast(d))); return; + case 'D': s.PutF8(*(reinterpret_cast(d))); return; + case 'L': s.PutI8(*(reinterpret_cast(d))); return; + case 'S': + case 'R': + s.PutU4(uint32_t(data.size())); + for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); } + return; + case 'i': + N = data.size() / 4; + s.PutU4(uint32_t(N)); // number of elements + s.PutU4(0); // no encoding (1 would be zip-compressed) + // TODO: compress if large? + s.PutU4(uint32_t(data.size())); // data size + for (size_t i = 0; i < N; ++i) { + s.PutI4((reinterpret_cast(d))[i]); + } + return; + case 'l': + N = data.size() / 8; + s.PutU4(uint32_t(N)); // number of elements + s.PutU4(0); // no encoding (1 would be zip-compressed) + // TODO: compress if large? + s.PutU4(uint32_t(data.size())); // data size + for (size_t i = 0; i < N; ++i) { + s.PutI8((reinterpret_cast(d))[i]); + } + return; + case 'f': + N = data.size() / 4; + s.PutU4(uint32_t(N)); // number of elements + s.PutU4(0); // no encoding (1 would be zip-compressed) + // TODO: compress if large? + s.PutU4(uint32_t(data.size())); // data size + for (size_t i = 0; i < N; ++i) { + s.PutF4((reinterpret_cast(d))[i]); + } + return; + case 'd': + N = data.size() / 8; + s.PutU4(uint32_t(N)); // number of elements + s.PutU4(0); // no encoding (1 would be zip-compressed) + // TODO: compress if large? + s.PutU4(uint32_t(data.size())); // data size + for (size_t i = 0; i < N; ++i) { + s.PutF8((reinterpret_cast(d))[i]); + } + return; + default: + std::ostringstream err; + err << "Tried to dump property with invalid type '"; + err << type << "'!"; + throw DeadlyExportError(err.str()); } } -void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent) -{ +void FBXExportProperty::DumpAscii(Assimp::StreamWriterLE& outstream, int indent) { std::ostringstream ss; ss.imbue(std::locale::classic()); ss.precision(15); // this seems to match official FBX SDK exports @@ -240,8 +263,7 @@ void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent) outstream.PutString(ss.str()); } -void FBX::Property::DumpAscii(std::ostream& s, int indent) -{ +void FBXExportProperty::DumpAscii(std::ostream& s, int indent) { // no writing type... or anything. just shove it into the stream. uint8_t* d = data.data(); size_t N; @@ -359,6 +381,9 @@ void FBX::Property::DumpAscii(std::ostream& s, int indent) throw runtime_error(err.str()); } } -} + +} // Namespace FBX +} // Namespace Assimp + #endif // ASSIMP_BUILD_NO_FBX_EXPORTER #endif // ASSIMP_BUILD_NO_EXPORT diff --git a/code/FBXExportProperty.h b/code/FBXExportProperty.h index 424bf8b32..d692fe6ee 100644 --- a/code/FBXExportProperty.h +++ b/code/FBXExportProperty.h @@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ASSIMP_BUILD_NO_FBX_EXPORTER - #include // aiMatrix4x4 #include // StreamWriterLE @@ -58,10 +57,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace Assimp { namespace FBX { - class Property; -} -/** FBX::Property +/** @brief FBX::Property * * Holds a value of any of FBX's recognized types, * each represented by a particular one-character code. @@ -79,35 +76,34 @@ namespace FBX { * S : string (array of 1-byte char) * R : raw data (array of bytes) */ -class FBX::Property -{ +class FBXExportProperty { public: // constructors for basic types. // all explicit to avoid accidental typecasting - explicit Property(bool v); + explicit FBXExportProperty(bool v); // TODO: determine if there is actually a byte type, // or if this always means . 'C' seems to imply , // so possibly the above was intended to represent both. - explicit Property(int16_t v); - explicit Property(int32_t v); - explicit Property(float v); - explicit Property(double v); - explicit Property(int64_t v); + explicit FBXExportProperty(int16_t v); + explicit FBXExportProperty(int32_t v); + explicit FBXExportProperty(float v); + explicit FBXExportProperty(double v); + explicit FBXExportProperty(int64_t v); // strings can either be stored as 'R' (raw) or 'S' (string) type - explicit Property(const char* c, bool raw=false); - explicit Property(const std::string& s, bool raw=false); - explicit Property(const std::vector& r); - explicit Property(const std::vector& va); - explicit Property(const std::vector& va); - explicit Property(const std::vector& va); - explicit Property(const std::vector& va); - explicit Property(const aiMatrix4x4& vm); + explicit FBXExportProperty(const char* c, bool raw = false); + explicit FBXExportProperty(const std::string& s, bool raw = false); + explicit FBXExportProperty(const std::vector& r); + explicit FBXExportProperty(const std::vector& va); + explicit FBXExportProperty(const std::vector& va); + explicit FBXExportProperty(const std::vector& va); + explicit FBXExportProperty(const std::vector& va); + explicit FBXExportProperty(const aiMatrix4x4& vm); // this will catch any type not defined above, // so that we don't accidentally convert something we don't want. // for example (const char*) --> (bool)... seriously wtf C++ template - explicit Property(T v) : type('X') { + explicit FBXExportProperty(T v) : type('X') { static_assert(std::is_void::value, "TRIED TO CREATE FBX PROPERTY WITH UNSUPPORTED TYPE, CHECK YOUR PROPERTY INSTANTIATION"); } // note: no line wrap so it appears verbatim on the compiler error @@ -115,16 +111,19 @@ public: size_t size(); // write this property node as binary data to the given stream - void DumpBinary(Assimp::StreamWriterLE &s); - void DumpAscii(Assimp::StreamWriterLE &s, int indent=0); - void DumpAscii(std::ostream &s, int indent=0); + void DumpBinary(Assimp::StreamWriterLE& s); + void DumpAscii(Assimp::StreamWriterLE& s, int indent = 0); + void DumpAscii(std::ostream& s, int indent = 0); // note: make sure the ostream is in classic "C" locale private: char type; std::vector data; }; -} + +} // Namespace FBX +} // Namespace Assimp + #endif // ASSIMP_BUILD_NO_FBX_EXPORTER #endif // AI_FBXEXPORTPROPERTY_H_INC diff --git a/code/FBXExporter.cpp b/code/FBXExporter.cpp index ddfac6d34..dd34e135f 100644 --- a/code/FBXExporter.cpp +++ b/code/FBXExporter.cpp @@ -2271,8 +2271,8 @@ void FBXExporter::WriteModelNode( // not sure what these are for, // but they seem to be omnipresent - m.AddChild("Shading", Property(true)); - m.AddChild("Culling", Property("CullingOff")); + m.AddChild("Shading", FBXExportProperty(true)); + m.AddChild("Culling", FBXExportProperty("CullingOff")); m.Dump(outstream, binary, 1); } @@ -2385,7 +2385,7 @@ void FBXExporter::WriteModelNodes( na.AddProperties( node_attribute_uid, FBX::SEPARATOR + "NodeAttribute", "LimbNode" ); - na.AddChild("TypeFlags", Property("Skeleton")); + na.AddChild("TypeFlags", FBXExportProperty("Skeleton")); na.Dump(outstream, binary, 1); // and connect them connections.emplace_back("C", "OO", node_attribute_uid, node_uid); diff --git a/test/models/PLY/cube_test.ply b/test/models/PLY/cube_test.ply index 6ec6d3991..a86d022a5 100644 --- a/test/models/PLY/cube_test.ply +++ b/test/models/PLY/cube_test.ply @@ -1,6 +1,6 @@ ply format ascii 1.0 -comment Created by Open Asset Import Library - http://assimp.sf.net (v4.1.412856994) +comment Created by Open Asset Import Library - http://assimp.sf.net (v4.1.3297435427) element vertex 8 property float x property float y