From 11af0866dce60802274b4386af246aa62d5e490e Mon Sep 17 00:00:00 2001 From: Gargaj Date: Sat, 2 Aug 2014 14:47:59 +0200 Subject: [PATCH 01/34] Add FieldOfView token type (fixes #245) "FieldOfView" has its own token type (basically just one float), if it's missing the camera will keep reverting to default FOV in ASSIMP. --- code/FBXProperties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/FBXProperties.cpp b/code/FBXProperties.cpp index 48bdb4f40..62cbba51d 100644 --- a/code/FBXProperties.cpp +++ b/code/FBXProperties.cpp @@ -105,7 +105,7 @@ Property* ReadTypedProperty(const Element& element) ParseTokenAsFloat(*tok[6])) ); } - else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float")) { + else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"KTime") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView")) { return new TypedProperty(ParseTokenAsFloat(*tok[4])); } return NULL; From e5ed62581d9672b05c3875e3c89d8333385790f5 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Sat, 2 Aug 2014 14:57:43 +0200 Subject: [PATCH 02/34] Handle both types of element names MAX seems to add an "s" to "Binormal" and "Tangent" when exporting --- code/FBXMeshGeometry.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/FBXMeshGeometry.cpp b/code/FBXMeshGeometry.cpp index be3fbd621..ebc75f48e 100644 --- a/code/FBXMeshGeometry.cpp +++ b/code/FBXMeshGeometry.cpp @@ -466,8 +466,9 @@ void MeshGeometry::ReadVertexDataTangents(std::vector& tangents_out, const std::string& MappingInformationType, const std::string& ReferenceInformationType) { + const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent"; ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType, - "Tangent", + str, "TangentIndex", vertices.size(), mapping_counts, @@ -481,8 +482,9 @@ void MeshGeometry::ReadVertexDataBinormals(std::vector& binormals_ou const std::string& MappingInformationType, const std::string& ReferenceInformationType) { + const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal"; ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType, - "Binormal", + str, "BinormalIndex", vertices.size(), mapping_counts, From 203d5d6fcc9c4d5559ff2cc6ac5dda9cf17d69bc Mon Sep 17 00:00:00 2001 From: acgessler Date: Sat, 2 Aug 2014 21:18:21 -0700 Subject: [PATCH 03/34] Obj: make mtl importer accept kd, ks etc. as well (Kd, Ks being the correct form). This is for keeping up compatibility with assimp's own Obj exporter, which has been inaccurate about this since inception. --- code/ObjFileMtlImporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ObjFileMtlImporter.cpp b/code/ObjFileMtlImporter.cpp index a25b960e7..90898f7b2 100644 --- a/code/ObjFileMtlImporter.cpp +++ b/code/ObjFileMtlImporter.cpp @@ -129,6 +129,7 @@ void ObjFileMtlImporter::load() { switch (*m_DataIt) { + case 'k': case 'K': { ++m_DataIt; From dfe1f03e5b392aa877c1760e63dd0c0171a63131 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Mon, 4 Aug 2014 23:57:08 +0200 Subject: [PATCH 04/34] Split off postprocessing progress --- code/Importer.cpp | 3 ++- include/assimp/ProgressHandler.hpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index c6b9daf67..50ce016d5 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -768,6 +768,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) { BaseProcess* process = pimpl->mPostProcessingSteps[a]; + pimpl->mProgressHandler->UpdatePostProcess( a, pimpl->mPostProcessingSteps.size() ); if( process->IsActive( pFlags)) { if (profiler) { @@ -775,7 +776,6 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) } process->ExecuteOnScene ( this ); - pimpl->mProgressHandler->Update(); if (profiler) { profiler->EndRegion("postprocess"); @@ -803,6 +803,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) } #endif // ! DEBUG } + pimpl->mProgressHandler->UpdatePostProcess( pimpl->mPostProcessingSteps.size(), pimpl->mPostProcessingSteps.size() ); // update private scene flags if( pimpl->mScene ) diff --git a/include/assimp/ProgressHandler.hpp b/include/assimp/ProgressHandler.hpp index 31c746c59..7a4cec84f 100644 --- a/include/assimp/ProgressHandler.hpp +++ b/include/assimp/ProgressHandler.hpp @@ -88,6 +88,19 @@ public: virtual bool Update(float percentage = -1.f) = 0; + // ------------------------------------------------------------------- + /** @brief Progress callback for post-processing steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * */ + virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = currentStep / (float)numberOfSteps; + Update( f * 0.5f + 0.5f ); + }; }; // !class ProgressHandler // ------------------------------------------------------------------------------------ From dbc553343ce52211aab14227929fe5202cf2b2e9 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 00:05:18 +0200 Subject: [PATCH 05/34] Granulate file loading too --- code/Importer.cpp | 4 ++-- include/assimp/ProgressHandler.hpp | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 50ce016d5..49cfeffa6 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,14 +642,14 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); - pimpl->mProgressHandler->Update(); + pimpl->mProgressHandler->UpdateFileRead( 0, 1 ); if (profiler) { profiler->BeginRegion("import"); } pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->Update(); + pimpl->mProgressHandler->UpdateFileRead( 1, 1 ); if (profiler) { profiler->EndRegion("import"); diff --git a/include/assimp/ProgressHandler.hpp b/include/assimp/ProgressHandler.hpp index 7a4cec84f..8aaa99276 100644 --- a/include/assimp/ProgressHandler.hpp +++ b/include/assimp/ProgressHandler.hpp @@ -81,12 +81,25 @@ public: * all needed cleanup tasks prior to returning control to the * caller). If the loading is aborted, #Importer::ReadFile() * returns always NULL. - * - * @note Currently, percentage is always -1.f because there is - * no reliable way to compute it. * */ virtual bool Update(float percentage = -1.f) = 0; + // ------------------------------------------------------------------- + /** @brief Progress callback for file loading steps + * @param numberOfSteps The number of total post-processing + * steps + * @param currentStep The index of the current post-processing + * step that will run, or equal to numberOfSteps if all of + * them has finished. This number is always strictly monotone + * increasing, although not necessarily linearly. + * + * @note This is currently only used at the start and the end + * of the file parsing. + * */ + virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { + float f = currentStep / (float)numberOfSteps; + Update( f * 0.5f ); + }; // ------------------------------------------------------------------- /** @brief Progress callback for post-processing steps From 6b8cbe5c834ef99ca2f330b97068b7af7d312b01 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 00:10:23 +0200 Subject: [PATCH 06/34] this isn't needed anymore --- code/Importer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 49cfeffa6..0a817476a 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -678,7 +678,6 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) ScenePreprocessor pre(pimpl->mScene); pre.ProcessScene(); - pimpl->mProgressHandler->Update(); if (profiler) { profiler->EndRegion("preprocess"); } From 8f960f0ed2ea073017e8f8672f3575c8de273a29 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 19:36:18 +0200 Subject: [PATCH 07/34] avoid division by zero --- include/assimp/ProgressHandler.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/assimp/ProgressHandler.hpp b/include/assimp/ProgressHandler.hpp index 8aaa99276..3ab1e489b 100644 --- a/include/assimp/ProgressHandler.hpp +++ b/include/assimp/ProgressHandler.hpp @@ -97,7 +97,7 @@ public: * of the file parsing. * */ virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = currentStep / (float)numberOfSteps; + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; Update( f * 0.5f ); }; @@ -111,7 +111,7 @@ public: * increasing, although not necessarily linearly. * */ virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) { - float f = currentStep / (float)numberOfSteps; + float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f; Update( f * 0.5f + 0.5f ); }; From 3d5e1b5cbc2e8359389172f5ff2f13b9d7593227 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 20:54:38 +0200 Subject: [PATCH 08/34] add basic framework (files, etc) --- code/AssbinExporter.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ code/AssbinExporter.h | 51 ++++++++++++++++++++++++++++++++++++ code/CMakeLists.txt | 7 +++++ code/Exporter.cpp | 5 ++++ 4 files changed, 121 insertions(+) create mode 100644 code/AssbinExporter.cpp create mode 100644 code/AssbinExporter.h diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp new file mode 100644 index 000000000..2f5e885c0 --- /dev/null +++ b/code/AssbinExporter.cpp @@ -0,0 +1,58 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +#include "AssimpPCH.h" +#include "assbin_chunks.h" +#include "./../include/assimp/version.h" + +#ifndef ASSIMP_BUILD_NO_EXPORT +#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER + +using namespace Assimp; + +namespace Assimp { + +void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) +{ +} +} // end of namespace Assimp + +#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER +#endif // ASSIMP_BUILD_NO_EXPORT diff --git a/code/AssbinExporter.h b/code/AssbinExporter.h new file mode 100644 index 000000000..f6a0cf598 --- /dev/null +++ b/code/AssbinExporter.h @@ -0,0 +1,51 @@ +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file AssbinExporter.h + * ASSBIN Exporter Main Header + */ +#ifndef AI_ASSBINEXPORTER_H_INC +#define AI_ASSBINEXPORTER_H_INC + +#include + +#include "StreamWriter.h" + +#endif diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 15cbe1321..0a57d540b 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -171,6 +171,12 @@ SET( ASE_SRCS ) SOURCE_GROUP( ASE FILES ${ASE_SRCS}) +SET( ASSBIN_SRCS + AssbinExporter.h + AssbinExporter.cpp +) +SOURCE_GROUP( Assbin FILES ${ASSBIN_SRCS}) + SET( B3D_SRCS B3DImporter.cpp B3DImporter.h @@ -646,6 +652,7 @@ SET( assimp_src ${3DS_SRCS} ${AC_SRCS} ${ASE_SRCS} + ${ASSBIN_SRCS} ${B3D_SRCS} ${BVH_SRCS} ${Collada_SRCS} diff --git a/code/Exporter.cpp b/code/Exporter.cpp index 7f51fb71f..c105e36ba 100644 --- a/code/Exporter.cpp +++ b/code/Exporter.cpp @@ -79,6 +79,7 @@ void ExportSceneSTL(const char*,IOSystem*, const aiScene*); void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*); void ExportScenePly(const char*,IOSystem*, const aiScene*); void ExportScene3DS(const char*, IOSystem*, const aiScene*); +void ExportSceneAssbin(const char*, IOSystem*, const aiScene*); // ------------------------------------------------------------------------------------------------ // global array of all export formats which Assimp supports in its current build @@ -117,6 +118,10 @@ Exporter::ExportFormatEntry gExporters[] = Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS, aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices), #endif + +#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER + Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, NULL), +#endif }; #define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0])) From 2592ff07967b72d7e3d9f13dc3d88a73806ec0e1 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 22:54:45 +0200 Subject: [PATCH 09/34] convert exporter from tools/assimp_cmd --- code/AssbinExporter.cpp | 688 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 688 insertions(+) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2f5e885c0..b3dfd082e 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "AssimpPCH.h" #include "assbin_chunks.h" #include "./../include/assimp/version.h" +#include "ProcessHelper.h" #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER @@ -49,8 +50,695 @@ using namespace Assimp; namespace Assimp { + class AssbinChunkWriter : public IOStream + { + private: + + uint8_t* buffer; + uint32_t magic; + IOStream * container; + uint32_t cur_size, cursor, initial; + + private: + // ------------------------------------------------------------------- + void Grow(size_t need = 0) + { + size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); + + const uint8_t* const old = buffer; + buffer = new uint8_t[new_size]; + + if (old) { + memcpy(buffer,old,cur_size); + delete[] old; + } + + cur_size = new_size; + } + + public: + + AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) + : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) + { + } + + virtual ~AssbinChunkWriter() + { + if (container) { + container->Write( &magic, sizeof(uint32_t), 1 ); + container->Write( &cursor, sizeof(uint32_t), 1 ); + container->Write( buffer, 1, cursor ); + } + if (buffer) delete[] buffer; + } + + // ------------------------------------------------------------------- + virtual size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount) { return 0; }; + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Tell() const { return 0; }; + virtual void Flush() { }; + + virtual size_t FileSize() const + { + return cursor; + } + + // ------------------------------------------------------------------- + virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) + { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } + + memcpy(buffer+cursor, pvBuffer, pSize); + cursor += pSize; + + return pCount; + } + + template + size_t Write(const T& v) + { + return Write( &v, sizeof(T), 1 ); + } + + // ----------------------------------------------------------------------------------- + // Serialize an aiString + template <> + inline uint32_t Write(const aiString& s) + { + const uint32_t s2 = (uint32_t)s.length; + Write(&s,4,1); + Write(s.data,s2,1); + return s2+4; + } + + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint32_t + template <> + inline uint32_t Write(const unsigned int& w) + { + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + printf("loss of data due to 64 -> 32 bit integer conversion"); + } + + Write(&t,4,1); + return 4; + } + + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint16_t + template <> + inline uint32_t Write(const uint16_t& w) + { + Write(&w,2,1); + return 2; + } + + // ----------------------------------------------------------------------------------- + // Serialize a float + template <> + inline uint32_t Write(const float& f) + { + BOOST_STATIC_ASSERT(sizeof(float)==4); + Write(&f,4,1); + return 4; + } + + // ----------------------------------------------------------------------------------- + // Serialize a double + template <> + inline uint32_t Write(const double& f) + { + BOOST_STATIC_ASSERT(sizeof(double)==8); + Write(&f,8,1); + return 8; + } + + // ----------------------------------------------------------------------------------- + // Serialize a vec3 + template <> + inline uint32_t Write(const aiVector3D& v) + { + uint32_t t = Write(v.x); + t += Write(v.y); + t += Write(v.z); + return t; + } + + // ----------------------------------------------------------------------------------- + // Serialize a color value + template <> + inline uint32_t Write(const aiColor4D& v) + { + uint32_t t = Write(v.r); + t += Write(v.g); + t += Write(v.b); + t += Write(v.a); + return t; + } + + // ----------------------------------------------------------------------------------- + // Serialize a quaternion + template <> + inline uint32_t Write(const aiQuaternion& v) + { + uint32_t t = Write(v.w); + t += Write(v.x); + t += Write(v.y); + t += Write(v.z); + return 16; + } + + + // ----------------------------------------------------------------------------------- + // Serialize a vertex weight + template <> + inline uint32_t Write(const aiVertexWeight& v) + { + uint32_t t = Write(v.mVertexId); + return t+Write(v.mWeight); + } + + // ----------------------------------------------------------------------------------- + // Serialize a mat4x4 + template <> + inline uint32_t Write(const aiMatrix4x4& m) + { + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write(m[i][i2]); + } + } + return 64; + } + + // ----------------------------------------------------------------------------------- + // Serialize an aiVectorKey + template <> + inline uint32_t Write(const aiVectorKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } + + // ----------------------------------------------------------------------------------- + // Serialize an aiQuatKey + template <> + inline uint32_t Write(const aiQuatKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } + + template + inline uint32_t WriteBounds(const T* in, unsigned int size) + { + T minc,maxc; + ArrayBounds(in,size,minc,maxc); + + const uint32_t t = Write(minc); + return t + Write(maxc); + } + + + }; + +/* + class AssbinChunkWriter + { + AssbinStream stream; + uint32_t magic; + public: + AssbinChunkWriter( uint32_t _magic ) + { + magic = _magic; + } + void AppendToStream( AssbinStream & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.Write( &magic, sizeof(uint32_t), 1 ); + _stream.Write( &s, sizeof(uint32_t), 1 ); + _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); + } + void AppendToStream( AssbinChunkWriter & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.WriteRaw( &magic, sizeof(uint32_t) ); + _stream.WriteRaw( &s, sizeof(uint32_t) ); + _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); + } + + }; +*/ + + class AssbinExport + { + private: + bool shortened; + bool compressed; + //AssbinStream stream; + + protected: + template + size_t Write( IOStream * container, const T& v) + { + return container->Write( &v, sizeof(T), 1 ); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryNode( IOStream * container, const aiNode* node) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); + + chunk.Write(node->mName); + chunk.Write(node->mTransformation); + chunk.Write(node->mNumChildren); + chunk.Write(node->mNumMeshes); + + for (unsigned int i = 0; i < node->mNumMeshes;++i) { + chunk.Write(node->mMeshes[i]); + } + + for (unsigned int i = 0; i < node->mNumChildren;++i) { + WriteBinaryNode( &chunk, node->mChildren[i] ); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryTexture(IOStream * container, const aiTexture* tex) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); + + chunk.Write(tex->mWidth); + chunk.Write(tex->mHeight); + chunk.Write( tex->achFormatHint, sizeof(char), 4 ); + + if(!shortened) { + if (!tex->mHeight) { + chunk.Write(tex->pcData,1,tex->mWidth); + } + else { + chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); + } + } + + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryBone(IOStream * container, const aiBone* b) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); + + chunk.Write(b->mName); + chunk.Write(b->mNumWeights); + chunk.Write(b->mOffsetMatrix); + + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) { + chunk.WriteBounds(b->mWeights,b->mNumWeights); + } // else write as usual + else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); + + chunk.Write(mesh->mPrimitiveTypes); + chunk.Write(mesh->mNumVertices); + chunk.Write(mesh->mNumFaces); + chunk.Write(mesh->mNumBones); + chunk.Write(mesh->mMaterialIndex); + + // first of all, write bits for all existent vertex components + unsigned int c = 0; + if (mesh->mVertices) { + c |= ASSBIN_MESH_HAS_POSITIONS; + } + if (mesh->mNormals) { + c |= ASSBIN_MESH_HAS_NORMALS; + } + if (mesh->mTangents && mesh->mBitangents) { + c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) { + break; + } + c |= ASSBIN_MESH_HAS_TEXCOORD(n); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) { + break; + } + c |= ASSBIN_MESH_HAS_COLOR(n); + } + chunk.Write(c); + + aiVector3D minVec, maxVec; + if (mesh->mVertices) { + if (shortened) { + chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); + } + if (mesh->mNormals) { + if (shortened) { + chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); + } + if (mesh->mTangents && mesh->mBitangents) { + if (shortened) { + chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); + chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); + chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) + break; + + if (shortened) { + chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) + break; + + // write number of UV components + chunk.Write(mesh->mNumUVComponents[n]); + + if (shortened) { + chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } + + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + unsigned int processed = 0; + for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { + + uint32_t hash = 0; + for (unsigned int a = 0; a < job;++a) { + + const aiFace& f = mesh->mFaces[processed+a]; + uint32_t tmp = f.mNumIndices; + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + for (unsigned int i = 0; i < f.mNumIndices; ++i) { + BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); + tmp = static_cast( f.mIndices[i] ); + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + } + } + chunk.Write(hash); + } + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + const aiFace& f = mesh->mFaces[i]; + + BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); + chunk.Write(f.mNumIndices); + + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) { + chunk.Write(f.mIndices[a]); + } + else chunk.Write(f.mIndices[a]); + } + } + } + + // write bones + if (mesh->mNumBones) { + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + const aiBone* b = mesh->mBones[a]; + WriteBinaryBone(&chunk,b); + } + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); + + chunk.Write(prop->mKey); + chunk.Write(prop->mSemantic); + chunk.Write(prop->mIndex); + + chunk.Write(prop->mDataLength); + chunk.Write((unsigned int)prop->mType); + chunk.Write(prop->mData,1,prop->mDataLength); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); + + chunk.Write(mat->mNumProperties); + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); + + chunk.Write(nd->mNodeName); + chunk.Write(nd->mNumPositionKeys); + chunk.Write(nd->mNumRotationKeys); + chunk.Write(nd->mNumScalingKeys); + chunk.Write(nd->mPreState); + chunk.Write(nd->mPostState); + + if (nd->mPositionKeys) { + if (shortened) { + chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + + } // else write as usual + else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } + if (nd->mRotationKeys) { + if (shortened) { + chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + + } // else write as usual + else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } + if (nd->mScalingKeys) { + if (shortened) { + chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + + } // else write as usual + else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } + } + + + // ----------------------------------------------------------------------------------- + void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); + + chunk.Write (anim->mName); + chunk.Write (anim->mDuration); + chunk.Write (anim->mTicksPerSecond); + chunk.Write(anim->mNumChannels); + + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + const aiNodeAnim* nd = anim->mChannels[a]; + WriteBinaryNodeAnim(&chunk,nd); + } + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryLight( IOStream * container, const aiLight* l ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); + + chunk.Write(l->mName); + chunk.Write(l->mType); + + if (l->mType != aiLightSource_DIRECTIONAL) { + chunk.Write(l->mAttenuationConstant); + chunk.Write(l->mAttenuationLinear); + chunk.Write(l->mAttenuationQuadratic); + } + + chunk.Write((const aiVector3D&)l->mColorDiffuse); + chunk.Write((const aiVector3D&)l->mColorSpecular); + chunk.Write((const aiVector3D&)l->mColorAmbient); + + if (l->mType == aiLightSource_SPOT) { + chunk.Write(l->mAngleInnerCone); + chunk.Write(l->mAngleOuterCone); + } + + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); + + chunk.Write(cam->mName); + chunk.Write(cam->mPosition); + chunk.Write(cam->mLookAt); + chunk.Write(cam->mUp); + chunk.Write(cam->mHorizontalFOV); + chunk.Write(cam->mClipPlaneNear); + chunk.Write(cam->mClipPlaneFar); + chunk.Write(cam->mAspect); + } + + // ----------------------------------------------------------------------------------- + void WriteBinaryScene( IOStream * container, const aiScene* scene) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); + + // basic scene information + chunk.Write(scene->mFlags); + chunk.Write(scene->mNumMeshes); + chunk.Write(scene->mNumMaterials); + chunk.Write(scene->mNumAnimations); + chunk.Write(scene->mNumTextures); + chunk.Write(scene->mNumLights); + chunk.Write(scene->mNumCameras); + + // write node graph + WriteBinaryNode( &chunk, scene->mRootNode ); + + // write all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + WriteBinaryMesh( &chunk,mesh); + } + + // write materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + WriteBinaryMaterial(&chunk,mat); + } + + // write all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + WriteBinaryAnim(&chunk,anim); + } + + + // write all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + WriteBinaryTexture(&chunk,mesh); + } + + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + WriteBinaryLight(&chunk,l); + } + + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + WriteBinaryCamera(&chunk,cam); + } + + } + + public: + AssbinExport() + { + shortened = false; + compressed = false; + } + + // ----------------------------------------------------------------------------------- + // Write a binary model dump + void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) + { + IOStream * out = pIOSystem->Open( pFile, "wb" ); + if (!out) return; + + time_t tt = time(NULL); + tm* p = gmtime(&tt); + + // header + char s[64]; + memset( s, 0, 64 ); +#if _MSC_VER >= 1400 + sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); +#else + snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); +#endif + out->Write( s, 44, 1 ); + // == 44 bytes + + Write( out, ASSBIN_VERSION_MAJOR ); + Write( out, ASSBIN_VERSION_MINOR ); + Write( out, aiGetVersionRevision() ); + Write( out, aiGetCompileFlags() ); + Write( out, shortened ); + Write( out, compressed ); + // == 20 bytes + + //todo + + char buff[256]; + strncpy(buff,pFile,256); + out->Write(buff,sizeof(char),256); + + char cmd[] = "\0"; + strncpy(buff,cmd,128); + out->Write(buff,sizeof(char),128); + + // leave 64 bytes free for future extensions + memset(buff,0xcd,64); + out->Write(buff,sizeof(char),64); + // == 435 bytes + + // ==== total header size: 512 bytes + ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); + + // Up to here the data is uncompressed. For compressed files, the rest + // is compressed using standard DEFLATE from zlib. + WriteBinaryScene( out, pScene ); + + pIOSystem->Close( out ); + } + }; + void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) { + AssbinExport exporter; + exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); } } // end of namespace Assimp From fc9b4e2adf025d17bd9695f812d010b77be8e194 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 22:55:20 +0200 Subject: [PATCH 10/34] follow assimp code style (tabs) --- code/AssbinExporter.cpp | 1166 +++++++++++++++++++-------------------- 1 file changed, 583 insertions(+), 583 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index b3dfd082e..27da1a303 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -10,18 +10,18 @@ with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. + copyright notice, this list of conditions and the + following disclaimer. * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. * Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -50,695 +50,695 @@ using namespace Assimp; namespace Assimp { - class AssbinChunkWriter : public IOStream - { - private: + class AssbinChunkWriter : public IOStream + { + private: - uint8_t* buffer; - uint32_t magic; - IOStream * container; - uint32_t cur_size, cursor, initial; + uint8_t* buffer; + uint32_t magic; + IOStream * container; + uint32_t cur_size, cursor, initial; - private: - // ------------------------------------------------------------------- - void Grow(size_t need = 0) - { - size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); + private: + // ------------------------------------------------------------------- + void Grow(size_t need = 0) + { + size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); - const uint8_t* const old = buffer; - buffer = new uint8_t[new_size]; + const uint8_t* const old = buffer; + buffer = new uint8_t[new_size]; - if (old) { - memcpy(buffer,old,cur_size); - delete[] old; - } + if (old) { + memcpy(buffer,old,cur_size); + delete[] old; + } - cur_size = new_size; - } + cur_size = new_size; + } - public: + public: - AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) - : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) - { - } + AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) + : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) + { + } - virtual ~AssbinChunkWriter() - { - if (container) { - container->Write( &magic, sizeof(uint32_t), 1 ); - container->Write( &cursor, sizeof(uint32_t), 1 ); - container->Write( buffer, 1, cursor ); - } - if (buffer) delete[] buffer; - } + virtual ~AssbinChunkWriter() + { + if (container) { + container->Write( &magic, sizeof(uint32_t), 1 ); + container->Write( &cursor, sizeof(uint32_t), 1 ); + container->Write( buffer, 1, cursor ); + } + if (buffer) delete[] buffer; + } - // ------------------------------------------------------------------- - virtual size_t Read(void* pvBuffer, - size_t pSize, - size_t pCount) { return 0; }; - virtual aiReturn Seek(size_t pOffset, - aiOrigin pOrigin) { return aiReturn_FAILURE; }; - virtual size_t Tell() const { return 0; }; - virtual void Flush() { }; + // ------------------------------------------------------------------- + virtual size_t Read(void* pvBuffer, + size_t pSize, + size_t pCount) { return 0; }; + virtual aiReturn Seek(size_t pOffset, + aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Tell() const { return 0; }; + virtual void Flush() { }; - virtual size_t FileSize() const - { - return cursor; - } + virtual size_t FileSize() const + { + return cursor; + } - // ------------------------------------------------------------------- - virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) - { - pSize *= pCount; - if (cursor + pSize > cur_size) { - Grow(cursor + pSize); - } + // ------------------------------------------------------------------- + virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount) + { + pSize *= pCount; + if (cursor + pSize > cur_size) { + Grow(cursor + pSize); + } - memcpy(buffer+cursor, pvBuffer, pSize); - cursor += pSize; + memcpy(buffer+cursor, pvBuffer, pSize); + cursor += pSize; - return pCount; - } + return pCount; + } - template - size_t Write(const T& v) - { - return Write( &v, sizeof(T), 1 ); - } + template + size_t Write(const T& v) + { + return Write( &v, sizeof(T), 1 ); + } - // ----------------------------------------------------------------------------------- - // Serialize an aiString - template <> - inline uint32_t Write(const aiString& s) - { - const uint32_t s2 = (uint32_t)s.length; - Write(&s,4,1); - Write(s.data,s2,1); - return s2+4; - } + // ----------------------------------------------------------------------------------- + // Serialize an aiString + template <> + inline uint32_t Write(const aiString& s) + { + const uint32_t s2 = (uint32_t)s.length; + Write(&s,4,1); + Write(s.data,s2,1); + return s2+4; + } - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint32_t - template <> - inline uint32_t Write(const unsigned int& w) - { - const uint32_t t = (uint32_t)w; - if (w > t) { - // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - printf("loss of data due to 64 -> 32 bit integer conversion"); - } + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint32_t + template <> + inline uint32_t Write(const unsigned int& w) + { + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + printf("loss of data due to 64 -> 32 bit integer conversion"); + } - Write(&t,4,1); - return 4; - } + Write(&t,4,1); + return 4; + } - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint16_t - template <> - inline uint32_t Write(const uint16_t& w) - { - Write(&w,2,1); - return 2; - } + // ----------------------------------------------------------------------------------- + // Serialize an unsigned int as uint16_t + template <> + inline uint32_t Write(const uint16_t& w) + { + Write(&w,2,1); + return 2; + } - // ----------------------------------------------------------------------------------- - // Serialize a float - template <> - inline uint32_t Write(const float& f) - { - BOOST_STATIC_ASSERT(sizeof(float)==4); - Write(&f,4,1); - return 4; - } + // ----------------------------------------------------------------------------------- + // Serialize a float + template <> + inline uint32_t Write(const float& f) + { + BOOST_STATIC_ASSERT(sizeof(float)==4); + Write(&f,4,1); + return 4; + } - // ----------------------------------------------------------------------------------- - // Serialize a double - template <> - inline uint32_t Write(const double& f) - { - BOOST_STATIC_ASSERT(sizeof(double)==8); - Write(&f,8,1); - return 8; - } + // ----------------------------------------------------------------------------------- + // Serialize a double + template <> + inline uint32_t Write(const double& f) + { + BOOST_STATIC_ASSERT(sizeof(double)==8); + Write(&f,8,1); + return 8; + } - // ----------------------------------------------------------------------------------- - // Serialize a vec3 - template <> - inline uint32_t Write(const aiVector3D& v) - { - uint32_t t = Write(v.x); - t += Write(v.y); - t += Write(v.z); - return t; - } + // ----------------------------------------------------------------------------------- + // Serialize a vec3 + template <> + inline uint32_t Write(const aiVector3D& v) + { + uint32_t t = Write(v.x); + t += Write(v.y); + t += Write(v.z); + return t; + } - // ----------------------------------------------------------------------------------- - // Serialize a color value - template <> - inline uint32_t Write(const aiColor4D& v) - { - uint32_t t = Write(v.r); - t += Write(v.g); - t += Write(v.b); - t += Write(v.a); - return t; - } + // ----------------------------------------------------------------------------------- + // Serialize a color value + template <> + inline uint32_t Write(const aiColor4D& v) + { + uint32_t t = Write(v.r); + t += Write(v.g); + t += Write(v.b); + t += Write(v.a); + return t; + } - // ----------------------------------------------------------------------------------- - // Serialize a quaternion - template <> - inline uint32_t Write(const aiQuaternion& v) - { - uint32_t t = Write(v.w); - t += Write(v.x); - t += Write(v.y); - t += Write(v.z); - return 16; - } + // ----------------------------------------------------------------------------------- + // Serialize a quaternion + template <> + inline uint32_t Write(const aiQuaternion& v) + { + uint32_t t = Write(v.w); + t += Write(v.x); + t += Write(v.y); + t += Write(v.z); + return 16; + } - // ----------------------------------------------------------------------------------- - // Serialize a vertex weight - template <> - inline uint32_t Write(const aiVertexWeight& v) - { - uint32_t t = Write(v.mVertexId); - return t+Write(v.mWeight); - } + // ----------------------------------------------------------------------------------- + // Serialize a vertex weight + template <> + inline uint32_t Write(const aiVertexWeight& v) + { + uint32_t t = Write(v.mVertexId); + return t+Write(v.mWeight); + } - // ----------------------------------------------------------------------------------- - // Serialize a mat4x4 - template <> - inline uint32_t Write(const aiMatrix4x4& m) - { - for (unsigned int i = 0; i < 4;++i) { - for (unsigned int i2 = 0; i2 < 4;++i2) { - Write(m[i][i2]); - } - } - return 64; - } + // ----------------------------------------------------------------------------------- + // Serialize a mat4x4 + template <> + inline uint32_t Write(const aiMatrix4x4& m) + { + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write(m[i][i2]); + } + } + return 64; + } - // ----------------------------------------------------------------------------------- - // Serialize an aiVectorKey - template <> - inline uint32_t Write(const aiVectorKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } + // ----------------------------------------------------------------------------------- + // Serialize an aiVectorKey + template <> + inline uint32_t Write(const aiVectorKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } - // ----------------------------------------------------------------------------------- - // Serialize an aiQuatKey - template <> - inline uint32_t Write(const aiQuatKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } + // ----------------------------------------------------------------------------------- + // Serialize an aiQuatKey + template <> + inline uint32_t Write(const aiQuatKey& v) + { + const uint32_t t = Write(v.mTime); + return t + Write(v.mValue); + } - template - inline uint32_t WriteBounds(const T* in, unsigned int size) - { - T minc,maxc; - ArrayBounds(in,size,minc,maxc); + template + inline uint32_t WriteBounds(const T* in, unsigned int size) + { + T minc,maxc; + ArrayBounds(in,size,minc,maxc); - const uint32_t t = Write(minc); - return t + Write(maxc); - } + const uint32_t t = Write(minc); + return t + Write(maxc); + } - }; + }; /* - class AssbinChunkWriter - { - AssbinStream stream; - uint32_t magic; - public: - AssbinChunkWriter( uint32_t _magic ) - { - magic = _magic; - } - void AppendToStream( AssbinStream & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.Write( &magic, sizeof(uint32_t), 1 ); - _stream.Write( &s, sizeof(uint32_t), 1 ); - _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); - } - void AppendToStream( AssbinChunkWriter & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.WriteRaw( &magic, sizeof(uint32_t) ); - _stream.WriteRaw( &s, sizeof(uint32_t) ); - _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); - } + class AssbinChunkWriter + { + AssbinStream stream; + uint32_t magic; + public: + AssbinChunkWriter( uint32_t _magic ) + { + magic = _magic; + } + void AppendToStream( AssbinStream & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.Write( &magic, sizeof(uint32_t), 1 ); + _stream.Write( &s, sizeof(uint32_t), 1 ); + _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); + } + void AppendToStream( AssbinChunkWriter & _stream ) + { + uint32_t s = stream.FileSize(); + _stream.WriteRaw( &magic, sizeof(uint32_t) ); + _stream.WriteRaw( &s, sizeof(uint32_t) ); + _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); + } - }; + }; */ - class AssbinExport - { - private: - bool shortened; - bool compressed; - //AssbinStream stream; + class AssbinExport + { + private: + bool shortened; + bool compressed; + //AssbinStream stream; - protected: - template - size_t Write( IOStream * container, const T& v) - { - return container->Write( &v, sizeof(T), 1 ); - } + protected: + template + size_t Write( IOStream * container, const T& v) + { + return container->Write( &v, sizeof(T), 1 ); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryNode( IOStream * container, const aiNode* node) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryNode( IOStream * container, const aiNode* node) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); - chunk.Write(node->mName); - chunk.Write(node->mTransformation); - chunk.Write(node->mNumChildren); - chunk.Write(node->mNumMeshes); + chunk.Write(node->mName); + chunk.Write(node->mTransformation); + chunk.Write(node->mNumChildren); + chunk.Write(node->mNumMeshes); - for (unsigned int i = 0; i < node->mNumMeshes;++i) { - chunk.Write(node->mMeshes[i]); - } + for (unsigned int i = 0; i < node->mNumMeshes;++i) { + chunk.Write(node->mMeshes[i]); + } - for (unsigned int i = 0; i < node->mNumChildren;++i) { - WriteBinaryNode( &chunk, node->mChildren[i] ); - } - } + for (unsigned int i = 0; i < node->mNumChildren;++i) { + WriteBinaryNode( &chunk, node->mChildren[i] ); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryTexture(IOStream * container, const aiTexture* tex) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryTexture(IOStream * container, const aiTexture* tex) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); - chunk.Write(tex->mWidth); - chunk.Write(tex->mHeight); - chunk.Write( tex->achFormatHint, sizeof(char), 4 ); + chunk.Write(tex->mWidth); + chunk.Write(tex->mHeight); + chunk.Write( tex->achFormatHint, sizeof(char), 4 ); - if(!shortened) { - if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); - } - else { - chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); - } - } + if(!shortened) { + if (!tex->mHeight) { + chunk.Write(tex->pcData,1,tex->mWidth); + } + else { + chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); + } + } - } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryBone(IOStream * container, const aiBone* b) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryBone(IOStream * container, const aiBone* b) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); - chunk.Write(b->mName); - chunk.Write(b->mNumWeights); - chunk.Write(b->mOffsetMatrix); + chunk.Write(b->mName); + chunk.Write(b->mNumWeights); + chunk.Write(b->mOffsetMatrix); - // for the moment we write dumb min/max values for the bones, too. - // maybe I'll add a better, hash-like solution later - if (shortened) { - chunk.WriteBounds(b->mWeights,b->mNumWeights); - } // else write as usual - else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); - } + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) { + chunk.WriteBounds(b->mWeights,b->mNumWeights); + } // else write as usual + else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); + // ----------------------------------------------------------------------------------- + void WriteBinaryMesh(IOStream * container, const aiMesh* mesh) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); - chunk.Write(mesh->mPrimitiveTypes); - chunk.Write(mesh->mNumVertices); - chunk.Write(mesh->mNumFaces); - chunk.Write(mesh->mNumBones); - chunk.Write(mesh->mMaterialIndex); + chunk.Write(mesh->mPrimitiveTypes); + chunk.Write(mesh->mNumVertices); + chunk.Write(mesh->mNumFaces); + chunk.Write(mesh->mNumBones); + chunk.Write(mesh->mMaterialIndex); - // first of all, write bits for all existent vertex components - unsigned int c = 0; - if (mesh->mVertices) { - c |= ASSBIN_MESH_HAS_POSITIONS; - } - if (mesh->mNormals) { - c |= ASSBIN_MESH_HAS_NORMALS; - } - if (mesh->mTangents && mesh->mBitangents) { - c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (!mesh->mTextureCoords[n]) { - break; - } - c |= ASSBIN_MESH_HAS_TEXCOORD(n); - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { - if (!mesh->mColors[n]) { - break; - } - c |= ASSBIN_MESH_HAS_COLOR(n); - } - chunk.Write(c); + // first of all, write bits for all existent vertex components + unsigned int c = 0; + if (mesh->mVertices) { + c |= ASSBIN_MESH_HAS_POSITIONS; + } + if (mesh->mNormals) { + c |= ASSBIN_MESH_HAS_NORMALS; + } + if (mesh->mTangents && mesh->mBitangents) { + c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) { + break; + } + c |= ASSBIN_MESH_HAS_TEXCOORD(n); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) { + break; + } + c |= ASSBIN_MESH_HAS_COLOR(n); + } + chunk.Write(c); - aiVector3D minVec, maxVec; - if (mesh->mVertices) { - if (shortened) { - chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); - } - if (mesh->mNormals) { - if (shortened) { - chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); - } - if (mesh->mTangents && mesh->mBitangents) { - if (shortened) { - chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); - chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); - } // else write as usual - else { - chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); - chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); - } - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { - if (!mesh->mColors[n]) - break; + aiVector3D minVec, maxVec; + if (mesh->mVertices) { + if (shortened) { + chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); + } + if (mesh->mNormals) { + if (shortened) { + chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); + } + if (mesh->mTangents && mesh->mBitangents) { + if (shortened) { + chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); + chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); + chunk.Write(mesh->mBitangents,1,12*mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) + break; - if (shortened) { - chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); - } - for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { - if (!mesh->mTextureCoords[n]) - break; + if (shortened) { + chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) + break; - // write number of UV components - chunk.Write(mesh->mNumUVComponents[n]); + // write number of UV components + chunk.Write(mesh->mNumUVComponents[n]); - if (shortened) { - chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); - } // else write as usual - else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); - } + if (shortened) { + chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } - // write faces. There are no floating-point calculations involved - // in these, so we can write a simple hash over the face data - // to the dump file. We generate a single 32 Bit hash for 512 faces - // using Assimp's standard hashing function. - if (shortened) { - unsigned int processed = 0; - for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + unsigned int processed = 0; + for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { - uint32_t hash = 0; - for (unsigned int a = 0; a < job;++a) { + uint32_t hash = 0; + for (unsigned int a = 0; a < job;++a) { - const aiFace& f = mesh->mFaces[processed+a]; - uint32_t tmp = f.mNumIndices; - hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); - for (unsigned int i = 0; i < f.mNumIndices; ++i) { - BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); - tmp = static_cast( f.mIndices[i] ); - hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); - } - } - chunk.Write(hash); - } - } - else // else write as usual - { - // if there are less than 2^16 vertices, we can simply use 16 bit integers ... - for (unsigned int i = 0; i < mesh->mNumFaces;++i) { - const aiFace& f = mesh->mFaces[i]; + const aiFace& f = mesh->mFaces[processed+a]; + uint32_t tmp = f.mNumIndices; + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + for (unsigned int i = 0; i < f.mNumIndices; ++i) { + BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff); + tmp = static_cast( f.mIndices[i] ); + hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); + } + } + chunk.Write(hash); + } + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + const aiFace& f = mesh->mFaces[i]; - BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); - chunk.Write(f.mNumIndices); + BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); + chunk.Write(f.mNumIndices); - for (unsigned int a = 0; a < f.mNumIndices;++a) { - if (mesh->mNumVertices < (1u<<16)) { - chunk.Write(f.mIndices[a]); - } - else chunk.Write(f.mIndices[a]); - } - } - } + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) { + chunk.Write(f.mIndices[a]); + } + else chunk.Write(f.mIndices[a]); + } + } + } - // write bones - if (mesh->mNumBones) { - for (unsigned int a = 0; a < mesh->mNumBones;++a) { - const aiBone* b = mesh->mBones[a]; - WriteBinaryBone(&chunk,b); - } - } - } + // write bones + if (mesh->mNumBones) { + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + const aiBone* b = mesh->mBones[a]; + WriteBinaryBone(&chunk,b); + } + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); - chunk.Write(prop->mKey); - chunk.Write(prop->mSemantic); - chunk.Write(prop->mIndex); + chunk.Write(prop->mKey); + chunk.Write(prop->mSemantic); + chunk.Write(prop->mIndex); - chunk.Write(prop->mDataLength); - chunk.Write((unsigned int)prop->mType); - chunk.Write(prop->mData,1,prop->mDataLength); - } + chunk.Write(prop->mDataLength); + chunk.Write((unsigned int)prop->mType); + chunk.Write(prop->mData,1,prop->mDataLength); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); + // ----------------------------------------------------------------------------------- + void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); - chunk.Write(mat->mNumProperties); - for (unsigned int i = 0; i < mat->mNumProperties;++i) { - WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); - } - } + chunk.Write(mat->mNumProperties); + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); + // ----------------------------------------------------------------------------------- + void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); - chunk.Write(nd->mNodeName); - chunk.Write(nd->mNumPositionKeys); - chunk.Write(nd->mNumRotationKeys); - chunk.Write(nd->mNumScalingKeys); - chunk.Write(nd->mPreState); - chunk.Write(nd->mPostState); + chunk.Write(nd->mNodeName); + chunk.Write(nd->mNumPositionKeys); + chunk.Write(nd->mNumRotationKeys); + chunk.Write(nd->mNumScalingKeys); + chunk.Write(nd->mPreState); + chunk.Write(nd->mPostState); - if (nd->mPositionKeys) { - if (shortened) { - chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + if (nd->mPositionKeys) { + if (shortened) { + chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); - } // else write as usual - else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); - } - if (nd->mRotationKeys) { - if (shortened) { - chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + } // else write as usual + else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } + if (nd->mRotationKeys) { + if (shortened) { + chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); - } // else write as usual - else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); - } - if (nd->mScalingKeys) { - if (shortened) { - chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + } // else write as usual + else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } + if (nd->mScalingKeys) { + if (shortened) { + chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); - } // else write as usual - else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); - } - } + } // else write as usual + else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); + // ----------------------------------------------------------------------------------- + void WriteBinaryAnim( IOStream * container, const aiAnimation* anim ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); - chunk.Write (anim->mName); - chunk.Write (anim->mDuration); - chunk.Write (anim->mTicksPerSecond); - chunk.Write(anim->mNumChannels); + chunk.Write (anim->mName); + chunk.Write (anim->mDuration); + chunk.Write (anim->mTicksPerSecond); + chunk.Write(anim->mNumChannels); - for (unsigned int a = 0; a < anim->mNumChannels;++a) { - const aiNodeAnim* nd = anim->mChannels[a]; - WriteBinaryNodeAnim(&chunk,nd); - } - } + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + const aiNodeAnim* nd = anim->mChannels[a]; + WriteBinaryNodeAnim(&chunk,nd); + } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryLight( IOStream * container, const aiLight* l ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); + // ----------------------------------------------------------------------------------- + void WriteBinaryLight( IOStream * container, const aiLight* l ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); - chunk.Write(l->mName); - chunk.Write(l->mType); + chunk.Write(l->mName); + chunk.Write(l->mType); - if (l->mType != aiLightSource_DIRECTIONAL) { - chunk.Write(l->mAttenuationConstant); - chunk.Write(l->mAttenuationLinear); - chunk.Write(l->mAttenuationQuadratic); - } + if (l->mType != aiLightSource_DIRECTIONAL) { + chunk.Write(l->mAttenuationConstant); + chunk.Write(l->mAttenuationLinear); + chunk.Write(l->mAttenuationQuadratic); + } - chunk.Write((const aiVector3D&)l->mColorDiffuse); - chunk.Write((const aiVector3D&)l->mColorSpecular); - chunk.Write((const aiVector3D&)l->mColorAmbient); + chunk.Write((const aiVector3D&)l->mColorDiffuse); + chunk.Write((const aiVector3D&)l->mColorSpecular); + chunk.Write((const aiVector3D&)l->mColorAmbient); - if (l->mType == aiLightSource_SPOT) { - chunk.Write(l->mAngleInnerCone); - chunk.Write(l->mAngleOuterCone); - } + if (l->mType == aiLightSource_SPOT) { + chunk.Write(l->mAngleInnerCone); + chunk.Write(l->mAngleOuterCone); + } - } + } - // ----------------------------------------------------------------------------------- - void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); + // ----------------------------------------------------------------------------------- + void WriteBinaryCamera( IOStream * container, const aiCamera* cam ) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); - chunk.Write(cam->mName); - chunk.Write(cam->mPosition); - chunk.Write(cam->mLookAt); - chunk.Write(cam->mUp); - chunk.Write(cam->mHorizontalFOV); - chunk.Write(cam->mClipPlaneNear); - chunk.Write(cam->mClipPlaneFar); - chunk.Write(cam->mAspect); - } + chunk.Write(cam->mName); + chunk.Write(cam->mPosition); + chunk.Write(cam->mLookAt); + chunk.Write(cam->mUp); + chunk.Write(cam->mHorizontalFOV); + chunk.Write(cam->mClipPlaneNear); + chunk.Write(cam->mClipPlaneFar); + chunk.Write(cam->mAspect); + } - // ----------------------------------------------------------------------------------- - void WriteBinaryScene( IOStream * container, const aiScene* scene) - { - AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); + // ----------------------------------------------------------------------------------- + void WriteBinaryScene( IOStream * container, const aiScene* scene) + { + AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); - // basic scene information - chunk.Write(scene->mFlags); - chunk.Write(scene->mNumMeshes); - chunk.Write(scene->mNumMaterials); - chunk.Write(scene->mNumAnimations); - chunk.Write(scene->mNumTextures); - chunk.Write(scene->mNumLights); - chunk.Write(scene->mNumCameras); + // basic scene information + chunk.Write(scene->mFlags); + chunk.Write(scene->mNumMeshes); + chunk.Write(scene->mNumMaterials); + chunk.Write(scene->mNumAnimations); + chunk.Write(scene->mNumTextures); + chunk.Write(scene->mNumLights); + chunk.Write(scene->mNumCameras); - // write node graph - WriteBinaryNode( &chunk, scene->mRootNode ); + // write node graph + WriteBinaryNode( &chunk, scene->mRootNode ); - // write all meshes - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - const aiMesh* mesh = scene->mMeshes[i]; - WriteBinaryMesh( &chunk,mesh); - } + // write all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + WriteBinaryMesh( &chunk,mesh); + } - // write materials - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - const aiMaterial* mat = scene->mMaterials[i]; - WriteBinaryMaterial(&chunk,mat); - } + // write materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + WriteBinaryMaterial(&chunk,mat); + } - // write all animations - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - const aiAnimation* anim = scene->mAnimations[i]; - WriteBinaryAnim(&chunk,anim); - } + // write all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + WriteBinaryAnim(&chunk,anim); + } - // write all textures - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - const aiTexture* mesh = scene->mTextures[i]; - WriteBinaryTexture(&chunk,mesh); - } + // write all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + WriteBinaryTexture(&chunk,mesh); + } - // write lights - for (unsigned int i = 0; i < scene->mNumLights;++i) { - const aiLight* l = scene->mLights[i]; - WriteBinaryLight(&chunk,l); - } + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + WriteBinaryLight(&chunk,l); + } - // write cameras - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - const aiCamera* cam = scene->mCameras[i]; - WriteBinaryCamera(&chunk,cam); - } + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + WriteBinaryCamera(&chunk,cam); + } - } + } - public: - AssbinExport() - { - shortened = false; - compressed = false; - } + public: + AssbinExport() + { + shortened = false; + compressed = false; + } - // ----------------------------------------------------------------------------------- - // Write a binary model dump - void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) - { - IOStream * out = pIOSystem->Open( pFile, "wb" ); - if (!out) return; + // ----------------------------------------------------------------------------------- + // Write a binary model dump + void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) + { + IOStream * out = pIOSystem->Open( pFile, "wb" ); + if (!out) return; - time_t tt = time(NULL); - tm* p = gmtime(&tt); + time_t tt = time(NULL); + tm* p = gmtime(&tt); - // header - char s[64]; - memset( s, 0, 64 ); + // header + char s[64]; + memset( s, 0, 64 ); #if _MSC_VER >= 1400 - sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); + sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p)); #else - snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); + snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p)); #endif - out->Write( s, 44, 1 ); - // == 44 bytes + out->Write( s, 44, 1 ); + // == 44 bytes - Write( out, ASSBIN_VERSION_MAJOR ); - Write( out, ASSBIN_VERSION_MINOR ); - Write( out, aiGetVersionRevision() ); - Write( out, aiGetCompileFlags() ); - Write( out, shortened ); - Write( out, compressed ); - // == 20 bytes + Write( out, ASSBIN_VERSION_MAJOR ); + Write( out, ASSBIN_VERSION_MINOR ); + Write( out, aiGetVersionRevision() ); + Write( out, aiGetCompileFlags() ); + Write( out, shortened ); + Write( out, compressed ); + // == 20 bytes - //todo + //todo - char buff[256]; - strncpy(buff,pFile,256); - out->Write(buff,sizeof(char),256); + char buff[256]; + strncpy(buff,pFile,256); + out->Write(buff,sizeof(char),256); - char cmd[] = "\0"; - strncpy(buff,cmd,128); - out->Write(buff,sizeof(char),128); + char cmd[] = "\0"; + strncpy(buff,cmd,128); + out->Write(buff,sizeof(char),128); - // leave 64 bytes free for future extensions - memset(buff,0xcd,64); - out->Write(buff,sizeof(char),64); - // == 435 bytes + // leave 64 bytes free for future extensions + memset(buff,0xcd,64); + out->Write(buff,sizeof(char),64); + // == 435 bytes - // ==== total header size: 512 bytes - ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); + // ==== total header size: 512 bytes + ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH ); - // Up to here the data is uncompressed. For compressed files, the rest - // is compressed using standard DEFLATE from zlib. - WriteBinaryScene( out, pScene ); + // Up to here the data is uncompressed. For compressed files, the rest + // is compressed using standard DEFLATE from zlib. + WriteBinaryScene( out, pScene ); - pIOSystem->Close( out ); - } - }; + pIOSystem->Close( out ); + } + }; void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene) { - AssbinExport exporter; - exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); + AssbinExport exporter; + exporter.WriteBinaryDump( pFile, pIOSystem, pScene ); } } // end of namespace Assimp From cd86818888703063f3a85b659793ec479c16b86c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 5 Aug 2014 23:18:45 +0200 Subject: [PATCH 11/34] - add compression support - remove unneeded code - change log warning to exception - document --- code/AssbinExporter.cpp | 109 ++++++++++++++++++++++------------------ code/AssbinExporter.h | 4 +- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 27da1a303..2f1c403e9 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -10,18 +10,18 @@ with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. + copyright notice, this list of conditions and the + following disclaimer. * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. * Neither the name of the assimp team, nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission of the assimp team. + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT @@ -37,12 +37,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ - +/** @file AssbinExporter.cpp + * ASSBIN exporter main code + */ #include "AssimpPCH.h" #include "assbin_chunks.h" #include "./../include/assimp/version.h" #include "ProcessHelper.h" +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +#else +# include "../contrib/zlib/zlib.h" +#endif + #ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER @@ -50,6 +58,16 @@ using namespace Assimp; namespace Assimp { + // ---------------------------------------------------------------------------------- + /** @class AssbinChunkWriter + * @brief Chunk writer mechanism for the .assbin file structure + * + * This is a standard in-memory IOStream (most of the code is based on BlobIOStream), + * the difference being that this takes another IOStream as a "container" in the + * constructor, and when it is destroyed, it appends the magic number, the chunk size, + * and the chunk contents to the container stream. This allows relatively easy chunk + * chunk construction, even recursively. + */ class AssbinChunkWriter : public IOStream { private: @@ -93,13 +111,12 @@ namespace Assimp { if (buffer) delete[] buffer; } + void * GetBufferPointer() { return buffer; }; + // ------------------------------------------------------------------- - virtual size_t Read(void* pvBuffer, - size_t pSize, - size_t pCount) { return 0; }; - virtual aiReturn Seek(size_t pOffset, - aiOrigin pOrigin) { return aiReturn_FAILURE; }; - virtual size_t Tell() const { return 0; }; + virtual size_t Read(void* pvBuffer, size_t pSize, size_t pCount) { return 0; }; + virtual aiReturn Seek(size_t pOffset, aiOrigin pOrigin) { return aiReturn_FAILURE; }; + virtual size_t Tell() const { return cursor; }; virtual void Flush() { }; virtual size_t FileSize() const @@ -127,6 +144,7 @@ namespace Assimp { return Write( &v, sizeof(T), 1 ); } + // ----------------------------------------------------------------------------------- // Serialize an aiString template <> @@ -146,7 +164,7 @@ namespace Assimp { const uint32_t t = (uint32_t)w; if (w > t) { // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - printf("loss of data due to 64 -> 32 bit integer conversion"); + throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); } Write(&t,4,1); @@ -268,43 +286,19 @@ namespace Assimp { return t + Write(maxc); } - }; -/* - class AssbinChunkWriter - { - AssbinStream stream; - uint32_t magic; - public: - AssbinChunkWriter( uint32_t _magic ) - { - magic = _magic; - } - void AppendToStream( AssbinStream & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.Write( &magic, sizeof(uint32_t), 1 ); - _stream.Write( &s, sizeof(uint32_t), 1 ); - _stream.Write( stream.GetBuffer(), stream.FileSize(), 1 ); - } - void AppendToStream( AssbinChunkWriter & _stream ) - { - uint32_t s = stream.FileSize(); - _stream.WriteRaw( &magic, sizeof(uint32_t) ); - _stream.WriteRaw( &s, sizeof(uint32_t) ); - _stream.WriteRaw( stream.GetBuffer(), stream.FileSize() ); - } - - }; -*/ - + // ---------------------------------------------------------------------------------- + /** @class AssbinExport + * @brief Assbin exporter class + * + * This class performs the .assbin exporting, and is responsible for the file layout. + */ class AssbinExport { private: bool shortened; bool compressed; - //AssbinStream stream; protected: template @@ -709,8 +703,6 @@ namespace Assimp { Write( out, compressed ); // == 20 bytes - //todo - char buff[256]; strncpy(buff,pFile,256); out->Write(buff,sizeof(char),256); @@ -729,7 +721,26 @@ namespace Assimp { // Up to here the data is uncompressed. For compressed files, the rest // is compressed using standard DEFLATE from zlib. - WriteBinaryScene( out, pScene ); + if (compressed) + { + AssbinChunkWriter uncompressedStream( NULL, NULL ); + WriteBinaryScene( &uncompressedStream, pScene ); + + uLongf uncompressedSize = uncompressedStream.Tell(); + uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.); + uint8_t* compressedBuffer = new uint8_t[ compressedSize ]; + + compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); + + out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); + out->Write( compressedBuffer, sizeof(char), compressedSize ); + + delete[] compressedBuffer; + } + else + { + WriteBinaryScene( out, pScene ); + } pIOSystem->Close( out ); } diff --git a/code/AssbinExporter.h b/code/AssbinExporter.h index f6a0cf598..34ccda3e1 100644 --- a/code/AssbinExporter.h +++ b/code/AssbinExporter.h @@ -44,8 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef AI_ASSBINEXPORTER_H_INC #define AI_ASSBINEXPORTER_H_INC -#include - -#include "StreamWriter.h" +// nothing really needed here - reserved for future use like properties #endif From 0f822d38cd5aa01bccfcaef50c24ef59fd66df48 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 00:39:54 +0200 Subject: [PATCH 12/34] add basic framework for importer --- code/AssbinLoader.cpp | 71 ++++++++++++++++++++++++++++++++++++ code/AssbinLoader.h | 77 +++++++++++++++++++++++++++++++++++++++ code/ImporterRegistry.cpp | 8 +++- 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 code/AssbinLoader.cpp create mode 100644 code/AssbinLoader.h diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp new file mode 100644 index 000000000..336061326 --- /dev/null +++ b/code/AssbinLoader.cpp @@ -0,0 +1,71 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file AssbinLoader.cpp + * @brief Implementation of the .assbin importer class + * + * see assbin_chunks.h + */ + +#include "AssimpPCH.h" +#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER + +// internal headers +#include "AssbinLoader.h" + +using namespace Assimp; + +bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +{ + return false; +} + +const aiImporterDesc* Assimp::AssbinImporter::GetInfo() const +{ + return NULL; +} + +void Assimp::AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) +{ + +} + +#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h new file mode 100644 index 000000000..c3f6a5873 --- /dev/null +++ b/code/AssbinLoader.h @@ -0,0 +1,77 @@ + +/* +Open Asset Import Library (assimp) +---------------------------------------------------------------------- + +Copyright (c) 2006-2012, assimp team +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the +following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- +*/ + +/** @file AssbinLoader.h + * @brief .assbin File format loader + */ +#ifndef AI_ASSBINIMPORTER_H_INC +#define AI_ASSBINIMPORTER_H_INC + +#include "BaseImporter.h" +#include "../include/assimp/types.h" + +#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER + +namespace Assimp { + +// --------------------------------------------------------------------------------- +/** Importer class for 3D Studio r3 and r4 3DS files + */ +class AssbinImporter : public BaseImporter +{ + virtual bool CanRead( + const std::string& pFile, + IOSystem* pIOHandler, + bool checkSig + ) const; + virtual const aiImporterDesc* GetInfo() const; + virtual void InternReadFile( + const std::string& pFile, + aiScene* pScene, + IOSystem* pIOHandler + ); +}; + +} // end of namespace Assimp + +#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER + +#endif // AI_ASSBINIMPORTER_H_INC diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index e301804e2..8499aaeaa 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -166,6 +166,9 @@ corresponding preprocessor flag to selectively disable formats. #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER # include "FBXImporter.h" #endif +#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER +# include "AssbinLoader.h" +#endif namespace Assimp { @@ -289,7 +292,10 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) out.push_back( new XGLImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) - out.push_back( new FBXImporter() ); + out.push_back( new FBXImporter() ); +#endif +#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER ) + out.push_back( new AssbinImporter() ); #endif } From 9cdecc780bbaf665c785f8239d912d3713bac14c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 00:44:30 +0200 Subject: [PATCH 13/34] Fix wrong nesting Otherwise doesn't compile if ASSIMP_BUILD_NO_3DS_IMPORTER is defined because the #endif is inside the namespace block --- code/3DSLoader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/3DSLoader.h b/code/3DSLoader.h index 5e80195f5..2b1dd26f8 100644 --- a/code/3DSLoader.h +++ b/code/3DSLoader.h @@ -273,8 +273,8 @@ protected: bool bIsPrj; }; -#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER - } // end of namespace Assimp +#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER + #endif // AI_3DSIMPORTER_H_INC From 5b512dd9ddcd163163c2af6341df3bdea33ee860 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 00:52:05 +0200 Subject: [PATCH 14/34] add info + header check --- code/AssbinLoader.cpp | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 336061326..890036b68 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -53,19 +53,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; -bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const -{ - return false; -} +static const aiImporterDesc desc = { + ".assbin Importer", + "Gargaj / Conspiracy", + "", + "", + aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, + 0, + 0, + 0, + 0, + "assbin" +}; const aiImporterDesc* Assimp::AssbinImporter::GetInfo() const { - return NULL; + return &desc; +} + +bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +{ + IOStream * in = pIOHandler->Open(pFile); + if (!in) + return false; + + char s[32]; + in->Read( s, sizeof(char), 32 ); + + pIOHandler->Close(in); + + return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; } void Assimp::AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) { - + // TODO } #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER From 87dff6a00eb38f327b504067fc3fafa81267be3c Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 13:26:26 +0200 Subject: [PATCH 15/34] start importer, load nodes --- code/AssbinLoader.cpp | 153 ++++++++++++++++++++++++++++++++++++++++-- code/AssbinLoader.h | 8 +++ 2 files changed, 157 insertions(+), 4 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 890036b68..cfe205ea8 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "AssbinLoader.h" +#include "assbin_chunks.h" using namespace Assimp; @@ -66,12 +67,12 @@ static const aiImporterDesc desc = { "assbin" }; -const aiImporterDesc* Assimp::AssbinImporter::GetInfo() const +const aiImporterDesc* AssbinImporter::GetInfo() const { return &desc; } -bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const +bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const { IOStream * in = pIOHandler->Open(pFile); if (!in) @@ -85,9 +86,153 @@ bool Assimp::AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHan return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; } -void Assimp::AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) +template +T Read(IOStream * stream) { - // TODO + T t; + stream->Read( &t, sizeof(T), 1 ); + return t; +} + +template <> +aiString Read(IOStream * stream) +{ + aiString s; + stream->Read(&s.length,4,1); + stream->Read(s.data,s.length,1); + return s; +} + +template <> +aiMatrix4x4 Read(IOStream * stream) +{ + aiMatrix4x4 m; + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + m[i][i2] = Read(stream); + } + } + return m; +} + +void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); + uint32_t size = Read(stream); + + *node = new aiNode(); + + (*node)->mName = Read(stream); + (*node)->mTransformation = Read(stream); + (*node)->mNumChildren = Read(stream); + (*node)->mNumMeshes = Read(stream); + + if ((*node)->mNumMeshes) + { + (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; + for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { + (*node)->mMeshes[i] = Read(stream); + } + } + + if ((*node)->mNumChildren) + { + (*node)->mChildren = new aiNode*[(*node)->mNumChildren]; + for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { + ReadBinaryNode( stream, &(*node)->mChildren[i] ); + } + } + +} + +void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); + uint32_t size = Read(stream); + + scene->mFlags = Read(stream); + scene->mNumMeshes = Read(stream); + scene->mNumMaterials = Read(stream); + scene->mNumAnimations = Read(stream); + scene->mNumTextures = Read(stream); + scene->mNumLights = Read(stream); + scene->mNumCameras = Read(stream); + + // Read node graph + scene->mRootNode = new aiNode[1]; + ReadBinaryNode( stream, &scene->mRootNode ); + +/* + // Read all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + ReadBinaryMesh( stream,mesh); + } + + // Read materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + ReadBinaryMaterial(stream,mat); + } + + // Read all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + ReadBinaryAnim(stream,anim); + } + + + // Read all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + ReadBinaryTexture(stream,mesh); + } + + // Read lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + ReadBinaryLight(stream,l); + } + + // Read cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + ReadBinaryCamera(stream,cam); + } +*/ + +} + +void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) +{ + IOStream * stream = pIOHandler->Open(pFile,"rb"); + if (!stream) + return; + + stream->Seek( 44, aiOrigin_CUR ); // signature + + unsigned int versionMajor = Read(stream); + unsigned int versionMinor = Read(stream); + unsigned int versionRevision = Read(stream); + unsigned int compileFlags = Read(stream); + + shortened = Read(stream) > 0; + compressed = Read(stream) > 0; + + stream->Seek( 256, aiOrigin_CUR ); // original filename + stream->Seek( 128, aiOrigin_CUR ); // options + stream->Seek( 64, aiOrigin_CUR ); // padding + + if (compressed) + { + // TODO + } + else + { + ReadBinaryScene(stream,pScene); + } + + pIOHandler->Close(stream); } #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index c3f6a5873..189b019ba 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -57,6 +57,12 @@ namespace Assimp { */ class AssbinImporter : public BaseImporter { +private: + bool shortened; + bool compressed; +protected: + +public: virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, @@ -68,6 +74,8 @@ class AssbinImporter : public BaseImporter aiScene* pScene, IOSystem* pIOHandler ); + void ReadBinaryScene( IOStream * stream, aiScene* pScene ); + void ReadBinaryNode( IOStream * stream, aiNode** mRootNode ); }; } // end of namespace Assimp From ac5c1f9df1b335f3a30e606b3057846fa2684def Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 13:27:09 +0200 Subject: [PATCH 16/34] add to cmake --- code/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 0a57d540b..4e05887ba 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -174,6 +174,8 @@ SOURCE_GROUP( ASE FILES ${ASE_SRCS}) SET( ASSBIN_SRCS AssbinExporter.h AssbinExporter.cpp + AssbinLoader.h + AssbinLoader.cpp ) SOURCE_GROUP( Assbin FILES ${ASSBIN_SRCS}) From ad298cd84f6525d39d32c2c91716604471041896 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 13:29:09 +0200 Subject: [PATCH 17/34] fix code style --- code/ImporterRegistry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/ImporterRegistry.cpp b/code/ImporterRegistry.cpp index 8499aaeaa..dff195854 100644 --- a/code/ImporterRegistry.cpp +++ b/code/ImporterRegistry.cpp @@ -292,10 +292,10 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out) out.push_back( new XGLImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_FBX_IMPORTER ) - out.push_back( new FBXImporter() ); + out.push_back( new FBXImporter() ); #endif #if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER ) - out.push_back( new AssbinImporter() ); + out.push_back( new AssbinImporter() ); #endif } From f38dd8e6e2468f417fa2a1d2cc133d8a2f1d9640 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:06:08 +0200 Subject: [PATCH 18/34] add mesh loader --- code/AssbinLoader.cpp | 167 ++++++++++++++++++++++++++++++++++++++++-- code/AssbinLoader.h | 2 + 2 files changed, 164 insertions(+), 5 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index cfe205ea8..24924ade5 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -115,6 +115,12 @@ aiMatrix4x4 Read(IOStream * stream) return m; } +template void ReadBounds( IOStream * stream, T* p, unsigned int n ) +{ + // not sure what to do here, the data isn't really useful. + stream->Seek( sizeof(T) * n, aiOrigin_CUR ); +} + void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); @@ -145,6 +151,153 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) } +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIBONE ); + uint32_t size = Read(stream); + + b->mName = Read(stream); + b->mNumWeights = Read(stream); + b->mOffsetMatrix = Read(stream); + + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) + { + ReadBounds(stream,b->mWeights,b->mNumWeights); + } // else write as usual + else + { + b->mWeights = new aiVertexWeight[b->mNumWeights]; + stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } +} + + +void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIMESH); + uint32_t size = Read(stream); + + mesh->mPrimitiveTypes = Read(stream); + mesh->mNumVertices = Read(stream); + mesh->mNumFaces = Read(stream); + mesh->mNumBones = Read(stream); + mesh->mMaterialIndex = Read(stream); + + // first of all, write bits for all existent vertex components + unsigned int c = Read(stream); + + if (c & ASSBIN_MESH_HAS_POSITIONS) + { + if (shortened) { + ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else + { + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); + } + } + if (c & ASSBIN_MESH_HAS_NORMALS) + { + if (shortened) { + ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else + { + mesh->mNormals = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); + } + } + if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) + { + if (shortened) { + ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); + ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + mesh->mTangents = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mTangents,1,12*mesh->mNumVertices); + mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mBitangents,1,12*mesh->mNumVertices); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) + { + if (!(c & ASSBIN_MESH_HAS_COLOR(n))) + break; + + if (shortened) + { + ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else + { + mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; + stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) + { + if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) + break; + + // write number of UV components + mesh->mNumUVComponents[n] = Read(stream); + + if (shortened) { + ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else + { + mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } + } + + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + Read(stream); + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + mesh->mFaces = new aiFace[mesh->mNumFaces]; + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + aiFace& f = mesh->mFaces[i]; + + BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); + f.mNumIndices = Read(stream); + f.mIndices = new unsigned int[f.mNumIndices]; + + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) + { + f.mIndices[a] = Read(stream); + } + else + { + f.mIndices[a] = Read(stream); + } + } + } + } + + // write bones + if (mesh->mNumBones) { + mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + mesh->mBones[a] = new aiBone(); + ReadBinaryBone(stream,mesh->mBones[a]); + } + } +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -162,13 +315,17 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) scene->mRootNode = new aiNode[1]; ReadBinaryNode( stream, &scene->mRootNode ); -/* // Read all meshes - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - const aiMesh* mesh = scene->mMeshes[i]; - ReadBinaryMesh( stream,mesh); - } + if (scene->mNumMeshes) + { + scene->mMeshes = new aiMesh*[scene->mNumMeshes]; + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + scene->mMeshes[i] = new aiMesh(); + ReadBinaryMesh( stream,scene->mMeshes[i]); + } + } +/* // Read materials for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { const aiMaterial* mat = scene->mMaterials[i]; diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index 189b019ba..64fb7056e 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -76,6 +76,8 @@ public: ); void ReadBinaryScene( IOStream * stream, aiScene* pScene ); void ReadBinaryNode( IOStream * stream, aiNode** mRootNode ); + void ReadBinaryMesh( IOStream * stream, aiMesh* mesh ); + void ReadBinaryBone( IOStream * stream, aiBone* bone ); }; } // end of namespace Assimp From 50487930969dda61caa5206c37401d452c0f5424 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:21:53 +0200 Subject: [PATCH 19/34] add material import --- code/AssbinLoader.cpp | 50 ++++++++++++++++++++++++++++++++++++++----- code/AssbinLoader.h | 2 ++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 24924ade5..ee970cd2e 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -298,6 +298,42 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) } } +void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY); + uint32_t size = Read(stream); + + prop->mKey = Read(stream); + prop->mSemantic = Read(stream); + prop->mIndex = Read(stream); + + prop->mDataLength = Read(stream); + prop->mType = (aiPropertyTypeInfo)Read(stream); + prop->mData = new char [ prop->mDataLength ]; + stream->Read(prop->mData,1,prop->mDataLength); +} + +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIAL); + uint32_t size = Read(stream); + + mat->mNumAllocated = mat->mNumProperties = Read(stream); + if (mat->mNumProperties) + { + if (mat->mProperties) + { + delete[] mat->mProperties; + } + mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + mat->mProperties[i] = new aiMaterialProperty(); + ReadBinaryMaterialProperty( stream, mat->mProperties[i]); + } + } +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -325,12 +361,16 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) } } -/* // Read materials - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - const aiMaterial* mat = scene->mMaterials[i]; - ReadBinaryMaterial(stream,mat); - } + if (scene->mNumMaterials) + { + scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + scene->mMaterials[i] = new aiMaterial(); + ReadBinaryMaterial(stream,scene->mMaterials[i]); + } + } +/* // Read all animations for (unsigned int i = 0; i < scene->mNumAnimations;++i) { diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index 64fb7056e..7b99860b4 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -78,6 +78,8 @@ public: void ReadBinaryNode( IOStream * stream, aiNode** mRootNode ); void ReadBinaryMesh( IOStream * stream, aiMesh* mesh ); void ReadBinaryBone( IOStream * stream, aiBone* bone ); + void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat); + void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop); }; } // end of namespace Assimp From 886a704c17d323f0b1d71eb22ec3c3989d2df208 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:43:47 +0200 Subject: [PATCH 20/34] some notes to self --- code/AssbinExporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2f1c403e9..439f2e61f 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -337,7 +337,7 @@ namespace Assimp { if(!shortened) { if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); + chunk.Write(tex->pcData,1,tex->mWidth); // BUG?! should be *4? } else { chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); @@ -732,7 +732,7 @@ namespace Assimp { compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); - out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); + out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); // BUG?! are we writing compressed or uncompressed size here? out->Write( compressedBuffer, sizeof(char), compressedSize ); delete[] compressedBuffer; From 97c9ce1d5b1e8fd76677c38e9759c3b182ee82e0 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 14:44:06 +0200 Subject: [PATCH 21/34] add animations and textures --- code/AssbinLoader.cpp | 118 ++++++++++++++++++++++++++++++++++++++---- code/AssbinLoader.h | 3 ++ 2 files changed, 111 insertions(+), 10 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index ee970cd2e..c0777a87b 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -334,6 +334,97 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) } } +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AINODEANIM); + uint32_t size = Read(stream); + + nd->mNodeName = Read(stream); + nd->mNumPositionKeys = Read(stream); + nd->mNumRotationKeys = Read(stream); + nd->mNumScalingKeys = Read(stream); + nd->mPreState = (aiAnimBehaviour)Read(stream); + nd->mPostState = (aiAnimBehaviour)Read(stream); + + if (nd->mNumPositionKeys) { + if (shortened) { + ReadBounds(stream,nd->mPositionKeys,nd->mNumPositionKeys); + + } // else write as usual + else { + nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; + stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } + } + if (nd->mNumRotationKeys) { + if (shortened) { + ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys); + + } // else write as usual + else + { + nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; + stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } + } + if (nd->mNumScalingKeys) { + if (shortened) { + ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys); + + } // else write as usual + else + { + nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; + stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } + } +} + + +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AIANIMATION); + uint32_t size = Read(stream); + + anim->mName = Read (stream); + anim->mDuration = Read (stream); + anim->mTicksPerSecond = Read (stream); + anim->mNumChannels = Read(stream); + + if (anim->mNumChannels) + { + anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + anim->mChannels[a] = new aiNodeAnim(); + ReadBinaryNodeAnim(stream,anim->mChannels[a]); + } + } +} + +void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AITEXTURE); + uint32_t size = Read(stream); + + tex->mWidth = Read(stream); + tex->mHeight = Read(stream); + stream->Read( tex->achFormatHint, sizeof(char), 4 ); + + if(!shortened) { + if (!tex->mHeight) { + tex->pcData = new aiTexel[ tex->mWidth ]; + stream->Read(tex->pcData,1,tex->mWidth); + } + else { + tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; + stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); + } + } + +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -370,21 +461,28 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) ReadBinaryMaterial(stream,scene->mMaterials[i]); } } -/* // Read all animations - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - const aiAnimation* anim = scene->mAnimations[i]; - ReadBinaryAnim(stream,anim); - } - + if (scene->mNumAnimations) + { + scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + scene->mAnimations[i] = new aiAnimation(); + ReadBinaryAnim(stream,scene->mAnimations[i]); + } + } // Read all textures - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - const aiTexture* mesh = scene->mTextures[i]; - ReadBinaryTexture(stream,mesh); - } + if (scene->mNumTextures) + { + scene->mTextures = new aiTexture*[scene->mNumTextures]; + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + scene->mTextures[i] = new aiTexture(); + ReadBinaryTexture(stream,scene->mTextures[i]); + } + } +/* // Read lights for (unsigned int i = 0; i < scene->mNumLights;++i) { const aiLight* l = scene->mLights[i]; diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index 7b99860b4..a1b2a71d6 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -80,6 +80,9 @@ public: void ReadBinaryBone( IOStream * stream, aiBone* bone ); void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat); void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop); + void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd); + void ReadBinaryAnim( IOStream * stream, aiAnimation* anim ); + void ReadBinaryTexture(IOStream * stream, aiTexture* tex); }; } // end of namespace Assimp From 1aeaef2037c71f1312e8cfe93dacae30f870683a Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 15:01:04 +0200 Subject: [PATCH 22/34] add lights and cameras --- code/AssbinLoader.cpp | 68 ++++++++++++++++++++++++++++++++++++------- code/AssbinLoader.h | 2 ++ 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index c0777a87b..8dbbbae22 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -425,6 +425,48 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) } +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AILIGHT); + uint32_t size = Read(stream); + + l->mName = Read(stream); + l->mType = (aiLightSourceType)Read(stream); + + if (l->mType != aiLightSource_DIRECTIONAL) { + l->mAttenuationConstant = Read(stream); + l->mAttenuationLinear = Read(stream); + l->mAttenuationQuadratic = Read(stream); + } + + l->mColorDiffuse = Read(stream); + l->mColorSpecular = Read(stream); + l->mColorAmbient = Read(stream); + + if (l->mType == aiLightSource_SPOT) { + l->mAngleInnerCone = Read(stream); + l->mAngleOuterCone = Read(stream); + } + +} + +// ----------------------------------------------------------------------------------- +void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) +{ + ai_assert( Read(stream) == ASSBIN_CHUNK_AICAMERA); + uint32_t size = Read(stream); + + cam->mName = Read(stream); + cam->mPosition = Read(stream); + cam->mLookAt = Read(stream); + cam->mUp = Read(stream); + cam->mHorizontalFOV = Read(stream); + cam->mClipPlaneNear = Read(stream); + cam->mClipPlaneFar = Read(stream); + cam->mAspect = Read(stream); +} + void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); @@ -482,19 +524,25 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) } } -/* // Read lights - for (unsigned int i = 0; i < scene->mNumLights;++i) { - const aiLight* l = scene->mLights[i]; - ReadBinaryLight(stream,l); - } + if (scene->mNumLights) + { + scene->mLights = new aiLight*[scene->mNumLights]; + for (unsigned int i = 0; i < scene->mNumLights;++i) { + scene->mLights[i] = new aiLight(); + ReadBinaryLight(stream,scene->mLights[i]); + } + } // Read cameras - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - const aiCamera* cam = scene->mCameras[i]; - ReadBinaryCamera(stream,cam); - } -*/ + if (scene->mNumCameras) + { + scene->mCameras = new aiCamera*[scene->mNumCameras]; + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + scene->mCameras[i] = new aiCamera(); + ReadBinaryCamera(stream,scene->mCameras[i]); + } + } } diff --git a/code/AssbinLoader.h b/code/AssbinLoader.h index a1b2a71d6..f4e6e059a 100644 --- a/code/AssbinLoader.h +++ b/code/AssbinLoader.h @@ -83,6 +83,8 @@ public: void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd); void ReadBinaryAnim( IOStream * stream, aiAnimation* anim ); void ReadBinaryTexture(IOStream * stream, aiTexture* tex); + void ReadBinaryLight( IOStream * stream, aiLight* l ); + void ReadBinaryCamera( IOStream * stream, aiCamera* cam ); }; } // end of namespace Assimp From fb546b694e1dc66d781c5df192e712290d2e3729 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Wed, 6 Aug 2014 15:25:39 +0200 Subject: [PATCH 23/34] code style --- code/AssbinLoader.cpp | 375 +++++++++++++++++++++--------------------- 1 file changed, 188 insertions(+), 187 deletions(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 8dbbbae22..1739659b1 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -55,58 +55,58 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using namespace Assimp; static const aiImporterDesc desc = { - ".assbin Importer", - "Gargaj / Conspiracy", - "", - "", - aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, - 0, - 0, - 0, - 0, - "assbin" + ".assbin Importer", + "Gargaj / Conspiracy", + "", + "", + aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, + 0, + 0, + 0, + 0, + "assbin" }; const aiImporterDesc* AssbinImporter::GetInfo() const { - return &desc; + return &desc; } bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const { - IOStream * in = pIOHandler->Open(pFile); - if (!in) - return false; + IOStream * in = pIOHandler->Open(pFile); + if (!in) + return false; - char s[32]; - in->Read( s, sizeof(char), 32 ); + char s[32]; + in->Read( s, sizeof(char), 32 ); - pIOHandler->Close(in); + pIOHandler->Close(in); - return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; + return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0; } template T Read(IOStream * stream) { - T t; - stream->Read( &t, sizeof(T), 1 ); - return t; + T t; + stream->Read( &t, sizeof(T), 1 ); + return t; } template <> aiString Read(IOStream * stream) { - aiString s; + aiString s; stream->Read(&s.length,4,1); - stream->Read(s.data,s.length,1); - return s; + stream->Read(s.data,s.length,1); + return s; } template <> aiMatrix4x4 Read(IOStream * stream) { - aiMatrix4x4 m; + aiMatrix4x4 m; for (unsigned int i = 0; i < 4;++i) { for (unsigned int i2 = 0; i2 < 4;++i2) { m[i][i2] = Read(stream); @@ -117,37 +117,37 @@ aiMatrix4x4 Read(IOStream * stream) template void ReadBounds( IOStream * stream, T* p, unsigned int n ) { - // not sure what to do here, the data isn't really useful. + // not sure what to do here, the data isn't really useful. stream->Seek( sizeof(T) * n, aiOrigin_CUR ); } void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODE); - uint32_t size = Read(stream); + uint32_t size = Read(stream); - *node = new aiNode(); + *node = new aiNode(); (*node)->mName = Read(stream); (*node)->mTransformation = Read(stream); (*node)->mNumChildren = Read(stream); (*node)->mNumMeshes = Read(stream); - if ((*node)->mNumMeshes) - { - (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; - for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { - (*node)->mMeshes[i] = Read(stream); - } - } + if ((*node)->mNumMeshes) + { + (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes]; + for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) { + (*node)->mMeshes[i] = Read(stream); + } + } - if ((*node)->mNumChildren) - { - (*node)->mChildren = new aiNode*[(*node)->mNumChildren]; - for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { - ReadBinaryNode( stream, &(*node)->mChildren[i] ); - } - } + if ((*node)->mNumChildren) + { + (*node)->mChildren = new aiNode*[(*node)->mNumChildren]; + for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) { + ReadBinaryNode( stream, &(*node)->mChildren[i] ); + } + } } @@ -155,7 +155,7 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node ) void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIBONE ); - uint32_t size = Read(stream); + uint32_t size = Read(stream); b->mName = Read(stream); b->mNumWeights = Read(stream); @@ -164,21 +164,21 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) - { + { ReadBounds(stream,b->mWeights,b->mNumWeights); } // else write as usual else - { - b->mWeights = new aiVertexWeight[b->mNumWeights]; - stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); - } + { + b->mWeights = new aiVertexWeight[b->mNumWeights]; + stream->Read(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); + } } void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMESH); - uint32_t size = Read(stream); + uint32_t size = Read(stream); mesh->mPrimitiveTypes = Read(stream); mesh->mNumVertices = Read(stream); @@ -190,57 +190,58 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) unsigned int c = Read(stream); if (c & ASSBIN_MESH_HAS_POSITIONS) - { + { if (shortened) { ReadBounds(stream,mesh->mVertices,mesh->mNumVertices); } // else write as usual else - { - mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); - } + { + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mVertices,1,12*mesh->mNumVertices); + } } if (c & ASSBIN_MESH_HAS_NORMALS) - { + { if (shortened) { ReadBounds(stream,mesh->mNormals,mesh->mNumVertices); } // else write as usual else - { - mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); - } + { + mesh->mNormals = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mNormals,1,12*mesh->mNumVertices); + } } if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) - { + { if (shortened) { ReadBounds(stream,mesh->mTangents,mesh->mNumVertices); ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices); } // else write as usual - else { - mesh->mTangents = new aiVector3D[mesh->mNumVertices]; + else + { + mesh->mTangents = new aiVector3D[mesh->mNumVertices]; stream->Read(mesh->mTangents,1,12*mesh->mNumVertices); - mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; + mesh->mBitangents = new aiVector3D[mesh->mNumVertices]; stream->Read(mesh->mBitangents,1,12*mesh->mNumVertices); } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) - { + { if (!(c & ASSBIN_MESH_HAS_COLOR(n))) break; if (shortened) - { + { ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices); } // else write as usual else - { - mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; - stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); - } + { + mesh->mColors[n] = new aiColor4D[mesh->mNumVertices]; + stream->Read(mesh->mColors[n],16*mesh->mNumVertices,1); + } } for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) - { + { if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n))) break; @@ -251,10 +252,10 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices); } // else write as usual else - { - mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; - stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); - } + { + mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices]; + stream->Read(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); + } } // write faces. There are no floating-point calculations involved @@ -267,30 +268,30 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) else // else write as usual { // if there are less than 2^16 vertices, we can simply use 16 bit integers ... - mesh->mFaces = new aiFace[mesh->mNumFaces]; + mesh->mFaces = new aiFace[mesh->mNumFaces]; for (unsigned int i = 0; i < mesh->mNumFaces;++i) { aiFace& f = mesh->mFaces[i]; BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); f.mNumIndices = Read(stream); - f.mIndices = new unsigned int[f.mNumIndices]; + f.mIndices = new unsigned int[f.mNumIndices]; for (unsigned int a = 0; a < f.mNumIndices;++a) { if (mesh->mNumVertices < (1u<<16)) - { + { f.mIndices[a] = Read(stream); } else - { - f.mIndices[a] = Read(stream); - } + { + f.mIndices[a] = Read(stream); + } } } } // write bones if (mesh->mNumBones) { - mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; + mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones]; for (unsigned int a = 0; a < mesh->mNumBones;++a) { mesh->mBones[a] = new aiBone(); ReadBinaryBone(stream,mesh->mBones[a]); @@ -301,7 +302,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY); - uint32_t size = Read(stream); + uint32_t size = Read(stream); prop->mKey = Read(stream); prop->mSemantic = Read(stream); @@ -309,7 +310,7 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro prop->mDataLength = Read(stream); prop->mType = (aiPropertyTypeInfo)Read(stream); - prop->mData = new char [ prop->mDataLength ]; + prop->mData = new char [ prop->mDataLength ]; stream->Read(prop->mData,1,prop->mDataLength); } @@ -317,28 +318,28 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIMATERIAL); - uint32_t size = Read(stream); + uint32_t size = Read(stream); mat->mNumAllocated = mat->mNumProperties = Read(stream); - if (mat->mNumProperties) - { - if (mat->mProperties) - { - delete[] mat->mProperties; - } - mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; - for (unsigned int i = 0; i < mat->mNumProperties;++i) { - mat->mProperties[i] = new aiMaterialProperty(); - ReadBinaryMaterialProperty( stream, mat->mProperties[i]); - } - } + if (mat->mNumProperties) + { + if (mat->mProperties) + { + delete[] mat->mProperties; + } + mat->mProperties = new aiMaterialProperty*[mat->mNumProperties]; + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + mat->mProperties[i] = new aiMaterialProperty(); + ReadBinaryMaterialProperty( stream, mat->mProperties[i]); + } + } } // ----------------------------------------------------------------------------------- void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) { ai_assert( Read(stream) == ASSBIN_CHUNK_AINODEANIM); - uint32_t size = Read(stream); + uint32_t size = Read(stream); nd->mNodeName = Read(stream); nd->mNumPositionKeys = Read(stream); @@ -353,9 +354,9 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else { - nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; - stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); - } + nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys]; + stream->Read(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); + } } if (nd->mNumRotationKeys) { if (shortened) { @@ -363,10 +364,10 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else - { - nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; - stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); - } + { + nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys]; + stream->Read(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); + } } if (nd->mNumScalingKeys) { if (shortened) { @@ -374,10 +375,10 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) } // else write as usual else - { - nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; - stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); - } + { + nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys]; + stream->Read(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); + } } } @@ -386,27 +387,27 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AIANIMATION); - uint32_t size = Read(stream); + uint32_t size = Read(stream); anim->mName = Read (stream); anim->mDuration = Read (stream); anim->mTicksPerSecond = Read (stream); anim->mNumChannels = Read(stream); - if (anim->mNumChannels) - { - anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; - for (unsigned int a = 0; a < anim->mNumChannels;++a) { - anim->mChannels[a] = new aiNodeAnim(); - ReadBinaryNodeAnim(stream,anim->mChannels[a]); - } - } + if (anim->mNumChannels) + { + anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ]; + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + anim->mChannels[a] = new aiNodeAnim(); + ReadBinaryNodeAnim(stream,anim->mChannels[a]); + } + } } void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) { ai_assert( Read(stream) == ASSBIN_CHUNK_AITEXTURE); - uint32_t size = Read(stream); + uint32_t size = Read(stream); tex->mWidth = Read(stream); tex->mHeight = Read(stream); @@ -414,11 +415,11 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) if(!shortened) { if (!tex->mHeight) { - tex->pcData = new aiTexel[ tex->mWidth ]; + tex->pcData = new aiTexel[ tex->mWidth ]; stream->Read(tex->pcData,1,tex->mWidth); } else { - tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; + tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ]; stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4); } } @@ -429,7 +430,7 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AILIGHT); - uint32_t size = Read(stream); + uint32_t size = Read(stream); l->mName = Read(stream); l->mType = (aiLightSourceType)Read(stream); @@ -455,7 +456,7 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AICAMERA); - uint32_t size = Read(stream); + uint32_t size = Read(stream); cam->mName = Read(stream); cam->mPosition = Read(stream); @@ -470,7 +471,7 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) { ai_assert( Read(stream) == ASSBIN_CHUNK_AISCENE); - uint32_t size = Read(stream); + uint32_t size = Read(stream); scene->mFlags = Read(stream); scene->mNumMeshes = Read(stream); @@ -481,68 +482,68 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) scene->mNumCameras = Read(stream); // Read node graph - scene->mRootNode = new aiNode[1]; + scene->mRootNode = new aiNode[1]; ReadBinaryNode( stream, &scene->mRootNode ); // Read all meshes - if (scene->mNumMeshes) - { - scene->mMeshes = new aiMesh*[scene->mNumMeshes]; - for (unsigned int i = 0; i < scene->mNumMeshes;++i) { - scene->mMeshes[i] = new aiMesh(); - ReadBinaryMesh( stream,scene->mMeshes[i]); - } - } + if (scene->mNumMeshes) + { + scene->mMeshes = new aiMesh*[scene->mNumMeshes]; + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + scene->mMeshes[i] = new aiMesh(); + ReadBinaryMesh( stream,scene->mMeshes[i]); + } + } // Read materials - if (scene->mNumMaterials) - { - scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; - for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { - scene->mMaterials[i] = new aiMaterial(); - ReadBinaryMaterial(stream,scene->mMaterials[i]); - } - } + if (scene->mNumMaterials) + { + scene->mMaterials = new aiMaterial*[scene->mNumMaterials]; + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + scene->mMaterials[i] = new aiMaterial(); + ReadBinaryMaterial(stream,scene->mMaterials[i]); + } + } // Read all animations - if (scene->mNumAnimations) - { - scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; - for (unsigned int i = 0; i < scene->mNumAnimations;++i) { - scene->mAnimations[i] = new aiAnimation(); - ReadBinaryAnim(stream,scene->mAnimations[i]); - } - } + if (scene->mNumAnimations) + { + scene->mAnimations = new aiAnimation*[scene->mNumAnimations]; + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + scene->mAnimations[i] = new aiAnimation(); + ReadBinaryAnim(stream,scene->mAnimations[i]); + } + } // Read all textures - if (scene->mNumTextures) - { - scene->mTextures = new aiTexture*[scene->mNumTextures]; - for (unsigned int i = 0; i < scene->mNumTextures;++i) { - scene->mTextures[i] = new aiTexture(); - ReadBinaryTexture(stream,scene->mTextures[i]); - } - } + if (scene->mNumTextures) + { + scene->mTextures = new aiTexture*[scene->mNumTextures]; + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + scene->mTextures[i] = new aiTexture(); + ReadBinaryTexture(stream,scene->mTextures[i]); + } + } // Read lights - if (scene->mNumLights) - { - scene->mLights = new aiLight*[scene->mNumLights]; - for (unsigned int i = 0; i < scene->mNumLights;++i) { - scene->mLights[i] = new aiLight(); - ReadBinaryLight(stream,scene->mLights[i]); - } - } + if (scene->mNumLights) + { + scene->mLights = new aiLight*[scene->mNumLights]; + for (unsigned int i = 0; i < scene->mNumLights;++i) { + scene->mLights[i] = new aiLight(); + ReadBinaryLight(stream,scene->mLights[i]); + } + } // Read cameras - if (scene->mNumCameras) - { - scene->mCameras = new aiCamera*[scene->mNumCameras]; - for (unsigned int i = 0; i < scene->mNumCameras;++i) { - scene->mCameras[i] = new aiCamera(); - ReadBinaryCamera(stream,scene->mCameras[i]); - } - } + if (scene->mNumCameras) + { + scene->mCameras = new aiCamera*[scene->mNumCameras]; + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + scene->mCameras[i] = new aiCamera(); + ReadBinaryCamera(stream,scene->mCameras[i]); + } + } } @@ -550,9 +551,9 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, { IOStream * stream = pIOHandler->Open(pFile,"rb"); if (!stream) - return; + return; - stream->Seek( 44, aiOrigin_CUR ); // signature + stream->Seek( 44, aiOrigin_CUR ); // signature unsigned int versionMajor = Read(stream); unsigned int versionMinor = Read(stream); @@ -562,20 +563,20 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, shortened = Read(stream) > 0; compressed = Read(stream) > 0; - stream->Seek( 256, aiOrigin_CUR ); // original filename - stream->Seek( 128, aiOrigin_CUR ); // options - stream->Seek( 64, aiOrigin_CUR ); // padding + stream->Seek( 256, aiOrigin_CUR ); // original filename + stream->Seek( 128, aiOrigin_CUR ); // options + stream->Seek( 64, aiOrigin_CUR ); // padding - if (compressed) - { - // TODO - } - else - { - ReadBinaryScene(stream,pScene); - } - - pIOHandler->Close(stream); + if (compressed) + { + // TODO + } + else + { + ReadBinaryScene(stream,pScene); + } + + pIOHandler->Close(stream); } #endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER From 061911bdbff6ac9613d8daaf202b95ebaf37cac4 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:05:07 +0200 Subject: [PATCH 24/34] add support for compressed, drop support for shortened --- code/AssbinLoader.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 1739659b1..9bc9a0a08 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -51,6 +51,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "AssbinLoader.h" #include "assbin_chunks.h" +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +# include +#else +# include "../contrib/zlib/zlib.h" +#include "MemoryIOWrapper.h" +#endif using namespace Assimp; @@ -563,13 +569,31 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, shortened = Read(stream) > 0; compressed = Read(stream) > 0; + if (shortened) + throw DeadlyImportError( "Shortened binaries are not supported!" ); + stream->Seek( 256, aiOrigin_CUR ); // original filename stream->Seek( 128, aiOrigin_CUR ); // options stream->Seek( 64, aiOrigin_CUR ); // padding if (compressed) { - // TODO + uLongf uncompressedSize = Read(stream); + uLongf compressedSize = stream->FileSize() - stream->Tell(); + + unsigned char * compressedData = new unsigned char[ compressedSize ]; + stream->Read( compressedData, 1, compressedSize ); + + unsigned char * uncompressedData = new unsigned char[ uncompressedSize ]; + + uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize ); + + MemoryIOStream io( uncompressedData, uncompressedSize ); + + ReadBinaryScene(&io,pScene); + + delete[] uncompressedData; + delete[] compressedData; } else { From 523d87bbe7c76ffbdc74ee49b5977a66055bea0d Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:22:47 +0200 Subject: [PATCH 25/34] use 0..fileSize as progress metric (easier for loaders) --- code/Importer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 0a817476a..9cfb5be46 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -640,16 +640,21 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) } } + // Get file size for progress handler + IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); + uint32_t fileSize = fileIO->FileSize(); + pimpl->mIOHandler->Close( fileIO ); + // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); - pimpl->mProgressHandler->UpdateFileRead( 0, 1 ); + pimpl->mProgressHandler->UpdateFileRead( 0, fileSize ); if (profiler) { profiler->BeginRegion("import"); } pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler); - pimpl->mProgressHandler->UpdateFileRead( 1, 1 ); + pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize ); if (profiler) { profiler->EndRegion("import"); From 7925dcadba2778d8e8a4308aacf252ef19ace689 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:25:10 +0200 Subject: [PATCH 26/34] avoid NULL, just in case (loader might just probably crash anyway) --- code/Importer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 9cfb5be46..c22b76057 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,8 +642,11 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Get file size for progress handler IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); - uint32_t fileSize = fileIO->FileSize(); - pimpl->mIOHandler->Close( fileIO ); + if (fileIO) + { + uint32_t fileSize = fileIO->FileSize(); + pimpl->mIOHandler->Close( fileIO ); + } // Dispatch the reading to the worker class for this format DefaultLogger::get()->info("Found a matching importer for this file format"); From aa5c1a1a23eb69af3e721e5d59fd2c7f08d12ce1 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:26:04 +0200 Subject: [PATCH 27/34] syntax --- code/Importer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index c22b76057..01f853a05 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,9 +642,10 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Get file size for progress handler IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); + uint32_t fileSize = 0; if (fileIO) { - uint32_t fileSize = fileIO->FileSize(); + fileSize = fileIO->FileSize(); pimpl->mIOHandler->Close( fileIO ); } From df4b17d145530403b507f528de28ff59b2df3bf0 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:26:34 +0200 Subject: [PATCH 28/34] code style --- code/Importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/Importer.cpp b/code/Importer.cpp index 01f853a05..a9173cddc 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -642,7 +642,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) // Get file size for progress handler IOStream * fileIO = pimpl->mIOHandler->Open( pFile ); - uint32_t fileSize = 0; + uint32_t fileSize = 0; if (fileIO) { fileSize = fileIO->FileSize(); From 3c172988bbb0360ad01d3ba01202081e044b1475 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 08:43:52 +0200 Subject: [PATCH 29/34] remove BUG notices (discussed with acgessler) --- code/AssbinExporter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 439f2e61f..2f1c403e9 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -337,7 +337,7 @@ namespace Assimp { if(!shortened) { if (!tex->mHeight) { - chunk.Write(tex->pcData,1,tex->mWidth); // BUG?! should be *4? + chunk.Write(tex->pcData,1,tex->mWidth); } else { chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4); @@ -732,7 +732,7 @@ namespace Assimp { compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 ); - out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); // BUG?! are we writing compressed or uncompressed size here? + out->Write( &uncompressedSize, sizeof(uint32_t), 1 ); out->Write( compressedBuffer, sizeof(char), compressedSize ); delete[] compressedBuffer; From 2775141da3db933f5eadf3d69a7fb5ce15c30f23 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:07:09 +0200 Subject: [PATCH 30/34] #include should be outside --- code/AssbinLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinLoader.cpp b/code/AssbinLoader.cpp index 9bc9a0a08..617355263 100644 --- a/code/AssbinLoader.cpp +++ b/code/AssbinLoader.cpp @@ -51,11 +51,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // internal headers #include "AssbinLoader.h" #include "assbin_chunks.h" +#include "MemoryIOWrapper.h" #ifdef ASSIMP_BUILD_NO_OWN_ZLIB # include #else # include "../contrib/zlib/zlib.h" -#include "MemoryIOWrapper.h" #endif using namespace Assimp; From b53a425fe4424a45bf52fb40e0ebdbd2f753ee4e Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:28:50 +0200 Subject: [PATCH 31/34] make templates gcc compatible --- code/AssbinExporter.cpp | 445 ++++++++++++++++++++-------------------- 1 file changed, 220 insertions(+), 225 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 2f1c403e9..bca9a3975 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -58,6 +58,154 @@ using namespace Assimp; namespace Assimp { +template +size_t Write(IOStream * stream, const T& v) +{ + return stream->Write( &v, sizeof(T), 1 ); +} + + +// ----------------------------------------------------------------------------------- +// Serialize an aiString +template <> +inline size_t Write(IOStream * stream, const aiString& s) +{ + const size_t s2 = (uint32_t)s.length; + stream->Write(&s,4,1); + stream->Write(s.data,s2,1); + return s2+4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint32_t +template <> +inline size_t Write(IOStream * stream, const unsigned int& w) +{ + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); + } + + stream->Write(&t,4,1); + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint16_t +template <> +inline size_t Write(IOStream * stream, const uint16_t& w) +{ + stream->Write(&w,2,1); + return 2; +} + +// ----------------------------------------------------------------------------------- +// Serialize a float +template <> +inline size_t Write(IOStream * stream, const float& f) +{ + BOOST_STATIC_ASSERT(sizeof(float)==4); + stream->Write(&f,4,1); + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize a double +template <> +inline size_t Write(IOStream * stream, const double& f) +{ + BOOST_STATIC_ASSERT(sizeof(double)==8); + stream->Write(&f,8,1); + return 8; +} + +// ----------------------------------------------------------------------------------- +// Serialize a vec3 +template <> +inline size_t Write(IOStream * stream, const aiVector3D& v) +{ + size_t t = Write(stream,v.x); + t += Write(stream,v.y); + t += Write(stream,v.z); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline size_t Write(IOStream * stream, const aiColor4D& v) +{ + size_t t = Write(stream,v.r); + t += Write(stream,v.g); + t += Write(stream,v.b); + t += Write(stream,v.a); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a quaternion +template <> +inline size_t Write(IOStream * stream, const aiQuaternion& v) +{ + size_t t = Write(stream,v.w); + t += Write(stream,v.x); + t += Write(stream,v.y); + t += Write(stream,v.z); + return 16; +} + + +// ----------------------------------------------------------------------------------- +// Serialize a vertex weight +template <> +inline size_t Write(IOStream * stream, const aiVertexWeight& v) +{ + uint32_t t = Write(stream,v.mVertexId); + return t+Write(stream,v.mWeight); +} + +// ----------------------------------------------------------------------------------- +// Serialize a mat4x4 +template <> +inline size_t Write(IOStream * stream, const aiMatrix4x4& m) +{ + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write(stream,m[i][i2]); + } + } + return 64; +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiVectorKey +template <> +inline size_t Write(IOStream * stream, const aiVectorKey& v) +{ + const size_t t = Write(stream,v.mTime); + return t + Write(stream,v.mValue); +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiQuatKey +template <> +inline size_t Write(IOStream * stream, const aiQuatKey& v) +{ + const size_t t = Write(stream,v.mTime); + return t + Write(stream,v.mValue); +} + +template +inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) +{ + T minc,maxc; + ArrayBounds(in,size,minc,maxc); + + const size_t t = Write(stream,minc); + return t + Write(stream,maxc); +} + // ---------------------------------------------------------------------------------- /** @class AssbinChunkWriter * @brief Chunk writer mechanism for the .assbin file structure @@ -138,154 +286,6 @@ namespace Assimp { return pCount; } - template - size_t Write(const T& v) - { - return Write( &v, sizeof(T), 1 ); - } - - - // ----------------------------------------------------------------------------------- - // Serialize an aiString - template <> - inline uint32_t Write(const aiString& s) - { - const uint32_t s2 = (uint32_t)s.length; - Write(&s,4,1); - Write(s.data,s2,1); - return s2+4; - } - - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint32_t - template <> - inline uint32_t Write(const unsigned int& w) - { - const uint32_t t = (uint32_t)w; - if (w > t) { - // this shouldn't happen, integers in Assimp data structures never exceed 2^32 - throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion"); - } - - Write(&t,4,1); - return 4; - } - - // ----------------------------------------------------------------------------------- - // Serialize an unsigned int as uint16_t - template <> - inline uint32_t Write(const uint16_t& w) - { - Write(&w,2,1); - return 2; - } - - // ----------------------------------------------------------------------------------- - // Serialize a float - template <> - inline uint32_t Write(const float& f) - { - BOOST_STATIC_ASSERT(sizeof(float)==4); - Write(&f,4,1); - return 4; - } - - // ----------------------------------------------------------------------------------- - // Serialize a double - template <> - inline uint32_t Write(const double& f) - { - BOOST_STATIC_ASSERT(sizeof(double)==8); - Write(&f,8,1); - return 8; - } - - // ----------------------------------------------------------------------------------- - // Serialize a vec3 - template <> - inline uint32_t Write(const aiVector3D& v) - { - uint32_t t = Write(v.x); - t += Write(v.y); - t += Write(v.z); - return t; - } - - // ----------------------------------------------------------------------------------- - // Serialize a color value - template <> - inline uint32_t Write(const aiColor4D& v) - { - uint32_t t = Write(v.r); - t += Write(v.g); - t += Write(v.b); - t += Write(v.a); - return t; - } - - // ----------------------------------------------------------------------------------- - // Serialize a quaternion - template <> - inline uint32_t Write(const aiQuaternion& v) - { - uint32_t t = Write(v.w); - t += Write(v.x); - t += Write(v.y); - t += Write(v.z); - return 16; - } - - - // ----------------------------------------------------------------------------------- - // Serialize a vertex weight - template <> - inline uint32_t Write(const aiVertexWeight& v) - { - uint32_t t = Write(v.mVertexId); - return t+Write(v.mWeight); - } - - // ----------------------------------------------------------------------------------- - // Serialize a mat4x4 - template <> - inline uint32_t Write(const aiMatrix4x4& m) - { - for (unsigned int i = 0; i < 4;++i) { - for (unsigned int i2 = 0; i2 < 4;++i2) { - Write(m[i][i2]); - } - } - return 64; - } - - // ----------------------------------------------------------------------------------- - // Serialize an aiVectorKey - template <> - inline uint32_t Write(const aiVectorKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } - - // ----------------------------------------------------------------------------------- - // Serialize an aiQuatKey - template <> - inline uint32_t Write(const aiQuatKey& v) - { - const uint32_t t = Write(v.mTime); - return t + Write(v.mValue); - } - - template - inline uint32_t WriteBounds(const T* in, unsigned int size) - { - T minc,maxc; - ArrayBounds(in,size,minc,maxc); - - const uint32_t t = Write(minc); - return t + Write(maxc); - } - }; // ---------------------------------------------------------------------------------- @@ -301,24 +301,19 @@ namespace Assimp { bool compressed; protected: - template - size_t Write( IOStream * container, const T& v) - { - return container->Write( &v, sizeof(T), 1 ); - } // ----------------------------------------------------------------------------------- void WriteBinaryNode( IOStream * container, const aiNode* node) { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE ); - chunk.Write(node->mName); - chunk.Write(node->mTransformation); - chunk.Write(node->mNumChildren); - chunk.Write(node->mNumMeshes); + Write(&chunk,node->mName); + Write(&chunk,node->mTransformation); + Write(&chunk,node->mNumChildren); + Write(&chunk,node->mNumMeshes); for (unsigned int i = 0; i < node->mNumMeshes;++i) { - chunk.Write(node->mMeshes[i]); + Write(&chunk,node->mMeshes[i]); } for (unsigned int i = 0; i < node->mNumChildren;++i) { @@ -331,8 +326,8 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE ); - chunk.Write(tex->mWidth); - chunk.Write(tex->mHeight); + Write(&chunk,tex->mWidth); + Write(&chunk,tex->mHeight); chunk.Write( tex->achFormatHint, sizeof(char), 4 ); if(!shortened) { @@ -351,14 +346,14 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE ); - chunk.Write(b->mName); - chunk.Write(b->mNumWeights); - chunk.Write(b->mOffsetMatrix); + Write(&chunk,b->mName); + Write(&chunk,b->mNumWeights); + Write(&chunk,b->mOffsetMatrix); // for the moment we write dumb min/max values for the bones, too. // maybe I'll add a better, hash-like solution later if (shortened) { - chunk.WriteBounds(b->mWeights,b->mNumWeights); + WriteBounds(&chunk,b->mWeights,b->mNumWeights); } // else write as usual else chunk.Write(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight)); } @@ -368,11 +363,11 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH ); - chunk.Write(mesh->mPrimitiveTypes); - chunk.Write(mesh->mNumVertices); - chunk.Write(mesh->mNumFaces); - chunk.Write(mesh->mNumBones); - chunk.Write(mesh->mMaterialIndex); + Write(&chunk,mesh->mPrimitiveTypes); + Write(&chunk,mesh->mNumVertices); + Write(&chunk,mesh->mNumFaces); + Write(&chunk,mesh->mNumBones); + Write(&chunk,mesh->mMaterialIndex); // first of all, write bits for all existent vertex components unsigned int c = 0; @@ -397,25 +392,25 @@ namespace Assimp { } c |= ASSBIN_MESH_HAS_COLOR(n); } - chunk.Write(c); + Write(&chunk,c); aiVector3D minVec, maxVec; if (mesh->mVertices) { if (shortened) { - chunk.WriteBounds(mesh->mVertices,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mVertices,1,12*mesh->mNumVertices); } if (mesh->mNormals) { if (shortened) { - chunk.WriteBounds(mesh->mNormals,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mNormals,1,12*mesh->mNumVertices); } if (mesh->mTangents && mesh->mBitangents) { if (shortened) { - chunk.WriteBounds(mesh->mTangents,mesh->mNumVertices); - chunk.WriteBounds(mesh->mBitangents,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices); + WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices); } // else write as usual else { chunk.Write(mesh->mTangents,1,12*mesh->mNumVertices); @@ -427,7 +422,7 @@ namespace Assimp { break; if (shortened) { - chunk.WriteBounds(mesh->mColors[n],mesh->mNumVertices); + WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mColors[n],16*mesh->mNumVertices,1); } @@ -436,10 +431,10 @@ namespace Assimp { break; // write number of UV components - chunk.Write(mesh->mNumUVComponents[n]); + Write(&chunk,mesh->mNumUVComponents[n]); if (shortened) { - chunk.WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices); } // else write as usual else chunk.Write(mesh->mTextureCoords[n],12*mesh->mNumVertices,1); } @@ -464,7 +459,7 @@ namespace Assimp { hash = SuperFastHash(reinterpret_cast(&tmp),sizeof tmp,hash); } } - chunk.Write(hash); + Write(&chunk,hash); } } else // else write as usual @@ -474,13 +469,13 @@ namespace Assimp { const aiFace& f = mesh->mFaces[i]; BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff); - chunk.Write(f.mNumIndices); + Write(&chunk,f.mNumIndices); for (unsigned int a = 0; a < f.mNumIndices;++a) { if (mesh->mNumVertices < (1u<<16)) { - chunk.Write(f.mIndices[a]); + Write(&chunk,f.mIndices[a]); } - else chunk.Write(f.mIndices[a]); + else Write(&chunk,f.mIndices[a]); } } } @@ -499,12 +494,12 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY ); - chunk.Write(prop->mKey); - chunk.Write(prop->mSemantic); - chunk.Write(prop->mIndex); + Write(&chunk,prop->mKey); + Write(&chunk,prop->mSemantic); + Write(&chunk,prop->mIndex); - chunk.Write(prop->mDataLength); - chunk.Write((unsigned int)prop->mType); + Write(&chunk,prop->mDataLength); + Write(&chunk,(unsigned int)prop->mType); chunk.Write(prop->mData,1,prop->mDataLength); } @@ -513,7 +508,7 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL); - chunk.Write(mat->mNumProperties); + Write(&chunk,mat->mNumProperties); for (unsigned int i = 0; i < mat->mNumProperties;++i) { WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]); } @@ -524,30 +519,30 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM ); - chunk.Write(nd->mNodeName); - chunk.Write(nd->mNumPositionKeys); - chunk.Write(nd->mNumRotationKeys); - chunk.Write(nd->mNumScalingKeys); - chunk.Write(nd->mPreState); - chunk.Write(nd->mPostState); + Write(&chunk,nd->mNodeName); + Write(&chunk,nd->mNumPositionKeys); + Write(&chunk,nd->mNumRotationKeys); + Write(&chunk,nd->mNumScalingKeys); + Write(&chunk,nd->mPreState); + Write(&chunk,nd->mPostState); if (nd->mPositionKeys) { if (shortened) { - chunk.WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys); } // else write as usual else chunk.Write(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey)); } if (nd->mRotationKeys) { if (shortened) { - chunk.WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys); } // else write as usual else chunk.Write(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey)); } if (nd->mScalingKeys) { if (shortened) { - chunk.WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys); } // else write as usual else chunk.Write(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey)); @@ -560,10 +555,10 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION ); - chunk.Write (anim->mName); - chunk.Write (anim->mDuration); - chunk.Write (anim->mTicksPerSecond); - chunk.Write(anim->mNumChannels); + Write(&chunk,anim->mName); + Write(&chunk,anim->mDuration); + Write(&chunk,anim->mTicksPerSecond); + Write(&chunk,anim->mNumChannels); for (unsigned int a = 0; a < anim->mNumChannels;++a) { const aiNodeAnim* nd = anim->mChannels[a]; @@ -576,22 +571,22 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT ); - chunk.Write(l->mName); - chunk.Write(l->mType); + Write(&chunk,l->mName); + Write(&chunk,l->mType); if (l->mType != aiLightSource_DIRECTIONAL) { - chunk.Write(l->mAttenuationConstant); - chunk.Write(l->mAttenuationLinear); - chunk.Write(l->mAttenuationQuadratic); + Write(&chunk,l->mAttenuationConstant); + Write(&chunk,l->mAttenuationLinear); + Write(&chunk,l->mAttenuationQuadratic); } - chunk.Write((const aiVector3D&)l->mColorDiffuse); - chunk.Write((const aiVector3D&)l->mColorSpecular); - chunk.Write((const aiVector3D&)l->mColorAmbient); + Write(&chunk,(const aiVector3D&)l->mColorDiffuse); + Write(&chunk,(const aiVector3D&)l->mColorSpecular); + Write(&chunk,(const aiVector3D&)l->mColorAmbient); if (l->mType == aiLightSource_SPOT) { - chunk.Write(l->mAngleInnerCone); - chunk.Write(l->mAngleOuterCone); + Write(&chunk,l->mAngleInnerCone); + Write(&chunk,l->mAngleOuterCone); } } @@ -601,14 +596,14 @@ namespace Assimp { { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA ); - chunk.Write(cam->mName); - chunk.Write(cam->mPosition); - chunk.Write(cam->mLookAt); - chunk.Write(cam->mUp); - chunk.Write(cam->mHorizontalFOV); - chunk.Write(cam->mClipPlaneNear); - chunk.Write(cam->mClipPlaneFar); - chunk.Write(cam->mAspect); + Write(&chunk,cam->mName); + Write(&chunk,cam->mPosition); + Write(&chunk,cam->mLookAt); + Write(&chunk,cam->mUp); + Write(&chunk,cam->mHorizontalFOV); + Write(&chunk,cam->mClipPlaneNear); + Write(&chunk,cam->mClipPlaneFar); + Write(&chunk,cam->mAspect); } // ----------------------------------------------------------------------------------- @@ -617,13 +612,13 @@ namespace Assimp { AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE ); // basic scene information - chunk.Write(scene->mFlags); - chunk.Write(scene->mNumMeshes); - chunk.Write(scene->mNumMaterials); - chunk.Write(scene->mNumAnimations); - chunk.Write(scene->mNumTextures); - chunk.Write(scene->mNumLights); - chunk.Write(scene->mNumCameras); + Write(&chunk,scene->mFlags); + Write(&chunk,scene->mNumMeshes); + Write(&chunk,scene->mNumMaterials); + Write(&chunk,scene->mNumAnimations); + Write(&chunk,scene->mNumTextures); + Write(&chunk,scene->mNumLights); + Write(&chunk,scene->mNumCameras); // write node graph WriteBinaryNode( &chunk, scene->mRootNode ); From 61ecff3474afa5f811db6d6247b260aa0fe8df08 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:30:20 +0200 Subject: [PATCH 32/34] missed one 32/64 type conversion --- code/AssbinExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index bca9a3975..9322f5047 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -161,7 +161,7 @@ inline size_t Write(IOStream * stream, const aiQuaternion& v) template <> inline size_t Write(IOStream * stream, const aiVertexWeight& v) { - uint32_t t = Write(stream,v.mVertexId); + size_t t = Write(stream,v.mVertexId); return t+Write(stream,v.mWeight); } From c3977bd1320f87c5a070f6e6b4c91653afb5662e Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 09:32:00 +0200 Subject: [PATCH 33/34] unify data types --- code/AssbinExporter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 9322f5047..0acf5c25e 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -223,7 +223,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) uint8_t* buffer; uint32_t magic; IOStream * container; - uint32_t cur_size, cursor, initial; + size_t cur_size, cursor, initial; private: // ------------------------------------------------------------------- From 58861542472aa3920d2a7dbd136d6712fe2183f6 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Thu, 7 Aug 2014 11:30:44 +0200 Subject: [PATCH 34/34] tweaks according to the comments of kimkulling --- code/AssbinExporter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/AssbinExporter.cpp b/code/AssbinExporter.cpp index 0acf5c25e..2a39a5be3 100644 --- a/code/AssbinExporter.cpp +++ b/code/AssbinExporter.cpp @@ -96,6 +96,7 @@ inline size_t Write(IOStream * stream, const unsigned int& w) template <> inline size_t Write(IOStream * stream, const uint16_t& w) { + BOOST_STATIC_ASSERT(sizeof(uint16_t)==2); stream->Write(&w,2,1); return 2; } @@ -245,7 +246,7 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) public: AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096) - : initial(initial), buffer(NULL), cur_size(0), cursor(0), container(container), magic(magic) + : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial) { } @@ -663,10 +664,9 @@ inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size) } public: - AssbinExport() + AssbinExport() + : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters { - shortened = false; - compressed = false; } // -----------------------------------------------------------------------------------