aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd
diff options
context:
space:
mode:
authorMarijn Tamis <[email protected]>2018-05-03 18:22:48 +0200
committerMarijn Tamis <[email protected]>2018-05-03 18:22:48 +0200
commitca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch)
treeb06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd
parentForced rename of platform folders in cmake dir. Git didn't pick this up before. (diff)
downloadnvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.tar.xz
nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.zip
NvCloth 1.1.4 Release. (24070740)
Diffstat (limited to 'NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd')
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt76
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp951
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp172
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp378
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp352
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp514
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h208
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp1415
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc51
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp113
-rw-r--r--NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h21
11 files changed, 4251 insertions, 0 deletions
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt
new file mode 100644
index 0000000..cb78942
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt
@@ -0,0 +1,76 @@
+# Open Asset Import Library (assimp)
+# ----------------------------------------------------------------------
+#
+# Copyright (c) 2006-2017, 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.
+#
+#----------------------------------------------------------------------
+cmake_minimum_required( VERSION 2.6 )
+
+INCLUDE_DIRECTORIES(
+ ${Assimp_SOURCE_DIR}/include
+ ${Assimp_SOURCE_DIR}/code
+)
+
+LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${Assimp_BINARY_DIR}/lib )
+
+ADD_EXECUTABLE( assimp_cmd
+ assimp_cmd.rc
+ CompareDump.cpp
+ ImageExtractor.cpp
+ Main.cpp
+ Main.h
+ resource.h
+ WriteDumb.cpp
+ Info.cpp
+ Export.cpp
+)
+
+SET_PROPERTY(TARGET assimp_cmd PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
+
+IF( WIN32 )
+ ADD_CUSTOM_COMMAND(TARGET assimp_cmd
+ PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:assimp> $<TARGET_FILE_DIR:assimp_cmd>
+ MAIN_DEPENDENCY assimp)
+ENDIF( WIN32 )
+
+TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} )
+SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES
+ OUTPUT_NAME assimp
+)
+
+INSTALL( TARGETS assimp_cmd
+ DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-bin
+)
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp
new file mode 100644
index 0000000..2db11ef
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp
@@ -0,0 +1,951 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 CompareDump.cpp
+ * @brief Implementation of the 'assimp cmpdmp', which compares
+ * two model dumps for equality. It plays an important role
+ * in the regression test suite.
+ */
+
+#include "Main.h"
+const char* AICMD_MSG_CMPDUMP_HELP =
+"assimp cmpdump <actual> <expected>\n"
+"\tCompare two short dumps produced with \'assimp dump <..> -s\' for equality.\n"
+;
+
+#include "../../code/assbin_chunks.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+#include "generic_inserter.hpp"
+#include <map>
+#include <deque>
+#include <stack>
+#include <sstream>
+#include <iostream>
+#include "../../include/assimp/ai_assert.h"
+
+// get << for aiString
+template <typename char_t, typename traits_t>
+void mysprint(std::basic_ostream<char_t, traits_t>& os, const aiString& vec) {
+ os << "[length: \'" << std::dec << vec.length << "\' content: \'" << vec.data << "\']";
+}
+
+template <typename char_t, typename traits_t>
+std::basic_ostream<char_t, traits_t>& operator<< (std::basic_ostream<char_t, traits_t>& os, const aiString& vec) {
+ return generic_inserter(mysprint<char_t,traits_t>, os, vec);
+}
+
+class sliced_chunk_iterator;
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/// @class compare_fails_exception
+///
+/// @brief Sentinel exception to return quickly from deeply nested control paths
+////////////////////////////////////////////////////////////////////////////////////////////////////
+class compare_fails_exception : public virtual std::exception {
+public:
+
+ enum {MAX_ERR_LEN = 4096};
+
+ /* public c'tors */
+ compare_fails_exception(const char* msg) {
+ strncpy(mywhat,msg,MAX_ERR_LEN-1);
+ strcat(mywhat,"\n");
+ }
+
+ /* public member functions */
+ const char* what() const throw() {
+ return mywhat;
+ }
+
+private:
+
+ char mywhat[MAX_ERR_LEN+1];
+};
+
+
+#define MY_FLT_EPSILON 1e-1f
+#define MY_DBL_EPSILON 1e-1
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/// @class comparer_context
+///
+/// @brief Record our way through the files to be compared and dump useful information if we fail.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+class comparer_context {
+ friend class sliced_chunk_iterator;
+
+public:
+
+ /* construct given two file handles to compare */
+ comparer_context(FILE* actual,FILE* expect)
+ : actual(actual)
+ , expect(expect)
+ , cnt_chunks(0)
+ {
+ ai_assert(actual);
+ ai_assert(expect);
+
+ fseek(actual,0,SEEK_END);
+ lengths.push(std::make_pair(static_cast<uint32_t>(ftell(actual)),0));
+ fseek(actual,0,SEEK_SET);
+
+ history.push_back(HistoryEntry("---",PerChunkCounter()));
+ }
+
+public:
+
+
+ /* set new scope */
+ void push_elem(const char* msg) {
+ const std::string s = msg;
+
+ PerChunkCounter::const_iterator it = history.back().second.find(s);
+ if(it != history.back().second.end()) {
+ ++history.back().second[s];
+ }
+ else history.back().second[s] = 0;
+
+ history.push_back(HistoryEntry(s,PerChunkCounter()));
+ debug_trace.push_back("PUSH " + s);
+ }
+
+ /* leave current scope */
+ void pop_elem() {
+ ai_assert(history.size());
+ debug_trace.push_back("POP "+ history.back().first);
+ history.pop_back();
+ }
+
+
+ /* push current chunk length and start offset on top of stack */
+ void push_length(uint32_t nl, uint32_t start) {
+ lengths.push(std::make_pair(nl,start));
+ ++cnt_chunks;
+ }
+
+ /* pop the chunk length stack */
+ void pop_length() {
+ ai_assert(lengths.size());
+ lengths.pop();
+ }
+
+ /* access the current chunk length */
+ uint32_t get_latest_chunk_length() {
+ ai_assert(lengths.size());
+ return lengths.top().first;
+ }
+
+ /* access the current chunk start offset */
+ uint32_t get_latest_chunk_start() {
+ ai_assert(lengths.size());
+ return lengths.top().second;
+ }
+
+ /* total number of chunk headers passed so far*/
+ uint32_t get_num_chunks() {
+ return cnt_chunks;
+ }
+
+
+ /* get ACTUAL file desc. != NULL */
+ FILE* get_actual() const {
+ return actual;
+ }
+
+ /* get EXPECT file desc. != NULL */
+ FILE* get_expect() const {
+ return expect;
+ }
+
+
+ /* compare next T from both streams, name occurs in error messages */
+ template<typename T> T cmp(const std::string& name) {
+ T a,e;
+ read(a,e);
+
+ if(a != e) {
+ std::stringstream ss;
+ failure((ss<< "Expected " << e << ", but actual is " << a,
+ ss.str()),name);
+ }
+ // std::cout << name << " " << std::hex << a << std::endl;
+ return a;
+ }
+
+ /* compare next num T's from both streams, name occurs in error messages */
+ template<typename T> void cmp(size_t num,const std::string& name) {
+ for(size_t n = 0; n < num; ++n) {
+ std::stringstream ss;
+ cmp<T>((ss<<name<<"["<<n<<"]",ss.str()));
+ // std::cout << name << " " << std::hex << a << std::endl;
+ }
+ }
+
+ /* Bounds of an aiVector3D array (separate function
+ * because partial specializations of member functions are illegal--)*/
+ template<typename T> void cmp_bounds(const std::string& name) {
+ cmp<T> (name+".<minimum-value>");
+ cmp<T> (name+".<maximum-value>");
+ }
+
+private:
+
+ /* Report failure */
+ AI_WONT_RETURN void failure(const std::string& err, const std::string& name) AI_WONT_RETURN_SUFFIX {
+ std::stringstream ss;
+ throw compare_fails_exception((ss
+ << "Files are different at "
+ << history.back().first
+ << "."
+ << name
+ << ".\nError is: "
+ << err
+ << ".\nCurrent position in scene hierarchy is "
+ << print_hierarchy(),ss.str().c_str()
+ ));
+ }
+
+ /** print our 'stack' */
+ std::string print_hierarchy() {
+ std::stringstream ss;
+ ss << "\n";
+
+ const char* last = history.back().first.c_str();
+ std::string pad;
+
+ for(ChunkHistory::reverse_iterator rev = history.rbegin(),
+ end = history.rend(); rev != end; ++rev, pad += " ")
+ {
+ ss << pad << (*rev).first << "(Index: " << (*rev).second[last] << ")" << "\n";
+ last = (*rev).first.c_str();
+ }
+
+ ss << std::endl << "Debug trace: "<< "\n";
+ for (std::vector<std::string>::const_iterator it = debug_trace.begin(); it != debug_trace.end(); ++it) {
+ ss << *it << "\n";
+ }
+ ss << std::flush;
+
+ return ss.str();
+ }
+
+
+ /* read from both streams at the same time */
+ template <typename T> void read(T& filla,T& fille) {
+ if(1 != fread(&filla,sizeof(T),1,actual)) {
+ EOFActual();
+ }
+ if(1 != fread(&fille,sizeof(T),1,expect)) {
+ EOFExpect();
+ }
+ }
+
+private:
+
+ void EOFActual() {
+ std::stringstream ss;
+ throw compare_fails_exception((ss
+ << "Unexpected EOF reading ACTUAL.\nCurrent position in scene hierarchy is "
+ << print_hierarchy(),ss.str().c_str()
+ ));
+ }
+
+ void EOFExpect() {
+ std::stringstream ss;
+ throw compare_fails_exception((ss
+ << "Unexpected EOF reading EXPECT.\nCurrent position in scene hierarchy is "
+ << print_hierarchy(),ss.str().c_str()
+ ));
+ }
+
+
+ FILE *const actual, *const expect;
+
+ typedef std::map<std::string,unsigned int> PerChunkCounter;
+ typedef std::pair<std::string,PerChunkCounter> HistoryEntry;
+
+ typedef std::deque<HistoryEntry> ChunkHistory;
+ ChunkHistory history;
+
+ std::vector<std::string> debug_trace;
+
+ typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack;
+ LengthStack lengths;
+
+ uint32_t cnt_chunks;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* specialization for aiString (it needs separate handling because its on-disk representation
+ * differs from its binary representation in memory and can't be treated as an array of n T's.*/
+template <> void comparer_context :: read<aiString>(aiString& filla,aiString& fille) {
+ uint32_t lena,lene;
+ read(lena,lene);
+
+ if(lena && 1 != fread(&filla.data,lena,1,actual)) {
+ EOFActual();
+ }
+ if(lene && 1 != fread(&fille.data,lene,1,expect)) {
+ EOFExpect();
+ }
+
+ fille.data[fille.length=static_cast<unsigned int>(lene)] = '\0';
+ filla.data[filla.length=static_cast<unsigned int>(lena)] = '\0';
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for float, uses epsilon for comparisons*/
+template<> float comparer_context :: cmp<float>(const std::string& name)
+{
+ float a,e,t;
+ read(a,e);
+
+ if((t=fabs(a-e)) > MY_FLT_EPSILON) {
+ std::stringstream ss;
+ failure((ss<< "Expected " << e << ", but actual is "
+ << a << " (delta is " << t << ")", ss.str()),name);
+ }
+ return a;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for double, uses epsilon for comparisons*/
+template<> double comparer_context :: cmp<double>(const std::string& name)
+{
+ double a,e,t;
+ read(a,e);
+
+ if((t=fabs(a-e)) > MY_DBL_EPSILON) {
+ std::stringstream ss;
+ failure((ss<< "Expected " << e << ", but actual is "
+ << a << " (delta is " << t << ")", ss.str()),name);
+ }
+ return a;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiVector3D */
+template<> aiVector3D comparer_context :: cmp<aiVector3D >(const std::string& name)
+{
+ const float x = cmp<float>(name+".x");
+ const float y = cmp<float>(name+".y");
+ const float z = cmp<float>(name+".z");
+
+ return aiVector3D(x,y,z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiColor4D */
+template<> aiColor4D comparer_context :: cmp<aiColor4D >(const std::string& name)
+{
+ const float r = cmp<float>(name+".r");
+ const float g = cmp<float>(name+".g");
+ const float b = cmp<float>(name+".b");
+ const float a = cmp<float>(name+".a");
+
+ return aiColor4D(r,g,b,a);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiQuaternion */
+template<> aiQuaternion comparer_context :: cmp<aiQuaternion >(const std::string& name)
+{
+ const float w = cmp<float>(name+".w");
+ const float x = cmp<float>(name+".x");
+ const float y = cmp<float>(name+".y");
+ const float z = cmp<float>(name+".z");
+
+ return aiQuaternion(w,x,y,z);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiQuatKey */
+template<> aiQuatKey comparer_context :: cmp<aiQuatKey >(const std::string& name)
+{
+ const double mTime = cmp<double>(name+".mTime");
+ const aiQuaternion mValue = cmp<aiQuaternion>(name+".mValue");
+
+ return aiQuatKey(mTime,mValue);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiVectorKey */
+template<> aiVectorKey comparer_context :: cmp<aiVectorKey >(const std::string& name)
+{
+ const double mTime = cmp<double>(name+".mTime");
+ const aiVector3D mValue = cmp<aiVector3D>(name+".mValue");
+
+ return aiVectorKey(mTime,mValue);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiMatrix4x4 */
+template<> aiMatrix4x4 comparer_context :: cmp<aiMatrix4x4 >(const std::string& name)
+{
+ aiMatrix4x4 res;
+ for(unsigned int i = 0; i < 4; ++i) {
+ for(unsigned int j = 0; j < 4; ++j) {
+ std::stringstream ss;
+ res[i][j] = cmp<float>(name+(ss<<".m"<<i<<j,ss.str()));
+ }
+ }
+
+ return res;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/* Specialization for aiVertexWeight */
+template<> aiVertexWeight comparer_context :: cmp<aiVertexWeight >(const std::string& name)
+{
+ const unsigned int mVertexId = cmp<unsigned int>(name+".mVertexId");
+ const float mWeight = cmp<float>(name+".mWeight");
+
+ return aiVertexWeight(mVertexId,mWeight);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/// @class sliced_chunk_iterator
+///
+/// @brief Helper to iterate easily through corresponding chunks of two dumps simultaneously.
+///
+/// Not a *real* iterator, doesn't fully conform to the isocpp iterator spec
+////////////////////////////////////////////////////////////////////////////////////////////////////
+class sliced_chunk_iterator {
+
+ friend class sliced_chunk_reader;
+ sliced_chunk_iterator(comparer_context& ctx, long end)
+ : ctx(ctx)
+ , endit(false)
+ , next(std::numeric_limits<long>::max())
+ , end(end)
+ {
+ load_next();
+ }
+
+public:
+
+ ~sliced_chunk_iterator() {
+ fseek(ctx.get_actual(),end,SEEK_SET);
+ fseek(ctx.get_expect(),end,SEEK_SET);
+ }
+
+public:
+
+ /* get current chunk head */
+ typedef std::pair<uint32_t,uint32_t> Chunk;
+ const Chunk& operator*() {
+ return current;
+ }
+
+ /* get to next chunk head */
+ const sliced_chunk_iterator& operator++() {
+ cleanup();
+ load_next();
+ return *this;
+ }
+
+ /* */
+ bool is_end() const {
+ return endit;
+ }
+
+private:
+
+ /* get to the end of *this* chunk */
+ void cleanup() {
+ if(next != std::numeric_limits<long>::max()) {
+ fseek(ctx.get_actual(),next,SEEK_SET);
+ fseek(ctx.get_expect(),next,SEEK_SET);
+
+ ctx.pop_length();
+ }
+ }
+
+ /* advance to the next chunk */
+ void load_next() {
+
+ Chunk actual;
+ size_t res=0;
+
+ const long cur = ftell(ctx.get_expect());
+ if(end-cur<8) {
+ current = std::make_pair(0u,0u);
+ endit = true;
+ return;
+ }
+
+ res|=fread(&current.first,4,1,ctx.get_expect());
+ res|=fread(&current.second,4,1,ctx.get_expect()) <<1u;
+ res|=fread(&actual.first,4,1,ctx.get_actual()) <<2u;
+ res|=fread(&actual.second,4,1,ctx.get_actual()) <<3u;
+
+ if(res!=0xf) {
+ ctx.failure("IO Error reading chunk head, dumps are malformed","<ChunkHead>");
+ }
+
+ if (current.first != actual.first) {
+ std::stringstream ss;
+ ctx.failure((ss
+ <<"Chunk headers do not match. EXPECT: "
+ << std::hex << current.first
+ <<" ACTUAL: "
+ << /*std::hex */actual.first,
+ ss.str()),
+ "<ChunkHead>");
+ }
+
+ if (current.first != actual.first) {
+ std::stringstream ss;
+ ctx.failure((ss
+ <<"Chunk lengths do not match. EXPECT: "
+ <<current.second
+ <<" ACTUAL: "
+ << actual.second,
+ ss.str()),
+ "<ChunkHead>");
+ }
+
+ next = cur+current.second+8;
+ ctx.push_length(current.second,cur+8);
+ }
+
+ comparer_context& ctx;
+ Chunk current;
+ bool endit;
+ long next,end;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/// @class sliced_chunk_reader
+///
+/// @brief Helper to iterate easily through corresponding chunks of two dumps simultaneously.
+////////////////////////////////////////////////////////////////////////////////////////////////////
+class sliced_chunk_reader {
+public:
+
+ //
+ sliced_chunk_reader(comparer_context& ctx)
+ : ctx(ctx)
+ {}
+
+ //
+ ~sliced_chunk_reader() {
+ }
+
+public:
+
+ sliced_chunk_iterator begin() const {
+ return sliced_chunk_iterator(ctx,ctx.get_latest_chunk_length()+
+ ctx.get_latest_chunk_start());
+ }
+
+private:
+
+ comparer_context& ctx;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+/// @class scoped_chunk
+///
+/// @brief Utility to simplify usage of comparer_context.push_elem/pop_elem
+////////////////////////////////////////////////////////////////////////////////////////////////////
+class scoped_chunk {
+public:
+
+ //
+ scoped_chunk(comparer_context& ctx,const char* msg)
+ : ctx(ctx)
+ {
+ ctx.push_elem(msg);
+ }
+
+ //
+ ~scoped_chunk()
+ {
+ ctx.pop_elem();
+ }
+
+private:
+
+ comparer_context& ctx;
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyMaterialProperty(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiMaterialProperty");
+
+ comp.cmp<aiString>("mKey");
+ comp.cmp<uint32_t>("mSemantic");
+ comp.cmp<uint32_t>("mIndex");
+ const uint32_t length = comp.cmp<uint32_t>("mDataLength");
+ const aiPropertyTypeInfo type = static_cast<aiPropertyTypeInfo>(
+ comp.cmp<uint32_t>("mType"));
+
+ switch (type)
+ {
+ case aiPTI_Float:
+ comp.cmp<float>(length/4,"mData");
+ break;
+
+ case aiPTI_String:
+ comp.cmp<aiString>("mData");
+ break;
+
+ case aiPTI_Integer:
+ comp.cmp<uint32_t>(length/4,"mData");
+ break;
+
+ case aiPTI_Buffer:
+ comp.cmp<uint8_t>(length,"mData");
+ break;
+
+ default:
+ break;
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyMaterial(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiMaterial");
+
+ comp.cmp<uint32_t>("aiMaterial::mNumProperties");
+ sliced_chunk_reader reader(comp);
+ for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) {
+ if ((*it).first == ASSBIN_CHUNK_AIMATERIALPROPERTY) {
+ CompareOnTheFlyMaterialProperty(comp);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyBone(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiBone");
+ comp.cmp<aiString>("mName");
+ comp.cmp<uint32_t>("mNumWeights");
+ comp.cmp<aiMatrix4x4>("mOffsetMatrix");
+
+ comp.cmp_bounds<aiVertexWeight>("mWeights");
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyNodeAnim(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiNodeAnim");
+
+ comp.cmp<aiString>("mNodeName");
+ comp.cmp<uint32_t>("mNumPositionKeys");
+ comp.cmp<uint32_t>("mNumRotationKeys");
+ comp.cmp<uint32_t>("mNumScalingKeys");
+ comp.cmp<uint32_t>("mPreState");
+ comp.cmp<uint32_t>("mPostState");
+
+ comp.cmp_bounds<aiVectorKey>("mPositionKeys");
+ comp.cmp_bounds<aiQuatKey>("mRotationKeys");
+ comp.cmp_bounds<aiVectorKey>("mScalingKeys");
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyMesh(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiMesh");
+
+ comp.cmp<uint32_t>("mPrimitiveTypes");
+ comp.cmp<uint32_t>("mNumVertices");
+ const uint32_t nf = comp.cmp<uint32_t>("mNumFaces");
+ comp.cmp<uint32_t>("mNumBones");
+ comp.cmp<uint32_t>("mMaterialIndex");
+
+ const uint32_t present = comp.cmp<uint32_t>("<vertex-components-present>");
+ if(present & ASSBIN_MESH_HAS_POSITIONS) {
+ comp.cmp_bounds<aiVector3D>("mVertices");
+ }
+
+ if(present & ASSBIN_MESH_HAS_NORMALS) {
+ comp.cmp_bounds<aiVector3D>("mNormals");
+ }
+
+ if(present & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) {
+ comp.cmp_bounds<aiVector3D>("mTangents");
+ comp.cmp_bounds<aiVector3D>("mBitangents");
+ }
+
+ for(unsigned int i = 0; present & ASSBIN_MESH_HAS_COLOR(i); ++i) {
+ std::stringstream ss;
+ comp.cmp_bounds<aiColor4D>((ss<<"mColors["<<i<<"]",ss.str()));
+ }
+
+ for(unsigned int i = 0; present & ASSBIN_MESH_HAS_TEXCOORD(i); ++i) {
+ std::stringstream ss;
+ comp.cmp<uint32_t>((ss<<"mNumUVComponents["<<i<<"]",ss.str()));
+ comp.cmp_bounds<aiVector3D>((ss.clear(),ss<<"mTextureCoords["<<i<<"]",ss.str()));
+ }
+
+ for(unsigned int i = 0; i< ((nf+511)/512); ++i) {
+ std::stringstream ss;
+ comp.cmp<uint32_t>((ss<<"mFaces["<<i*512<<"-"<<std::min(static_cast<
+ uint32_t>((i+1)*512),nf)<<"]",ss.str()));
+ }
+
+ sliced_chunk_reader reader(comp);
+ for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) {
+ if ((*it).first == ASSBIN_CHUNK_AIBONE) {
+ CompareOnTheFlyBone(comp);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyCamera(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiCamera");
+
+ comp.cmp<aiString>("mName");
+
+ comp.cmp<aiVector3D>("mPosition");
+ comp.cmp<aiVector3D>("mLookAt");
+ comp.cmp<aiVector3D>("mUp");
+
+ comp.cmp<float>("mHorizontalFOV");
+ comp.cmp<float>("mClipPlaneNear");
+ comp.cmp<float>("mClipPlaneFar");
+ comp.cmp<float>("mAspect");
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyLight(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiLight");
+
+ comp.cmp<aiString>("mName");
+ const aiLightSourceType type = static_cast<aiLightSourceType>(
+ comp.cmp<uint32_t>("mType"));
+
+ if(type!=aiLightSource_DIRECTIONAL) {
+ comp.cmp<float>("mAttenuationConstant");
+ comp.cmp<float>("mAttenuationLinear");
+ comp.cmp<float>("mAttenuationQuadratic");
+ }
+
+ comp.cmp<aiVector3D>("mColorDiffuse");
+ comp.cmp<aiVector3D>("mColorSpecular");
+ comp.cmp<aiVector3D>("mColorAmbient");
+
+ if(type==aiLightSource_SPOT) {
+ comp.cmp<float>("mAngleInnerCone");
+ comp.cmp<float>("mAngleOuterCone");
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyAnimation(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiAnimation");
+
+ comp.cmp<aiString>("mName");
+ comp.cmp<double>("mDuration");
+ comp.cmp<double>("mTicksPerSecond");
+ comp.cmp<uint32_t>("mNumChannels");
+
+ sliced_chunk_reader reader(comp);
+ for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) {
+ if ((*it).first == ASSBIN_CHUNK_AINODEANIM) {
+ CompareOnTheFlyNodeAnim(comp);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyTexture(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiTexture");
+
+ const uint32_t w = comp.cmp<uint32_t>("mWidth");
+ const uint32_t h = comp.cmp<uint32_t>("mHeight");
+ (void)w; (void)h;
+ comp.cmp<char>("achFormatHint[0]");
+ comp.cmp<char>("achFormatHint[1]");
+ comp.cmp<char>("achFormatHint[2]");
+ comp.cmp<char>("achFormatHint[3]");
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyNode(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiNode");
+ comp.cmp<aiString>("mName");
+ comp.cmp<aiMatrix4x4>("mTransformation");
+ comp.cmp<uint32_t>("mNumChildren");
+ comp.cmp<uint32_t>(comp.cmp<uint32_t>("mNumMeshes"),"mMeshes");
+
+ sliced_chunk_reader reader(comp);
+ for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) {
+ if ((*it).first == ASSBIN_CHUNK_AINODE) {
+ CompareOnTheFlyNode(comp);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFlyScene(comparer_context& comp) {
+ scoped_chunk chunk(comp,"aiScene");
+
+ comp.cmp<uint32_t>("mFlags");
+ comp.cmp<uint32_t>("mNumMeshes");
+ comp.cmp<uint32_t>("mNumMaterials");
+ comp.cmp<uint32_t>("mNumAnimations");
+ comp.cmp<uint32_t>("mNumTextures");
+ comp.cmp<uint32_t>("mNumLights");
+ comp.cmp<uint32_t>("mNumCameras");
+
+ sliced_chunk_reader reader(comp);
+ for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) {
+ if ((*it).first == ASSBIN_CHUNK_AIMATERIAL) {
+ CompareOnTheFlyMaterial(comp);
+ }
+ else if ((*it).first == ASSBIN_CHUNK_AITEXTURE) {
+ CompareOnTheFlyTexture(comp);
+ }
+ else if ((*it).first == ASSBIN_CHUNK_AIMESH) {
+ CompareOnTheFlyMesh(comp);
+ }
+ else if ((*it).first == ASSBIN_CHUNK_AIANIMATION) {
+ CompareOnTheFlyAnimation(comp);
+ }
+ else if ((*it).first == ASSBIN_CHUNK_AICAMERA) {
+ CompareOnTheFlyCamera(comp);
+ }
+ else if ((*it).first == ASSBIN_CHUNK_AILIGHT) {
+ CompareOnTheFlyLight(comp);
+ }
+ else if ((*it).first == ASSBIN_CHUNK_AINODE) {
+ CompareOnTheFlyNode(comp);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CompareOnTheFly(comparer_context& comp)
+{
+ sliced_chunk_reader reader(comp);
+ for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) {
+ if ((*it).first == ASSBIN_CHUNK_AISCENE) {
+ CompareOnTheFlyScene(comp);
+ break;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CheckHeader(comparer_context& comp)
+{
+ fseek(comp.get_actual(),ASSBIN_HEADER_LENGTH,SEEK_CUR);
+ fseek(comp.get_expect(),ASSBIN_HEADER_LENGTH,SEEK_CUR);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+int Assimp_CompareDump (const char* const* params, unsigned int num)
+{
+ // --help
+ if ((num == 1 && !strcmp( params[0], "-h")) || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
+ printf("%s",AICMD_MSG_CMPDUMP_HELP);
+ return 0;
+ }
+
+ // assimp cmpdump actual expected
+ if (num < 2) {
+ std::cout << "assimp cmpdump: Invalid number of arguments. "
+ "See \'assimp cmpdump --help\'\r\n" << std::endl;
+ return 1;
+ }
+
+ if(!strcmp(params[0],params[1])) {
+ std::cout << "assimp cmpdump: same file, same content." << std::endl;
+ return 0;
+ }
+
+ class file_ptr
+ {
+ public:
+ file_ptr(FILE *p)
+ : m_file(p)
+ {}
+ ~file_ptr()
+ {
+ if (m_file)
+ {
+ fclose(m_file);
+ m_file = NULL;
+ }
+ }
+
+ operator FILE *() { return m_file; }
+
+ private:
+ FILE *m_file;
+ };
+ file_ptr actual(fopen(params[0],"rb"));
+ if (!actual) {
+ std::cout << "assimp cmpdump: Failure reading ACTUAL data from " <<
+ params[0] << std::endl;
+ return -5;
+ }
+ file_ptr expected(fopen(params[1],"rb"));
+ if (!expected) {
+ std::cout << "assimp cmpdump: Failure reading EXPECT data from " <<
+ params[1] << std::endl;
+ return -6;
+ }
+
+ comparer_context comp(actual,expected);
+ try {
+ CheckHeader(comp);
+ CompareOnTheFly(comp);
+ }
+ catch(const compare_fails_exception& ex) {
+ printf("%s",ex.what());
+ return -1;
+ }
+ catch(...) {
+ // we don't bother checking too rigourously here, so
+ // we might end up here ...
+ std::cout << "Unknown failure, are the input files well-defined?";
+ return -3;
+ }
+
+ std::cout << "Success (totally " << std::dec << comp.get_num_chunks() <<
+ " chunks)" << std::endl;
+
+ return 0;
+}
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp
new file mode 100644
index 0000000..3752db5
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp
@@ -0,0 +1,172 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 Export.cpp
+ * @brief Implementation of the 'assimp export' utility
+ */
+
+#include "Main.h"
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+const char* AICMD_MSG_EXPORT_HELP_E =
+"assimp export <model> [<out>] [-f<h>] [common parameters]\n"
+"\t -f<h> Specify the file format. If omitted, the output format is \n"
+"\t\tderived from the file extension of the given output file \n"
+"\t[See the assimp_cmd docs for a full list of all common parameters] \n"
+;
+
+
+// -----------------------------------------------------------------------------------
+size_t GetMatchingFormat(const std::string& outf,bool byext=false)
+{
+ for(size_t i = 0, end = globalExporter->GetExportFormatCount(); i < end; ++i) {
+ const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(i);
+ if (outf == (byext ? e->fileExtension : e->id)) {
+ return i;
+ }
+ }
+ return SIZE_MAX;
+}
+
+
+// -----------------------------------------------------------------------------------
+int Assimp_Export(const char* const* params, unsigned int num)
+{
+ const char* const invalid = "assimp export: Invalid number of arguments. See \'assimp export --help\'\n";
+ if (num < 1) {
+ printf(invalid);
+ return 1;
+ }
+
+ // --help
+ if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
+ printf("%s",AICMD_MSG_EXPORT_HELP_E);
+ return 0;
+ }
+
+ std::string in = std::string(params[0]);
+ std::string out = (num > 1 ? std::string(params[1]) : "-"), outext;
+
+ //
+ const std::string::size_type s = out.find_last_of('.');
+ if (s != std::string::npos) {
+ outext = out.substr(s+1);
+ out = out.substr(0,s);
+ }
+
+ // get import flags
+ ImportData import;
+ ProcessStandardArguments(import,params+1,num-1);
+
+ // process other flags
+ std::string outf = "";
+ for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) {
+ if (!params[i]) {
+ continue;
+ }
+ if (!strncmp( params[i], "-f",2)) {
+ outf = std::string(params[i]+2);
+ }
+ else if ( !strncmp( params[i], "--format=",9)) {
+ outf = std::string(params[i]+9);
+ }
+ }
+
+ std::transform(outf.begin(),outf.end(),outf.begin(),::tolower);
+
+ // convert the output format to a format id
+ size_t outfi = GetMatchingFormat(outf);
+ if (outfi == SIZE_MAX) {
+ if (outf.length()) {
+ printf("assimp export: warning, format id \'%s\' is unknown\n",outf.c_str());
+ }
+
+ // retry to see if we know it as file extension
+ outfi = GetMatchingFormat(outf,true);
+ if (outfi == SIZE_MAX) {
+ // retry to see if we know the file extension of the output file
+ outfi = GetMatchingFormat(outext,true);
+
+ if (outfi == SIZE_MAX) {
+ // still no match -> failure
+ printf("assimp export: no output format specified and I failed to guess it\n");
+ return -23;
+ }
+ }
+ else {
+ outext = outf;
+ }
+ }
+
+ // if no output file is specified, take the file name from input file
+ if (out[0] == '-') {
+ std::string::size_type s = in.find_last_of('.');
+ if (s == std::string::npos) {
+ s = in.length();
+ }
+
+ out = in.substr(0,s);
+ }
+
+ const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(outfi);
+ printf("assimp export: select file format: \'%s\' (%s)\n",e->id,e->description);
+
+ // import the model
+ const aiScene* scene = ImportModel(import,in);
+ if (!scene) {
+ return -39;
+ }
+
+ // derive the final file name
+ out += "."+outext;
+
+ // and call the export routine
+ if(!ExportModel(scene, import, out,e->id)) {
+ return -25;
+ }
+ printf("assimp export: wrote output file: %s\n",out.c_str());
+ return 0;
+}
+
+#endif // no export
+
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp
new file mode 100644
index 0000000..691f629
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp
@@ -0,0 +1,378 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 ImageExtractor.cpp
+ * @brief Implementation of the 'assimp extract' utility
+ */
+
+#include "Main.h"
+#include <../code/fast_atof.h>
+#include <../code/StringComparison.h>
+
+const char* AICMD_MSG_DUMP_HELP_E =
+"assimp extract <model> [<out>] [-t<n>] [-f<fmt>] [-ba] [-s] [common parameters]\n"
+"\t -ba Writes BMP's with alpha channel\n"
+"\t -t<n> Zero-based index of the texture to be extracted \n"
+"\t -f<f> Specify the file format if <out> is omitted \n"
+"\t[See the assimp_cmd docs for a full list of all common parameters] \n"
+"\t -cfast Fast post processing preset, runs just a few important steps \n"
+"\t -cdefault Default post processing: runs all recommended steps\n"
+"\t -cfull Fires almost all post processing steps \n"
+;
+
+#define AI_EXTRACT_WRITE_BMP_ALPHA 0x1
+#include <assimp/Compiler/pushpack1.h>
+
+// -----------------------------------------------------------------------------------
+// Data structure for the first header of a BMP
+struct BITMAPFILEHEADER
+{
+ uint16_t bfType ;
+ uint32_t bfSize;
+ uint16_t bfReserved1 ;
+ uint16_t bfReserved2;
+ uint32_t bfOffBits;
+} PACK_STRUCT;
+
+// -----------------------------------------------------------------------------------
+// Data structure for the second header of a BMP
+struct BITMAPINFOHEADER
+{
+ int32_t biSize;
+ int32_t biWidth;
+ int32_t biHeight;
+ int16_t biPlanes;
+ int16_t biBitCount;
+ uint32_t biCompression;
+ int32_t biSizeImage;
+ int32_t biXPelsPerMeter;
+ int32_t biYPelsPerMeter;
+ int32_t biClrUsed;
+ int32_t biClrImportant;
+
+ // pixel data follows header
+} PACK_STRUCT;
+
+// -----------------------------------------------------------------------------------
+// Data structure for the header of a TGA
+struct TGA_HEADER
+{
+ uint8_t identsize; // size of ID field that follows 18 byte header (0 usually)
+ uint8_t colourmaptype; // type of colour map 0=none, 1=has palette
+ uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
+
+ uint16_t colourmapstart; // first colour map entry in palette
+ uint16_t colourmaplength; // number of colours in palette
+ uint8_t colourmapbits; // number of bits per palette entry 15,16,24,32
+
+ uint16_t xstart; // image x origin
+ uint16_t ystart; // image y origin
+ uint16_t width; // image width in pixels
+ uint16_t height; // image height in pixels
+ uint8_t bits; // image bits per pixel 8,16,24,32
+ uint8_t descriptor; // image descriptor bits (vh flip bits)
+
+ // pixel data follows header
+} PACK_STRUCT;
+
+
+#include <assimp/Compiler/poppack1.h>
+
+// -----------------------------------------------------------------------------------
+// Save a texture as bitmap
+int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int height, bool SaveAlpha = false)
+{
+ if (!file || !data) {
+ return 1;
+ }
+
+ const unsigned int numc = (SaveAlpha ? 4 : 3);
+ unsigned char* buffer = new unsigned char[width*height*numc];
+
+ for (unsigned int y = 0; y < height; ++y) {
+ for (unsigned int x = 0; x < width; ++x) {
+
+ unsigned char* s = &buffer[(y*width+x) * numc];
+ const aiTexel* t = &data [ y*width+x];
+ s[0] = t->b;
+ s[1] = t->g;
+ s[2] = t->r;
+ if (4 == numc)
+ s[3] = t->a;
+ }
+ }
+
+ BITMAPFILEHEADER header;
+ header.bfType = 'B' | (int('M') << 8u);
+ header.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
+ header.bfSize = header.bfOffBits+width*height*numc;
+ header.bfReserved1 = header.bfReserved2 = 0;
+
+ fwrite(&header,sizeof(BITMAPFILEHEADER),1,file);
+
+ BITMAPINFOHEADER info;
+ info.biSize = 40;
+ info.biWidth = width;
+ info.biHeight = height;
+ info.biPlanes = 1;
+ info.biBitCount = numc<<3;
+ info.biCompression = 0;
+ info.biSizeImage = width*height*numc;
+ info.biXPelsPerMeter = 1; // dummy
+ info.biYPelsPerMeter = 1; // dummy
+ info.biClrUsed = 0;
+ info.biClrImportant = 0;
+
+ fwrite(&info,sizeof(BITMAPINFOHEADER),1,file);
+
+ unsigned char* temp = buffer+info.biSizeImage;
+ const unsigned int row = width*numc;
+
+ for (int y = 0; temp -= row,y < info.biHeight;++y) {
+ fwrite(temp,row,1,file);
+ }
+
+ // delete the buffer
+ delete[] buffer;
+ return 0;
+}
+
+// -----------------------------------------------------------------------------------
+// Save a texture as tga
+int SaveAsTGA (FILE* file, const aiTexel* data, unsigned int width, unsigned int height)
+{
+ if (!file || !data) {
+ return 1;
+ }
+
+ TGA_HEADER head;
+ memset(&head, 0, sizeof(head));
+ head.bits = 32;
+ head.height = (uint16_t)height;
+ head.width = (uint16_t)width;
+ head.descriptor |= (1u<<5);
+
+ head.imagetype = 2; // actually it's RGBA
+ fwrite(&head,sizeof(TGA_HEADER),1,file);
+
+ for (unsigned int y = 0; y < height; ++y) {
+ for (unsigned int x = 0; x < width; ++x) {
+ fwrite(data + y*width+x,4,1,file);
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------------
+// Do the texture import for a given aiTexture
+int DoExport(const aiTexture* tx, FILE* p, const std::string& extension,
+ unsigned int flags)
+{
+ // export the image to the appropriate decoder
+ if (extension == "bmp") {
+ SaveAsBMP(p,tx->pcData,tx->mWidth,tx->mHeight,
+ (0 != (flags & AI_EXTRACT_WRITE_BMP_ALPHA)));
+ }
+ else if (extension == "tga") {
+ SaveAsTGA(p,tx->pcData,tx->mWidth,tx->mHeight);
+ }
+ else {
+ printf("assimp extract: No available texture encoder found for %s\n", extension.c_str());
+ return 1;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------------------
+// Implementation of the assimp extract utility
+int Assimp_Extract (const char* const* params, unsigned int num)
+{
+ const char* const invalid = "assimp extract: Invalid number of arguments. See \'assimp extract --help\'\n";
+ if (num < 1) {
+ printf(invalid);
+ return 1;
+ }
+
+ // --help
+ if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
+ printf("%s",AICMD_MSG_DUMP_HELP_E);
+ return 0;
+ }
+
+ // asssimp extract in out [options]
+ if (num < 1) {
+ printf(invalid);
+ return 1;
+ }
+
+ std::string in = std::string(params[0]);
+ std::string out = (num > 1 ? std::string(params[1]) : "-");
+
+ // get import flags
+ ImportData import;
+ ProcessStandardArguments(import,params+1,num-1);
+
+ bool nosuffix = false;
+ unsigned int texIdx = 0xffffffff, flags = 0;
+
+ // process other flags
+ std::string extension = "bmp";
+ for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) {
+ if (!params[i]) {
+ continue;
+ }
+
+ if (!strncmp( params[i], "-f",2)) {
+ extension = std::string(params[i]+2);
+ }
+ else if ( !strncmp( params[i], "--format=",9)) {
+ extension = std::string(params[i]+9);
+ }
+ else if ( !strcmp( params[i], "--nosuffix") || !strcmp(params[i],"-s")) {
+ nosuffix = true;
+ }
+ else if ( !strncmp( params[i], "--texture=",10)) {
+ texIdx = Assimp::strtoul10(params[i]+10);
+ }
+ else if ( !strncmp( params[i], "-t",2)) {
+ texIdx = Assimp::strtoul10(params[i]+2);
+ }
+ else if ( !strcmp( params[i], "-ba") || !strcmp( params[i], "--bmp-with-alpha")) {
+ flags |= AI_EXTRACT_WRITE_BMP_ALPHA;
+ }
+#if 0
+ else {
+ printf("Unknown parameter: %s\n",params[i]);
+ return 10;
+ }
+#endif
+ }
+
+ std::transform(extension.begin(),extension.end(),extension.begin(),::tolower);
+
+ if (out[0] == '-') {
+ // take file name from input file
+ std::string::size_type s = in.find_last_of('.');
+ if (s == std::string::npos)
+ s = in.length();
+
+ out = in.substr(0,s);
+ }
+
+ // take file extension from file name, if given
+ std::string::size_type s = out.find_last_of('.');
+ if (s != std::string::npos) {
+ extension = out.substr(s+1,in.length()-(s+1));
+ out = out.substr(0,s);
+ }
+
+ // import the main model
+ const aiScene* scene = ImportModel(import,in);
+ if (!scene) {
+ printf("assimp extract: Unable to load input file %s\n",in.c_str());
+ return 5;
+ }
+
+ // get the texture(s) to be exported
+ if (texIdx != 0xffffffff) {
+
+ // check whether the requested texture is existing
+ if (texIdx >= scene->mNumTextures) {
+ ::printf("assimp extract: Texture %i requested, but there are just %i textures\n",
+ texIdx, scene->mNumTextures);
+ return 6;
+ }
+ }
+ else {
+ ::printf("assimp extract: Exporting %i textures\n",scene->mNumTextures);
+ }
+
+ // now write all output textures
+ for (unsigned int i = 0; i < scene->mNumTextures;++i) {
+ if (texIdx != 0xffffffff && texIdx != i) {
+ continue;
+ }
+
+ const aiTexture* tex = scene->mTextures[i];
+ std::string out_cpy = out, out_ext = extension;
+
+ // append suffix if necessary - always if all textures are exported
+ if (!nosuffix || (texIdx == 0xffffffff)) {
+ out_cpy.append ("_img");
+ char tmp[10];
+ Assimp::ASSIMP_itoa10(tmp,i);
+
+ out_cpy.append(std::string(tmp));
+ }
+
+ // if the texture is a compressed one, we'll export
+ // it to its native file format
+ if (!tex->mHeight) {
+ printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n",
+ i,tex->achFormatHint);
+
+ // modify file extension
+ out_ext = std::string(tex->achFormatHint);
+ }
+ out_cpy.append("."+out_ext);
+
+ // open output file
+ FILE* p = ::fopen(out_cpy.c_str(),"wb");
+ if (!p) {
+ printf("assimp extract: Unable to open output file %s\n",out_cpy.c_str());
+ return 7;
+ }
+ int m;
+
+ if (!tex->mHeight) {
+ m = (1 != fwrite(tex->pcData,tex->mWidth,1,p));
+ }
+ else m = DoExport(tex,p,extension,flags);
+ ::fclose(p);
+
+ printf("assimp extract: Wrote texture %i to %s\n",i, out_cpy.c_str());
+ if (texIdx != 0xffffffff)
+ return m;
+ }
+ return 0;
+}
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp
new file mode 100644
index 0000000..d116f04
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp
@@ -0,0 +1,352 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 Info.cpp
+ * @brief Implementation of the 'assimp info' utility */
+
+#include "Main.h"
+
+const char* AICMD_MSG_INFO_HELP_E =
+"assimp info <file> [-r]\n"
+"\tPrint basic structure of a 3D model\n"
+"\t-r,--raw: No postprocessing, do a raw import\n";
+
+
+// -----------------------------------------------------------------------------------
+unsigned int CountNodes(const aiNode* root)
+{
+ unsigned int i = 0;
+ for (unsigned int a = 0; a < root->mNumChildren; ++a ) {
+ i += CountNodes(root->mChildren[a]);
+ }
+ return 1+i;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int GetMaxDepth(const aiNode* root)
+{
+ unsigned int cnt = 0;
+ for (unsigned int i = 0; i < root->mNumChildren; ++i ) {
+ cnt = std::max(cnt,GetMaxDepth(root->mChildren[i]));
+ }
+ return cnt+1;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int CountVertices(const aiScene* scene)
+{
+ unsigned int cnt = 0;
+ for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
+ cnt += scene->mMeshes[i]->mNumVertices;
+ }
+ return cnt;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int CountFaces(const aiScene* scene)
+{
+ unsigned int cnt = 0;
+ for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
+ cnt += scene->mMeshes[i]->mNumFaces;
+ }
+ return cnt;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int CountBones(const aiScene* scene)
+{
+ unsigned int cnt = 0;
+ for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
+ cnt += scene->mMeshes[i]->mNumBones;
+ }
+ return cnt;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int CountAnimChannels(const aiScene* scene)
+{
+ unsigned int cnt = 0;
+ for(unsigned int i = 0; i < scene->mNumAnimations; ++i) {
+ cnt += scene->mAnimations[i]->mNumChannels;
+ }
+ return cnt;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int GetAvgFacePerMesh(const aiScene* scene) {
+ return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountFaces(scene)/scene->mNumMeshes) : 0;
+}
+
+// -----------------------------------------------------------------------------------
+unsigned int GetAvgVertsPerMesh(const aiScene* scene) {
+ return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountVertices(scene)/scene->mNumMeshes) : 0;
+}
+
+// -----------------------------------------------------------------------------------
+void FindSpecialPoints(const aiScene* scene,const aiNode* root,aiVector3D special_points[3],const aiMatrix4x4& mat=aiMatrix4x4())
+{
+ // XXX that could be greatly simplified by using code from code/ProcessHelper.h
+ // XXX I just don't want to include it here.
+ const aiMatrix4x4 trafo = root->mTransformation*mat;
+ for(unsigned int i = 0; i < root->mNumMeshes; ++i) {
+ const aiMesh* mesh = scene->mMeshes[root->mMeshes[i]];
+
+ for(unsigned int a = 0; a < mesh->mNumVertices; ++a) {
+ aiVector3D v = trafo*mesh->mVertices[a];
+
+ special_points[0].x = std::min(special_points[0].x,v.x);
+ special_points[0].y = std::min(special_points[0].y,v.y);
+ special_points[0].z = std::min(special_points[0].z,v.z);
+
+ special_points[1].x = std::max(special_points[1].x,v.x);
+ special_points[1].y = std::max(special_points[1].y,v.y);
+ special_points[1].z = std::max(special_points[1].z,v.z);
+ }
+ }
+
+ for(unsigned int i = 0; i < root->mNumChildren; ++i) {
+ FindSpecialPoints(scene,root->mChildren[i],special_points,trafo);
+ }
+}
+
+// -----------------------------------------------------------------------------------
+void FindSpecialPoints(const aiScene* scene,aiVector3D special_points[3])
+{
+ special_points[0] = aiVector3D(1e10,1e10,1e10);
+ special_points[1] = aiVector3D(-1e10,-1e10,-1e10);
+
+ FindSpecialPoints(scene,scene->mRootNode,special_points);
+ special_points[2] = (special_points[0]+special_points[1])*(ai_real)0.5;
+}
+
+// -----------------------------------------------------------------------------------
+std::string FindPTypes(const aiScene* scene)
+{
+ bool haveit[4] = {0};
+ for(unsigned int i = 0; i < scene->mNumMeshes; ++i) {
+ const unsigned int pt = scene->mMeshes[i]->mPrimitiveTypes;
+ if (pt & aiPrimitiveType_POINT) {
+ haveit[0]=true;
+ }
+ if (pt & aiPrimitiveType_LINE) {
+ haveit[1]=true;
+ }
+ if (pt & aiPrimitiveType_TRIANGLE) {
+ haveit[2]=true;
+ }
+ if (pt & aiPrimitiveType_POLYGON) {
+ haveit[3]=true;
+ }
+ }
+ return (haveit[0]?std::string("points"):"")+(haveit[1]?"lines":"")+
+ (haveit[2]?"triangles":"")+(haveit[3]?"n-polygons":"");
+}
+
+// -----------------------------------------------------------------------------------
+void PrintHierarchy(const aiNode* root, unsigned int maxnest, unsigned int maxline,
+ unsigned int cline, unsigned int cnest=0)
+{
+ if (cline++ >= maxline || cnest >= maxnest) {
+ return;
+ }
+
+ for(unsigned int i = 0; i < cnest; ++i) {
+ printf("-- ");
+ }
+ printf("\'%s\', meshes: %u\n",root->mName.data,root->mNumMeshes);
+ for (unsigned int i = 0; i < root->mNumChildren; ++i ) {
+ PrintHierarchy(root->mChildren[i],maxnest,maxline,cline,cnest+1);
+ if(i == root->mNumChildren-1) {
+ for(unsigned int i = 0; i < cnest; ++i) {
+ printf(" ");
+ }
+ printf("<--\n");
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------------
+// Implementation of the assimp info utility to print basic file info
+int Assimp_Info (const char* const* params, unsigned int num)
+{
+ if (num < 1) {
+ printf("assimp info: Invalid number of arguments. "
+ "See \'assimp info --help\'\n");
+ return 1;
+ }
+
+ // --help
+ if (!strcmp( params[0],"-h")||!strcmp( params[0],"--help")||!strcmp( params[0],"-?") ) {
+ printf("%s",AICMD_MSG_INFO_HELP_E);
+ return 0;
+ }
+
+ // asssimp info <file> [-r]
+ if (num < 1) {
+ printf("assimp info: Invalid number of arguments. "
+ "See \'assimp info --help\'\n");
+ return 1;
+ }
+
+ const std::string in = std::string(params[0]);
+
+ // do maximum post-processing unless -r was specified
+ ImportData import;
+ import.ppFlags = num>1&&(!strcmp(params[1],"--raw")||!strcmp(params[1],"-r")) ? 0
+ : aiProcessPreset_TargetRealtime_MaxQuality;
+
+ // import the main model
+ const aiScene* scene = ImportModel(import,in);
+ if (!scene) {
+ printf("assimp info: Unable to load input file %s\n",
+ in.c_str());
+ return 5;
+ }
+
+ aiMemoryInfo mem;
+ globalImporter->GetMemoryRequirements(mem);
+
+
+ static const char* format_string =
+ "Memory consumption: %i B\n"
+ "Nodes: %i\n"
+ "Maximum depth %i\n"
+ "Meshes: %i\n"
+ "Animations: %i\n"
+ "Textures (embed.): %i\n"
+ "Materials: %i\n"
+ "Cameras: %i\n"
+ "Lights: %i\n"
+ "Vertices: %i\n"
+ "Faces: %i\n"
+ "Bones: %i\n"
+ "Animation Channels: %i\n"
+ "Primitive Types: %s\n"
+ "Average faces/mesh %i\n"
+ "Average verts/mesh %i\n"
+ "Minimum point (%f %f %f)\n"
+ "Maximum point (%f %f %f)\n"
+ "Center point (%f %f %f)\n"
+
+ ;
+
+ aiVector3D special_points[3];
+ FindSpecialPoints(scene,special_points);
+ printf(format_string,
+ mem.total,
+ CountNodes(scene->mRootNode),
+ GetMaxDepth(scene->mRootNode),
+ scene->mNumMeshes,
+ scene->mNumAnimations,
+ scene->mNumTextures,
+ scene->mNumMaterials,
+ scene->mNumCameras,
+ scene->mNumLights,
+ CountVertices(scene),
+ CountFaces(scene),
+ CountBones(scene),
+ CountAnimChannels(scene),
+ FindPTypes(scene).c_str(),
+ GetAvgFacePerMesh(scene),
+ GetAvgVertsPerMesh(scene),
+ special_points[0][0],special_points[0][1],special_points[0][2],
+ special_points[1][0],special_points[1][1],special_points[1][2],
+ special_points[2][0],special_points[2][1],special_points[2][2]
+ )
+ ;
+ unsigned int total=0;
+ for(unsigned int i = 0;i < scene->mNumMaterials; ++i) {
+ aiString name;
+ if (AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i],AI_MATKEY_NAME,&name)) {
+ printf("%s\n \'%s\'",(total++?"":"\nNamed Materials:" ),name.data);
+ }
+ }
+ if(total) {
+ printf("\n");
+ }
+
+ total=0;
+ for(unsigned int i = 0;i < scene->mNumMaterials; ++i) {
+ aiString name;
+ static const aiTextureType types[] = {
+ aiTextureType_NONE,
+ aiTextureType_DIFFUSE,
+ aiTextureType_SPECULAR,
+ aiTextureType_AMBIENT,
+ aiTextureType_EMISSIVE,
+ aiTextureType_HEIGHT,
+ aiTextureType_NORMALS,
+ aiTextureType_SHININESS,
+ aiTextureType_OPACITY,
+ aiTextureType_DISPLACEMENT,
+ aiTextureType_LIGHTMAP,
+ aiTextureType_REFLECTION,
+ aiTextureType_UNKNOWN
+ };
+ for(unsigned int type = 0; type < sizeof(types)/sizeof(types[0]); ++type) {
+ for(unsigned int idx = 0;AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i],
+ AI_MATKEY_TEXTURE(types[type],idx),&name); ++idx) {
+ printf("%s\n \'%s\'",(total++?"":"\nTexture Refs:" ),name.data);
+ }
+ }
+ }
+ if(total) {
+ printf("\n");
+ }
+
+ total=0;
+ for(unsigned int i = 0;i < scene->mNumAnimations; ++i) {
+ if (scene->mAnimations[i]->mName.length) {
+ printf("%s\n \'%s\'",(total++?"":"\nNamed Animations:" ),scene->mAnimations[i]->mName.data);
+ }
+ }
+ if(total) {
+ printf("\n");
+ }
+
+ printf("\nNode hierarchy:\n");
+ unsigned int cline=0;
+ PrintHierarchy(scene->mRootNode,20,1000,cline);
+
+ printf("\n");
+ return 0;
+}
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp
new file mode 100644
index 0000000..587e111
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp
@@ -0,0 +1,514 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 Main.cpp
+ * @brief main() function of assimp_cmd
+ */
+
+#include "Main.h"
+
+const char* AICMD_MSG_ABOUT =
+"------------------------------------------------------ \n"
+"Open Asset Import Library (\"Assimp\", https://github.com/assimp/assimp) \n"
+" -- Commandline toolchain --\n"
+"------------------------------------------------------ \n\n"
+
+"Version %i.%i %s%s%s%s%s(GIT commit %x)\n\n";
+
+const char* AICMD_MSG_HELP =
+"assimp <verb> <parameters>\n\n"
+" verbs:\n"
+" \tinfo - Quick file stats\n"
+" \tlistext - List all known file extensions available for import\n"
+" \tknowext - Check whether a file extension is recognized by Assimp\n"
+#ifndef ASSIMP_BUILD_NO_EXPORT
+" \texport - Export a file to one of the supported output formats\n"
+" \tlistexport - List all supported export formats\n"
+" \texportinfo - Show basic information on a specific export format\n"
+#endif
+" \textract - Extract embedded texture images\n"
+" \tdump - Convert models to a binary or textual dump (ASSBIN/ASSXML)\n"
+" \tcmpdump - Compare dumps created using \'assimp dump <file> -s ...\'\n"
+" \tversion - Display Assimp version\n"
+"\n Use \'assimp <verb> --help\' for detailed help on a command.\n"
+;
+
+/*extern*/ Assimp::Importer* globalImporter = NULL;
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+/*extern*/ Assimp::Exporter* globalExporter = NULL;
+#endif
+
+// ------------------------------------------------------------------------------
+// Application entry point
+int main (int argc, char* argv[])
+{
+ if (argc <= 1) {
+ printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n");
+ return 0;
+ }
+
+ // assimp version
+ // Display version information
+ if (! strcmp(argv[1], "version")) {
+ const unsigned int flags = aiGetCompileFlags();
+ printf(AICMD_MSG_ABOUT,
+ aiGetVersionMajor(),
+ aiGetVersionMinor(),
+ (flags & ASSIMP_CFLAGS_DEBUG ? "-debug " : ""),
+ (flags & ASSIMP_CFLAGS_NOBOOST ? "-noboost " : ""),
+ (flags & ASSIMP_CFLAGS_SHARED ? "-shared " : ""),
+ (flags & ASSIMP_CFLAGS_SINGLETHREADED ? "-st " : ""),
+ (flags & ASSIMP_CFLAGS_STLPORT ? "-stlport " : ""),
+ aiGetVersionRevision());
+
+ return 0;
+ }
+
+ // assimp help
+ // Display some basic help (--help and -h work as well
+ // because people could try them intuitively)
+ if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
+ printf("%s",AICMD_MSG_HELP);
+ return 0;
+ }
+
+ // assimp cmpdump
+ // Compare two mini model dumps (regression suite)
+ if (! strcmp(argv[1], "cmpdump")) {
+ return Assimp_CompareDump (&argv[2],argc-2);
+ }
+
+ // construct global importer and exporter instances
+ Assimp::Importer imp;
+ imp.SetPropertyBool("GLOB_MEASURE_TIME",true);
+ globalImporter = &imp;
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+ //
+ Assimp::Exporter exp;
+ globalExporter = &exp;
+#endif
+
+ // assimp listext
+ // List all file extensions supported by Assimp
+ if (! strcmp(argv[1], "listext")) {
+ aiString s;
+ imp.GetExtensionList(s);
+
+ printf("%s\n",s.data);
+ return 0;
+ }
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+ // assimp listexport
+ // List all export file formats supported by Assimp (not the file extensions, just the format identifiers!)
+ if (! strcmp(argv[1], "listexport")) {
+ aiString s;
+
+ for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
+ const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
+ s.Append( e->id );
+ if (i!=end-1) {
+ s.Append("\n");
+ }
+ }
+
+ printf("%s\n",s.data);
+ return 0;
+ }
+
+
+ // assimp exportinfo
+ // stat an export format
+ if (! strcmp(argv[1], "exportinfo")) {
+ aiString s;
+
+ if (argc<3) {
+ printf("Expected file format id\n");
+ return -11;
+ }
+
+ for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) {
+ const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i);
+ if (!strcmp(e->id,argv[2])) {
+ printf("%s\n%s\n%s\n",e->id,e->fileExtension,e->description);
+ return 0;
+ }
+ }
+
+ printf("Unknown file format id: \'%s\'\n",argv[2]);
+ return -12;
+ }
+
+ // assimp export
+ // Export a model to a file
+ if (! strcmp(argv[1], "export")) {
+ return Assimp_Export (&argv[2],argc-2);
+ }
+
+#endif
+
+ // assimp knowext
+ // Check whether a particular file extension is known by us, return 0 on success
+ if (! strcmp(argv[1], "knowext")) {
+ if (argc<3) {
+ printf("Expected file extension");
+ return -10;
+ }
+ const bool b = imp.IsExtensionSupported(argv[2]);
+ printf("File extension \'%s\' is %sknown\n",argv[2],(b?"":"not "));
+ return b?0:-1;
+ }
+
+ // assimp info
+ // Print basic model statistics
+ if (! strcmp(argv[1], "info")) {
+ return Assimp_Info ((const char**)&argv[2],argc-2);
+ }
+
+ // assimp dump
+ // Dump a model to a file
+ if (! strcmp(argv[1], "dump")) {
+ return Assimp_Dump (&argv[2],argc-2);
+ }
+
+ // assimp extract
+ // Extract an embedded texture from a file
+ if (! strcmp(argv[1], "extract")) {
+ return Assimp_Extract (&argv[2],argc-2);
+ }
+
+ // assimp testbatchload
+ // Used by /test/other/streamload.py to load a list of files
+ // using the same importer instance to check for incompatible
+ // importers.
+ if (! strcmp(argv[1], "testbatchload")) {
+ return Assimp_TestBatchLoad (&argv[2],argc-2);
+ }
+
+ printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n");
+ return 1;
+}
+
+
+// ------------------------------------------------------------------------------
+void SetLogStreams(const ImportData& imp)
+{
+ printf("\nAttaching log stream ... OK\n");
+
+ unsigned int flags = 0;
+ if (imp.logFile.length()) {
+ flags |= aiDefaultLogStream_FILE;
+ }
+ if (imp.showLog) {
+ flags |= aiDefaultLogStream_STDERR;
+ }
+ DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags);
+}
+
+
+// ------------------------------------------------------------------------------
+void FreeLogStreams()
+{
+ DefaultLogger::kill();
+}
+
+
+// ------------------------------------------------------------------------------
+void PrintHorBar()
+{
+ printf("-----------------------------------------------------------------\n");
+}
+
+
+// ------------------------------------------------------------------------------
+// Import a specific file
+const aiScene* ImportModel(
+ const ImportData& imp,
+ const std::string& path)
+{
+ // Attach log streams
+ if (imp.log) {
+ SetLogStreams(imp);
+ }
+ printf("Launching asset import ... OK\n");
+
+ // Now validate this flag combination
+ if(!globalImporter->ValidateFlags(imp.ppFlags)) {
+ printf("ERROR: Unsupported post-processing flags \n");
+ return NULL;
+ }
+ printf("Validating postprocessing flags ... OK\n");
+ if (imp.showLog) {
+ PrintHorBar();
+ }
+
+
+ // do the actual import, measure time
+ const clock_t first = clock();
+ const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags);
+
+ if (imp.showLog) {
+ PrintHorBar();
+ }
+ if (!scene) {
+ printf("ERROR: Failed to load file: %s\n", globalImporter->GetErrorString());
+ return NULL;
+ }
+
+ const clock_t second = ::clock();
+ const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC;
+
+ printf("Importing file ... OK \n import took approx. %.5f seconds\n"
+ "\n",seconds);
+
+ if (imp.log) {
+ FreeLogStreams();
+ }
+ return scene;
+}
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+// ------------------------------------------------------------------------------
+bool ExportModel(const aiScene* pOut,
+ const ImportData& imp,
+ const std::string& path,
+ const char* pID)
+{
+ // Attach log streams
+ if (imp.log) {
+ SetLogStreams(imp);
+ }
+ printf("Launching asset export ... OK\n");
+
+ if (imp.showLog) {
+ PrintHorBar();
+ }
+
+ // do the actual export, measure time
+ const clock_t first = clock();
+ const aiReturn res = globalExporter->Export(pOut,pID,path);
+
+ if (imp.showLog) {
+ PrintHorBar();
+ }
+ if (res != AI_SUCCESS) {
+ printf("ERROR: Failed to write file\n");
+ return false;
+ }
+
+ const clock_t second = ::clock();
+ const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC;
+
+ printf("Exporting file ... OK \n export took approx. %.5f seconds\n"
+ "\n",seconds);
+
+ if (imp.log) {
+ FreeLogStreams();
+ }
+
+ return true;
+}
+#endif
+
+// ------------------------------------------------------------------------------
+// Process standard arguments
+int ProcessStandardArguments(
+ ImportData& fill,
+ const char* const * params,
+ unsigned int num)
+{
+ // -ptv --pretransform-vertices
+ // -gsn --gen-smooth-normals
+ // -gn --gen-normals
+ // -cts --calc-tangent-space
+ // -jiv --join-identical-vertices
+ // -rrm --remove-redundant-materials
+ // -fd --find-degenerates
+ // -slm --split-large-meshes
+ // -lbw --limit-bone-weights
+ // -vds --validate-data-structure
+ // -icl --improve-cache-locality
+ // -sbpt --sort-by-ptype
+ // -lh --convert-to-lh
+ // -fuv --flip-uv
+ // -fwo --flip-winding-order
+ // -tuv --transform-uv-coords
+ // -guv --gen-uvcoords
+ // -fid --find-invalid-data
+ // -fixn --fix normals
+ // -tri --triangulate
+ // -fi --find-instances
+ // -og --optimize-graph
+ // -om --optimize-meshes
+ // -db --debone
+ // -sbc --split-by-bone-count
+ //
+ // -c<file> --config-file=<file>
+
+ for (unsigned int i = 0; i < num;++i)
+ {
+ if (! strcmp(params[i], "-ptv") || ! strcmp(params[i], "--pretransform-vertices")) {
+ fill.ppFlags |= aiProcess_PreTransformVertices;
+ }
+ else if (! strcmp(params[i], "-gsn") || ! strcmp(params[i], "--gen-smooth-normals")) {
+ fill.ppFlags |= aiProcess_GenSmoothNormals;
+ }
+ else if (! strcmp(params[i], "-gn") || ! strcmp(params[i], "--gen-normals")) {
+ fill.ppFlags |= aiProcess_GenNormals;
+ }
+ else if (! strcmp(params[i], "-jiv") || ! strcmp(params[i], "--join-identical-vertices")) {
+ fill.ppFlags |= aiProcess_JoinIdenticalVertices;
+ }
+ else if (! strcmp(params[i], "-rrm") || ! strcmp(params[i], "--remove-redundant-materials")) {
+ fill.ppFlags |= aiProcess_RemoveRedundantMaterials;
+ }
+ else if (! strcmp(params[i], "-fd") || ! strcmp(params[i], "--find-degenerates")) {
+ fill.ppFlags |= aiProcess_FindDegenerates;
+ }
+ else if (! strcmp(params[i], "-slm") || ! strcmp(params[i], "--split-large-meshes")) {
+ fill.ppFlags |= aiProcess_SplitLargeMeshes;
+ }
+ else if (! strcmp(params[i], "-lbw") || ! strcmp(params[i], "--limit-bone-weights")) {
+ fill.ppFlags |= aiProcess_LimitBoneWeights;
+ }
+ else if (! strcmp(params[i], "-vds") || ! strcmp(params[i], "--validate-data-structure")) {
+ fill.ppFlags |= aiProcess_ValidateDataStructure;
+ }
+ else if (! strcmp(params[i], "-icl") || ! strcmp(params[i], "--improve-cache-locality")) {
+ fill.ppFlags |= aiProcess_ImproveCacheLocality;
+ }
+ else if (! strcmp(params[i], "-sbpt") || ! strcmp(params[i], "--sort-by-ptype")) {
+ fill.ppFlags |= aiProcess_SortByPType;
+ }
+ else if (! strcmp(params[i], "-lh") || ! strcmp(params[i], "--left-handed")) {
+ fill.ppFlags |= aiProcess_ConvertToLeftHanded;
+ }
+ else if (! strcmp(params[i], "-fuv") || ! strcmp(params[i], "--flip-uv")) {
+ fill.ppFlags |= aiProcess_FlipUVs;
+ }
+ else if (! strcmp(params[i], "-fwo") || ! strcmp(params[i], "--flip-winding-order")) {
+ fill.ppFlags |= aiProcess_FlipWindingOrder;
+ }
+ else if (! strcmp(params[i], "-tuv") || ! strcmp(params[i], "--transform-uv-coords")) {
+ fill.ppFlags |= aiProcess_TransformUVCoords;
+ }
+ else if (! strcmp(params[i], "-guv") || ! strcmp(params[i], "--gen-uvcoords")) {
+ fill.ppFlags |= aiProcess_GenUVCoords;
+ }
+ else if (! strcmp(params[i], "-fid") || ! strcmp(params[i], "--find-invalid-data")) {
+ fill.ppFlags |= aiProcess_FindInvalidData;
+ }
+ else if (! strcmp(params[i], "-fixn") || ! strcmp(params[i], "--fix-normals")) {
+ fill.ppFlags |= aiProcess_FixInfacingNormals;
+ }
+ else if (! strcmp(params[i], "-tri") || ! strcmp(params[i], "--triangulate")) {
+ fill.ppFlags |= aiProcess_Triangulate;
+ }
+ else if (! strcmp(params[i], "-cts") || ! strcmp(params[i], "--calc-tangent-space")) {
+ fill.ppFlags |= aiProcess_CalcTangentSpace;
+ }
+ else if (! strcmp(params[i], "-fi") || ! strcmp(params[i], "--find-instances")) {
+ fill.ppFlags |= aiProcess_FindInstances;
+ }
+ else if (! strcmp(params[i], "-og") || ! strcmp(params[i], "--optimize-graph")) {
+ fill.ppFlags |= aiProcess_OptimizeGraph;
+ }
+ else if (! strcmp(params[i], "-om") || ! strcmp(params[i], "--optimize-meshes")) {
+ fill.ppFlags |= aiProcess_OptimizeMeshes;
+ }
+ else if (! strcmp(params[i], "-db") || ! strcmp(params[i], "--debone")) {
+ fill.ppFlags |= aiProcess_Debone;
+ }
+ else if (! strcmp(params[i], "-sbc") || ! strcmp(params[i], "--split-by-bone-count")) {
+ fill.ppFlags |= aiProcess_SplitByBoneCount;
+ }
+
+
+ else if (! strncmp(params[i], "-c",2) || ! strncmp(params[i], "--config=",9)) {
+
+ const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);
+
+ // use default configurations
+ if (! strncmp(params[i]+ofs,"full",4)) {
+ fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
+ }
+ else if (! strncmp(params[i]+ofs,"default",7)) {
+ fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality;
+ }
+ else if (! strncmp(params[i]+ofs,"fast",4)) {
+ fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast;
+ }
+ }
+ else if (! strcmp(params[i], "-l") || ! strcmp(params[i], "--show-log")) {
+ fill.showLog = true;
+ }
+ else if (! strcmp(params[i], "-v") || ! strcmp(params[i], "--verbose")) {
+ fill.verbose = true;
+ }
+ else if (! strncmp(params[i], "--log-out=",10) || ! strncmp(params[i], "-lo",3)) {
+ fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3));
+ if (!fill.logFile.length()) {
+ fill.logFile = "assimp-log.txt";
+ }
+ }
+ }
+
+ if (fill.logFile.length() || fill.showLog || fill.verbose) {
+ fill.log = true;
+ }
+
+ return 0;
+}
+
+// ------------------------------------------------------------------------------
+int Assimp_TestBatchLoad (
+ const char* const* params,
+ unsigned int num)
+{
+ for(unsigned int i = 0; i < num; ++i) {
+ globalImporter->ReadFile(params[i],aiProcessPreset_TargetRealtime_MaxQuality);
+ // we're totally silent. scene destructs automatically.
+ }
+ return 0;
+}
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h
new file mode 100644
index 0000000..56b06d5
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h
@@ -0,0 +1,208 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, 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 Main.h
+ * @brief Utility declarations for assimp_cmd
+ */
+
+#ifndef AICMD_MAIN_INCLUDED
+#define AICMD_MAIN_INCLUDED
+
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <limits>
+
+#include <assimp/postprocess.h>
+#include <assimp/version.h>
+#include <assimp/scene.h>
+#include <assimp/Importer.hpp>
+#include <assimp/DefaultLogger.hpp>
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+# include <assimp/Exporter.hpp>
+#endif
+
+#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
+#include <zlib.h>
+#else
+#include <../contrib/zlib/zlib.h>
+#endif
+
+
+#ifndef SIZE_MAX
+# define SIZE_MAX (std::numeric_limits<size_t>::max())
+#endif
+
+
+using namespace Assimp;
+
+
+// Global assimp importer instance
+extern Assimp::Importer* globalImporter;
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+// Global assimp exporter instance
+extern Assimp::Exporter* globalExporter;
+#endif
+
+// ------------------------------------------------------------------------------
+/** Defines common import parameters */
+struct ImportData
+{
+ ImportData()
+ : ppFlags (0)
+ , showLog (false)
+ , verbose (false)
+ , log (false)
+ {}
+
+ /** Postprocessing flags
+ */
+ unsigned int ppFlags;
+
+
+ // Log to std::err?
+ bool showLog;
+
+ // Log file
+ std::string logFile;
+
+ // Verbose log mode?
+ bool verbose;
+
+ // Need to log?
+ bool log;
+};
+
+// ------------------------------------------------------------------------------
+/** Process standard arguments
+ *
+ * @param fill Filled by function
+ * @param params Command line parameters to be processed
+ * @param num NUmber of params
+ * @return 0 for success */
+int ProcessStandardArguments(ImportData& fill,
+ const char* const* params,
+ unsigned int num);
+
+// ------------------------------------------------------------------------------
+/** Import a specific model file
+ * @param imp Import configuration to be used
+ * @param path Path to the file to be read */
+const aiScene* ImportModel(
+ const ImportData& imp,
+ const std::string& path);
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+// ------------------------------------------------------------------------------
+/** Export a specific model file
+ * @param imp Import configuration to be used
+ * @param path Path to the file to be written
+ * @param format Format id*/
+bool ExportModel(const aiScene* pOut,
+ const ImportData& imp,
+ const std::string& path,
+ const char* pID);
+
+#endif
+
+// ------------------------------------------------------------------------------
+/** assimp_dump utility
+ * @param params Command line parameters to 'assimp dumb'
+ * @param Number of params
+ * @return 0 for success*/
+int Assimp_Dump (
+ const char* const* params,
+ unsigned int num);
+
+// ------------------------------------------------------------------------------
+/** assimp_export utility
+ * @param params Command line parameters to 'assimp export'
+ * @param Number of params
+ * @return 0 for success*/
+int Assimp_Export (
+ const char* const* params,
+ unsigned int num);
+
+// ------------------------------------------------------------------------------
+/** assimp_extract utility
+ * @param params Command line parameters to 'assimp extract'
+ * @param Number of params
+ * @return 0 for success*/
+int Assimp_Extract (
+ const char* const* params,
+ unsigned int num);
+
+// ------------------------------------------------------------------------------
+/** assimp_cmpdump utility
+ * @param params Command line parameters to 'assimp cmpdump'
+ * @param Number of params
+ * @return 0 for success*/
+int Assimp_CompareDump (
+ const char* const* params,
+ unsigned int num);
+
+// ------------------------------------------------------------------------------
+/** @brief assimp info utility
+ * @param params Command line parameters to 'assimp info'
+ * @param Number of params
+ * @return 0 for success */
+int Assimp_Info (
+ const char* const* params,
+ unsigned int num);
+
+// ------------------------------------------------------------------------------
+/** @brief assimp testbatchload utility
+ * @param params Command line parameters to 'assimp testbatchload'
+ * @param Number of params
+ * @return 0 for success */
+int Assimp_TestBatchLoad (
+ const char* const* params,
+ unsigned int num);
+
+
+#endif // !! AICMD_MAIN_INCLUDED
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp
new file mode 100644
index 0000000..e1b104d
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp
@@ -0,0 +1,1415 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2017, 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 WriteTextDumb.cpp
+ * @brief Implementation of the 'assimp dump' utility
+ */
+
+#include "Main.h"
+#include "../code/ProcessHelper.h"
+
+const char* AICMD_MSG_DUMP_HELP =
+"assimp dump <model> [<out>] [-b] [-s] [-z] [common parameters]\n"
+"\t -b Binary output \n"
+"\t -s Shortened \n"
+"\t -z Compressed \n"
+"\t[See the assimp_cmd docs for a full list of all common parameters] \n"
+"\t -cfast Fast post processing preset, runs just a few important steps \n"
+"\t -cdefault Default post processing: runs all recommended steps\n"
+"\t -cfull Fires almost all post processing steps \n"
+;
+
+#include "../../code/assbin_chunks.h"
+
+FILE* out = NULL;
+bool shortened = false;
+
+// -----------------------------------------------------------------------------------
+// Compress a binary dump file (beginning at offset head_size)
+void CompressBinaryDump(const char* file, unsigned int head_size)
+{
+ // for simplicity ... copy the file into memory again and compress it there
+ FILE* p = fopen(file,"r");
+ fseek(p,0,SEEK_END);
+ const uint32_t size = ftell(p);
+ fseek(p,0,SEEK_SET);
+
+ if (size<head_size) {
+ fclose(p);
+ return;
+ }
+
+ uint8_t* data = new uint8_t[size];
+ fread(data,1,size,p);
+
+ uLongf out_size = (uLongf)((size-head_size) * 1.001 + 12.);
+ uint8_t* out = new uint8_t[out_size];
+
+ compress2(out,&out_size,data+head_size,size-head_size,9);
+ fclose(p);
+ p = fopen(file,"w");
+
+ fwrite(data,head_size,1,p);
+ fwrite(&out_size,4,1,p); // write size of uncompressed data
+ fwrite(out,out_size,1,p);
+
+ fclose(p);
+ delete[] data;
+ delete[] out;
+}
+
+// -----------------------------------------------------------------------------------
+// Write a magic start value for each serialized data structure
+inline uint32_t WriteMagic(uint32_t magic)
+{
+ fwrite(&magic,4,1,out);
+ fwrite(&magic,4,1,out);
+ return ftell(out)-4;
+}
+
+// use template specializations rather than regular overloading to be able to
+// explicitly select the right 'overload' to leave no doubts on what is called,
+// retaining the possibility of letting the compiler select.
+template <typename T> uint32_t Write(const T&);
+
+// -----------------------------------------------------------------------------------
+// Serialize an aiString
+template <>
+inline uint32_t Write<aiString>(const aiString& s)
+{
+ const uint32_t s2 = (uint32_t)s.length;
+ fwrite(&s,4,1,out);
+ fwrite(s.data,s2,1,out);
+ return s2+4;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize an unsigned int as uint32_t
+template <>
+inline uint32_t Write<unsigned int>(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");
+ }
+
+ fwrite(&t,4,1,out);
+ return 4;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize an unsigned int as uint16_t
+template <>
+inline uint32_t Write<uint16_t>(const uint16_t& w)
+{
+ fwrite(&w,2,1,out);
+ return 2;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a float
+template <>
+inline uint32_t Write<float>(const float& f)
+{
+ static_assert(sizeof(float)==4, "sizeof(float)==4");
+ fwrite(&f,4,1,out);
+ return 4;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a double
+template <>
+inline uint32_t Write<double>(const double& f)
+{
+ static_assert(sizeof(double)==8, "sizeof(double)==8");
+ fwrite(&f,8,1,out);
+ return 8;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a vec3
+template <>
+inline uint32_t Write<aiVector3D>(const aiVector3D& v)
+{
+ uint32_t t = Write<float>(v.x);
+ t += Write<float>(v.y);
+ t += Write<float>(v.z);
+ return t;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a color value
+template <>
+inline uint32_t Write<aiColor3D>(const aiColor3D& v)
+{
+ uint32_t t = Write<float>(v.r);
+ t += Write<float>(v.g);
+ t += Write<float>(v.b);
+ return t;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a color value
+template <>
+inline uint32_t Write<aiColor4D>(const aiColor4D& v)
+{
+ uint32_t t = Write<float>(v.r);
+ t += Write<float>(v.g);
+ t += Write<float>(v.b);
+ t += Write<float>(v.a);
+ return t;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a quaternion
+template <>
+inline uint32_t Write<aiQuaternion>(const aiQuaternion& v)
+{
+ uint32_t t = Write<float>(v.w);
+ t += Write<float>(v.x);
+ t += Write<float>(v.y);
+ t += Write<float>(v.z);
+ ai_assert(t == 16);
+ return 16;
+}
+
+
+// -----------------------------------------------------------------------------------
+// Serialize a vertex weight
+template <>
+inline uint32_t Write<aiVertexWeight>(const aiVertexWeight& v)
+{
+ uint32_t t = Write<unsigned int>(v.mVertexId);
+ return t+Write<float>(v.mWeight);
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a mat4x4
+template <>
+inline uint32_t Write<aiMatrix4x4>(const aiMatrix4x4& m)
+{
+ for (unsigned int i = 0; i < 4;++i) {
+ for (unsigned int i2 = 0; i2 < 4;++i2) {
+ Write<float>(m[i][i2]);
+ }
+ }
+ return 64;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize an aiVectorKey
+template <>
+inline uint32_t Write<aiVectorKey>(const aiVectorKey& v)
+{
+ const uint32_t t = Write<double>(v.mTime);
+ return t + Write<aiVector3D>(v.mValue);
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize an aiQuatKey
+template <>
+inline uint32_t Write<aiQuatKey>(const aiQuatKey& v)
+{
+ const uint32_t t = Write<double>(v.mTime);
+ return t + Write<aiQuaternion>(v.mValue);
+}
+
+// -----------------------------------------------------------------------------------
+// Write the min/max values of an array of Ts to the file
+template <typename T>
+inline uint32_t WriteBounds(const T* in, unsigned int size)
+{
+ T minc,maxc;
+ Assimp::ArrayBounds(in,size,minc,maxc);
+
+ const uint32_t t = Write<T>(minc);
+ return t + Write<T>(maxc);
+}
+
+
+
+// -----------------------------------------------------------------------------------
+void ChangeInteger(uint32_t ofs,uint32_t n)
+{
+ const uint32_t cur = ftell(out);
+ fseek(out,ofs,SEEK_SET);
+ fwrite(&n,4,1,out);
+ fseek(out,cur,SEEK_SET);
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryNode(const aiNode* node)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODE);
+ len += Write<aiString>(node->mName);
+ len += Write<aiMatrix4x4>(node->mTransformation);
+ len += Write<unsigned int>(node->mNumChildren);
+ len += Write<unsigned int>(node->mNumMeshes);
+
+ for (unsigned int i = 0; i < node->mNumMeshes;++i) {
+ len += Write<unsigned int>(node->mMeshes[i]);
+ }
+
+ for (unsigned int i = 0; i < node->mNumChildren;++i) {
+ len += WriteBinaryNode(node->mChildren[i])+8;
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryTexture(const aiTexture* tex)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AITEXTURE);
+
+ len += Write<unsigned int>(tex->mWidth);
+ len += Write<unsigned int>(tex->mHeight);
+ len += static_cast<uint32_t>(fwrite(tex->achFormatHint,1,4,out));
+
+ if(!shortened) {
+ if (!tex->mHeight) {
+ len += static_cast<uint32_t>(fwrite(tex->pcData,1,tex->mWidth,out));
+ }
+ else {
+ len += static_cast<uint32_t>(fwrite(tex->pcData,1,tex->mWidth*tex->mHeight*4,out));
+ }
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryBone(const aiBone* b)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIBONE);
+
+ len += Write<aiString>(b->mName);
+ len += Write<unsigned int>(b->mNumWeights);
+ len += Write<aiMatrix4x4>(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) {
+ len += WriteBounds(b->mWeights,b->mNumWeights);
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight),out));
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryMesh(const aiMesh* mesh)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMESH);
+
+ len += Write<unsigned int>(mesh->mPrimitiveTypes);
+ len += Write<unsigned int>(mesh->mNumVertices);
+ len += Write<unsigned int>(mesh->mNumFaces);
+ len += Write<unsigned int>(mesh->mNumBones);
+ len += Write<unsigned int>(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);
+ }
+ len += Write<unsigned int>(c);
+
+ aiVector3D minVec, maxVec;
+ if (mesh->mVertices) {
+ if (shortened) {
+ len += WriteBounds(mesh->mVertices,mesh->mNumVertices);
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(mesh->mVertices,1,12*mesh->mNumVertices,out));
+ }
+ if (mesh->mNormals) {
+ if (shortened) {
+ len += WriteBounds(mesh->mNormals,mesh->mNumVertices);
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(mesh->mNormals,1,12*mesh->mNumVertices,out));
+ }
+ if (mesh->mTangents && mesh->mBitangents) {
+ if (shortened) {
+ len += WriteBounds(mesh->mTangents,mesh->mNumVertices);
+ len += WriteBounds(mesh->mBitangents,mesh->mNumVertices);
+ } // else write as usual
+ else {
+ len += static_cast<uint32_t>(fwrite(mesh->mTangents,1,12*mesh->mNumVertices,out));
+ len += static_cast<uint32_t>(fwrite(mesh->mBitangents,1,12*mesh->mNumVertices,out));
+ }
+ }
+ for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
+ if (!mesh->mColors[n])
+ break;
+
+ if (shortened) {
+ len += WriteBounds(mesh->mColors[n],mesh->mNumVertices);
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(mesh->mColors[n],16*mesh->mNumVertices,1,out));
+ }
+ for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
+ if (!mesh->mTextureCoords[n])
+ break;
+
+ // write number of UV components
+ len += Write<unsigned int>(mesh->mNumUVComponents[n]);
+
+ if (shortened) {
+ len += WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices);
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(mesh->mTextureCoords[n],12*mesh->mNumVertices,1,out));
+ }
+
+ // 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<const char*>(&tmp),sizeof tmp,hash);
+ for (unsigned int i = 0; i < f.mNumIndices; ++i) {
+ static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff");
+ tmp = static_cast<uint32_t>( f.mIndices[i] );
+ hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
+ }
+ }
+ len += Write<unsigned int>(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];
+
+ static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
+ len += Write<uint16_t>(f.mNumIndices);
+
+ for (unsigned int a = 0; a < f.mNumIndices;++a) {
+ if (mesh->mNumVertices < (1u<<16)) {
+ len += Write<uint16_t>(f.mIndices[a]);
+ }
+ else len += Write<unsigned int>(f.mIndices[a]);
+ }
+ }
+ }
+
+ // write bones
+ if (mesh->mNumBones) {
+ for (unsigned int a = 0; a < mesh->mNumBones;++a) {
+ const aiBone* b = mesh->mBones[a];
+ len += WriteBinaryBone(b)+8;
+ }
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryMaterialProperty(const aiMaterialProperty* prop)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIALPROPERTY);
+
+ len += Write<aiString>(prop->mKey);
+ len += Write<unsigned int>(prop->mSemantic);
+ len += Write<unsigned int>(prop->mIndex);
+
+ len += Write<unsigned int>(prop->mDataLength);
+ len += Write<unsigned int>((unsigned int)prop->mType);
+ len += static_cast<uint32_t>(fwrite(prop->mData,1,prop->mDataLength,out));
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryMaterial(const aiMaterial* mat)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIAL);
+
+ len += Write<unsigned int>(mat->mNumProperties);
+ for (unsigned int i = 0; i < mat->mNumProperties;++i) {
+ len += WriteBinaryMaterialProperty(mat->mProperties[i])+8;
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryNodeAnim(const aiNodeAnim* nd)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODEANIM);
+
+ len += Write<aiString>(nd->mNodeName);
+ len += Write<unsigned int>(nd->mNumPositionKeys);
+ len += Write<unsigned int>(nd->mNumRotationKeys);
+ len += Write<unsigned int>(nd->mNumScalingKeys);
+ len += Write<unsigned int>(nd->mPreState);
+ len += Write<unsigned int>(nd->mPostState);
+
+ if (nd->mPositionKeys) {
+ if (shortened) {
+ len += WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys);
+
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey),out));
+ }
+ if (nd->mRotationKeys) {
+ if (shortened) {
+ len += WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys);
+
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey),out));
+ }
+ if (nd->mScalingKeys) {
+ if (shortened) {
+ len += WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys);
+
+ } // else write as usual
+ else len += static_cast<uint32_t>(fwrite(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey),out));
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryAnim(const aiAnimation* anim)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIANIMATION);
+
+ len += Write<aiString> (anim->mName);
+ len += Write<double> (anim->mDuration);
+ len += Write<double> (anim->mTicksPerSecond);
+ len += Write<unsigned int>(anim->mNumChannels);
+
+ for (unsigned int a = 0; a < anim->mNumChannels;++a) {
+ const aiNodeAnim* nd = anim->mChannels[a];
+ len += WriteBinaryNodeAnim(nd)+8;
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryLight(const aiLight* l)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AILIGHT);
+
+ len += Write<aiString>(l->mName);
+ len += Write<unsigned int>(l->mType);
+
+ if (l->mType != aiLightSource_DIRECTIONAL) {
+ len += Write<float>(l->mAttenuationConstant);
+ len += Write<float>(l->mAttenuationLinear);
+ len += Write<float>(l->mAttenuationQuadratic);
+ }
+
+ len += Write<aiColor3D>(l->mColorDiffuse);
+ len += Write<aiColor3D>(l->mColorSpecular);
+ len += Write<aiColor3D>(l->mColorAmbient);
+
+ if (l->mType == aiLightSource_SPOT) {
+ len += Write<float>(l->mAngleInnerCone);
+ len += Write<float>(l->mAngleOuterCone);
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryCamera(const aiCamera* cam)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AICAMERA);
+
+ len += Write<aiString>(cam->mName);
+ len += Write<aiVector3D>(cam->mPosition);
+ len += Write<aiVector3D>(cam->mLookAt);
+ len += Write<aiVector3D>(cam->mUp);
+ len += Write<float>(cam->mHorizontalFOV);
+ len += Write<float>(cam->mClipPlaneNear);
+ len += Write<float>(cam->mClipPlaneFar);
+ len += Write<float>(cam->mAspect);
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+uint32_t WriteBinaryScene(const aiScene* scene)
+{
+ uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AISCENE);
+
+ // basic scene information
+ len += Write<unsigned int>(scene->mFlags);
+ len += Write<unsigned int>(scene->mNumMeshes);
+ len += Write<unsigned int>(scene->mNumMaterials);
+ len += Write<unsigned int>(scene->mNumAnimations);
+ len += Write<unsigned int>(scene->mNumTextures);
+ len += Write<unsigned int>(scene->mNumLights);
+ len += Write<unsigned int>(scene->mNumCameras);
+
+ // write node graph
+ len += WriteBinaryNode(scene->mRootNode)+8;
+
+ // write all meshes
+ for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
+ const aiMesh* mesh = scene->mMeshes[i];
+ len += WriteBinaryMesh(mesh)+8;
+ }
+
+ // write materials
+ for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
+ const aiMaterial* mat = scene->mMaterials[i];
+ len += WriteBinaryMaterial(mat)+8;
+ }
+
+ // write all animations
+ for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
+ const aiAnimation* anim = scene->mAnimations[i];
+ len += WriteBinaryAnim(anim)+8;
+ }
+
+
+ // write all textures
+ for (unsigned int i = 0; i < scene->mNumTextures;++i) {
+ const aiTexture* mesh = scene->mTextures[i];
+ len += WriteBinaryTexture(mesh)+8;
+ }
+
+ // write lights
+ for (unsigned int i = 0; i < scene->mNumLights;++i) {
+ const aiLight* l = scene->mLights[i];
+ len += WriteBinaryLight(l)+8;
+ }
+
+ // write cameras
+ for (unsigned int i = 0; i < scene->mNumCameras;++i) {
+ const aiCamera* cam = scene->mCameras[i];
+ len += WriteBinaryCamera(cam)+8;
+ }
+
+ ChangeInteger(old,len);
+ return len;
+}
+
+// -----------------------------------------------------------------------------------
+// Write a binary model dump
+void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const char* cmd,
+ bool _shortened, bool compressed, ImportData& /*imp*/)
+{
+ out = _out;
+ shortened = _shortened;
+
+ time_t tt = time(NULL);
+ tm* p = gmtime(&tt);
+
+ // header
+ fprintf(out,"ASSIMP.binary-dump.%s",asctime(p));
+ // == 44 bytes
+
+ Write<unsigned int>(ASSBIN_VERSION_MAJOR);
+ Write<unsigned int>(ASSBIN_VERSION_MINOR);
+ Write<unsigned int>(aiGetVersionRevision());
+ Write<unsigned int>(aiGetCompileFlags());
+ Write<uint16_t>(shortened);
+ Write<uint16_t>(compressed);
+ // == 20 bytes
+
+ {
+ char buff[256] = { 0 };
+ strncpy(buff,src,256);
+ buff[255] = 0;
+ fwrite(buff,256,1,out);
+ }
+
+ {
+ char buff[128] = { 0 };
+ strncpy(buff,cmd,128);
+ buff[127] = 0;
+ fwrite(buff,128,1,out);
+ }
+
+ // leave 64 bytes free for future extensions
+ {
+ char buff[64];
+ memset(buff,0xcd,64);
+ fwrite(buff,64,1,out);
+ }
+ // == 435 bytes
+
+ // ==== total header size: 512 bytes
+ ai_assert(ftell(out)==ASSBIN_HEADER_LENGTH);
+
+ // Up to here the data is uncompressed. For compressed files, the rest
+ // is compressed using standard DEFLATE from zlib.
+ WriteBinaryScene(scene);
+}
+
+// -----------------------------------------------------------------------------------
+// Convert a name to standard XML format
+void ConvertName(aiString& out, const aiString& in)
+{
+ out.length = 0;
+ for (unsigned int i = 0; i < in.length; ++i) {
+ switch (in.data[i]) {
+ case '<':
+ out.Append("&lt;");break;
+ case '>':
+ out.Append("&gt;");break;
+ case '&':
+ out.Append("&amp;");break;
+ case '\"':
+ out.Append("&quot;");break;
+ case '\'':
+ out.Append("&apos;");break;
+ default:
+ out.data[out.length++] = in.data[i];
+ }
+ }
+ out.data[out.length] = 0;
+}
+
+// -----------------------------------------------------------------------------------
+// Write a single node as text dump
+void WriteNode(const aiNode* node, FILE* out, unsigned int depth)
+{
+ char prefix[512];
+ for (unsigned int i = 0; i < depth;++i)
+ prefix[i] = '\t';
+ prefix[depth] = '\0';
+
+ const aiMatrix4x4& m = node->mTransformation;
+
+ aiString name;
+ ConvertName(name,node->mName);
+ fprintf(out,"%s<Node name=\"%s\"> \n"
+ "%s\t<Matrix4> \n"
+ "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "%s\t</Matrix4> \n",
+ prefix,name.data,prefix,
+ prefix,m.a1,m.a2,m.a3,m.a4,
+ prefix,m.b1,m.b2,m.b3,m.b4,
+ prefix,m.c1,m.c2,m.c3,m.c4,
+ prefix,m.d1,m.d2,m.d3,m.d4,prefix);
+
+ if (node->mNumMeshes) {
+ fprintf(out, "%s\t<MeshRefs num=\"%u\">\n%s\t",
+ prefix,node->mNumMeshes,prefix);
+
+ for (unsigned int i = 0; i < node->mNumMeshes;++i) {
+ fprintf(out,"%u ",node->mMeshes[i]);
+ }
+ fprintf(out,"\n%s\t</MeshRefs>\n",prefix);
+ }
+
+ if (node->mNumChildren) {
+ fprintf(out,"%s\t<NodeList num=\"%u\">\n",
+ prefix,node->mNumChildren);
+
+ for (unsigned int i = 0; i < node->mNumChildren;++i) {
+ WriteNode(node->mChildren[i],out,depth+2);
+ }
+ fprintf(out,"%s\t</NodeList>\n",prefix);
+ }
+ fprintf(out,"%s</Node>\n",prefix);
+}
+
+
+// -------------------------------------------------------------------------------
+const char* TextureTypeToString(aiTextureType in)
+{
+ switch (in)
+ {
+ case aiTextureType_NONE:
+ return "n/a";
+ case aiTextureType_DIFFUSE:
+ return "Diffuse";
+ case aiTextureType_SPECULAR:
+ return "Specular";
+ case aiTextureType_AMBIENT:
+ return "Ambient";
+ case aiTextureType_EMISSIVE:
+ return "Emissive";
+ case aiTextureType_OPACITY:
+ return "Opacity";
+ case aiTextureType_NORMALS:
+ return "Normals";
+ case aiTextureType_HEIGHT:
+ return "Height";
+ case aiTextureType_SHININESS:
+ return "Shininess";
+ case aiTextureType_DISPLACEMENT:
+ return "Displacement";
+ case aiTextureType_LIGHTMAP:
+ return "Lightmap";
+ case aiTextureType_REFLECTION:
+ return "Reflection";
+ case aiTextureType_UNKNOWN:
+ return "Unknown";
+ default:
+ break;
+ }
+ ai_assert(false);
+ return "BUG";
+}
+
+
+// -----------------------------------------------------------------------------------
+// Some chuncks of text will need to be encoded for XML
+// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377
+static std::string encodeXML(const std::string& data) {
+ std::string buffer;
+ buffer.reserve(data.size());
+ for(size_t pos = 0; pos != data.size(); ++pos) {
+ switch(data[pos]) {
+ case '&': buffer.append("&amp;"); break;
+ case '\"': buffer.append("&quot;"); break;
+ case '\'': buffer.append("&apos;"); break;
+ case '<': buffer.append("&lt;"); break;
+ case '>': buffer.append("&gt;"); break;
+ default: buffer.append(&data[pos], 1); break;
+ }
+ }
+ return buffer;
+}
+
+
+
+// -----------------------------------------------------------------------------------
+// Write a text model dump
+void WriteDump(const aiScene* scene, FILE* out, const char* src, const char* cmd, bool shortened)
+{
+ time_t tt = ::time(NULL);
+ tm* p = ::gmtime(&tt);
+
+ std::string c = cmd;
+ std::string::size_type s;
+
+ // https://sourceforge.net/tracker/?func=detail&aid=3167364&group_id=226462&atid=1067632
+ // -- not allowed in XML comments
+ while((s = c.find("--")) != std::string::npos) {
+ c[s] = '?';
+ }
+ aiString name;
+
+ // write header
+ fprintf(out,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<ASSIMP format_id=\"1\">\n\n"
+
+ "<!-- XML Model dump produced by assimp dump\n"
+ " Library version: %u.%u.%u\n"
+ " Source: %s\n"
+ " Command line: %s\n"
+ " %s\n"
+ "-->"
+ " \n\n"
+ "<Scene flags=\"%u\" postprocessing=\"%i\">\n",
+
+ aiGetVersionMajor(),aiGetVersionMinor(),aiGetVersionRevision(),src,c.c_str(),asctime(p),
+ scene->mFlags,
+ 0 /*globalImporter->GetEffectivePostProcessing()*/);
+
+ // write the node graph
+ WriteNode(scene->mRootNode, out, 0);
+
+#if 0
+ // write cameras
+ for (unsigned int i = 0; i < scene->mNumCameras;++i) {
+ aiCamera* cam = scene->mCameras[i];
+ ConvertName(name,cam->mName);
+
+ // camera header
+ fprintf(out,"\t<Camera parent=\"%s\">\n"
+ "\t\t<Vector3 name=\"up\" > %0 8f %0 8f %0 8f </Vector3>\n"
+ "\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n"
+ "\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n"
+ "\t\t<Float name=\"fov\" > %f </Float>\n"
+ "\t\t<Float name=\"aspect\" > %f </Float>\n"
+ "\t\t<Float name=\"near_clip\" > %f </Float>\n"
+ "\t\t<Float name=\"far_clip\" > %f </Float>\n"
+ "\t</Camera>\n",
+ name.data,
+ cam->mUp.x,cam->mUp.y,cam->mUp.z,
+ cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z,
+ cam->mPosition.x,cam->mPosition.y,cam->mPosition.z,
+ cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i);
+ }
+
+ // write lights
+ for (unsigned int i = 0; i < scene->mNumLights;++i) {
+ aiLight* l = scene->mLights[i];
+ ConvertName(name,l->mName);
+
+ // light header
+ fprintf(out,"\t<Light parent=\"%s\"> type=\"%s\"\n"
+ "\t\t<Vector3 name=\"diffuse\" > %0 8f %0 8f %0 8f </Vector3>\n"
+ "\t\t<Vector3 name=\"specular\" > %0 8f %0 8f %0 8f </Vector3>\n"
+ "\t\t<Vector3 name=\"ambient\" > %0 8f %0 8f %0 8f </Vector3>\n",
+ name.data,
+ (l->mType == aiLightSource_DIRECTIONAL ? "directional" :
+ (l->mType == aiLightSource_POINT ? "point" : "spot" )),
+ l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b,
+ l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b,
+ l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b);
+
+ if (l->mType != aiLightSource_DIRECTIONAL) {
+ fprintf(out,
+ "\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n"
+ "\t\t<Float name=\"atten_cst\" > %f </Float>\n"
+ "\t\t<Float name=\"atten_lin\" > %f </Float>\n"
+ "\t\t<Float name=\"atten_sqr\" > %f </Float>\n",
+ l->mPosition.x,l->mPosition.y,l->mPosition.z,
+ l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic);
+ }
+
+ if (l->mType != aiLightSource_POINT) {
+ fprintf(out,
+ "\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n",
+ l->mDirection.x,l->mDirection.y,l->mDirection.z);
+ }
+
+ if (l->mType == aiLightSource_SPOT) {
+ fprintf(out,
+ "\t\t<Float name=\"cone_out\" > %f </Float>\n"
+ "\t\t<Float name=\"cone_inn\" > %f </Float>\n",
+ l->mAngleOuterCone,l->mAngleInnerCone);
+ }
+ fprintf(out,"\t</Light>\n");
+ }
+#endif
+
+ // write textures
+ if (scene->mNumTextures) {
+ fprintf(out,"<TextureList num=\"%u\">\n",scene->mNumTextures);
+ for (unsigned int i = 0; i < scene->mNumTextures;++i) {
+ aiTexture* tex = scene->mTextures[i];
+ bool compressed = (tex->mHeight == 0);
+
+ // mesh header
+ fprintf(out,"\t<Texture width=\"%i\" height=\"%i\" compressed=\"%s\"> \n",
+ (compressed ? -1 : tex->mWidth),(compressed ? -1 : tex->mHeight),
+ (compressed ? "true" : "false"));
+
+ if (compressed) {
+ fprintf(out,"\t\t<Data length=\"%u\"> \n",tex->mWidth);
+
+ if (!shortened) {
+ for (unsigned int n = 0; n < tex->mWidth;++n) {
+ fprintf(out,"\t\t\t%2x",reinterpret_cast<uint8_t*>(tex->pcData)[n]);
+ if (n && !(n % 50)) {
+ fprintf(out,"\n");
+ }
+ }
+ }
+ }
+ else if (!shortened){
+ fprintf(out,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);
+
+ // const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1;
+ for (unsigned int y = 0; y < tex->mHeight;++y) {
+ for (unsigned int x = 0; x < tex->mWidth;++x) {
+ aiTexel* tx = tex->pcData + y*tex->mWidth+x;
+ unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
+ fprintf(out,"\t\t\t%2x %2x %2x %2x",r,g,b,a);
+
+ // group by four for readibility
+ if (0 == (x+y*tex->mWidth) % 4)
+ fprintf(out,"\n");
+ }
+ }
+ }
+ fprintf(out,"\t\t</Data>\n\t</Texture>\n");
+ }
+ fprintf(out,"</TextureList>\n");
+ }
+
+ // write materials
+ if (scene->mNumMaterials) {
+ fprintf(out,"<MaterialList num=\"%u\">\n",scene->mNumMaterials);
+ for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
+ const aiMaterial* mat = scene->mMaterials[i];
+
+ fprintf(out,"\t<Material>\n");
+ fprintf(out,"\t\t<MatPropertyList num=\"%u\">\n",mat->mNumProperties);
+ for (unsigned int n = 0; n < mat->mNumProperties;++n) {
+
+ const aiMaterialProperty* prop = mat->mProperties[n];
+ const char* sz = "";
+ if (prop->mType == aiPTI_Float) {
+ sz = "float";
+ }
+ else if (prop->mType == aiPTI_Integer) {
+ sz = "integer";
+ }
+ else if (prop->mType == aiPTI_String) {
+ sz = "string";
+ }
+ else if (prop->mType == aiPTI_Buffer) {
+ sz = "binary_buffer";
+ }
+
+ fprintf(out,"\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%u\"",
+ prop->mKey.data, sz,
+ ::TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex);
+
+ if (prop->mType == aiPTI_Float) {
+ fprintf(out," size=\"%i\">\n\t\t\t\t",
+ static_cast<int>(prop->mDataLength/sizeof(float)));
+
+ for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) {
+ fprintf(out,"%f ",*((float*)(prop->mData+p*sizeof(float))));
+ }
+ }
+ else if (prop->mType == aiPTI_Integer) {
+ fprintf(out," size=\"%i\">\n\t\t\t\t",
+ static_cast<int>(prop->mDataLength/sizeof(int)));
+
+ for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) {
+ fprintf(out,"%i ",*((int*)(prop->mData+p*sizeof(int))));
+ }
+ }
+ else if (prop->mType == aiPTI_Buffer) {
+ fprintf(out," size=\"%i\">\n\t\t\t\t",
+ static_cast<int>(prop->mDataLength));
+
+ for (unsigned int p = 0; p < prop->mDataLength;++p) {
+ fprintf(out,"%2x ",prop->mData[p]);
+ if (p && 0 == p%30) {
+ fprintf(out,"\n\t\t\t\t");
+ }
+ }
+ }
+ else if (prop->mType == aiPTI_String) {
+ fprintf(out,">\n\t\t\t\t\"%s\"",encodeXML(prop->mData+4).c_str() /* skip length */);
+ }
+ fprintf(out,"\n\t\t\t</MatProperty>\n");
+ }
+ fprintf(out,"\t\t</MatPropertyList>\n");
+ fprintf(out,"\t</Material>\n");
+ }
+ fprintf(out,"</MaterialList>\n");
+ }
+
+ // write animations
+ if (scene->mNumAnimations) {
+ fprintf(out,"<AnimationList num=\"%u\">\n",scene->mNumAnimations);
+ for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
+ aiAnimation* anim = scene->mAnimations[i];
+
+ // anim header
+ ConvertName(name,anim->mName);
+ fprintf(out,"\t<Animation name=\"%s\" duration=\"%e\" tick_cnt=\"%e\">\n",
+ name.data, anim->mDuration, anim->mTicksPerSecond);
+
+ // write bone animation channels
+ if (anim->mNumChannels) {
+ fprintf(out,"\t\t<NodeAnimList num=\"%u\">\n",anim->mNumChannels);
+ for (unsigned int n = 0; n < anim->mNumChannels;++n) {
+ aiNodeAnim* nd = anim->mChannels[n];
+
+ // node anim header
+ ConvertName(name,nd->mNodeName);
+ fprintf(out,"\t\t\t<NodeAnim node=\"%s\">\n",name.data);
+
+ if (!shortened) {
+ // write position keys
+ if (nd->mNumPositionKeys) {
+ fprintf(out,"\t\t\t\t<PositionKeyList num=\"%u\">\n",nd->mNumPositionKeys);
+ for (unsigned int a = 0; a < nd->mNumPositionKeys;++a) {
+ aiVectorKey* vc = nd->mPositionKeys+a;
+ fprintf(out,"\t\t\t\t\t<PositionKey time=\"%e\">\n"
+ "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</PositionKey>\n",
+ vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
+ }
+ fprintf(out,"\t\t\t\t</PositionKeyList>\n");
+ }
+
+ // write scaling keys
+ if (nd->mNumScalingKeys) {
+ fprintf(out,"\t\t\t\t<ScalingKeyList num=\"%u\">\n",nd->mNumScalingKeys);
+ for (unsigned int a = 0; a < nd->mNumScalingKeys;++a) {
+ aiVectorKey* vc = nd->mScalingKeys+a;
+ fprintf(out,"\t\t\t\t\t<ScalingKey time=\"%e\">\n"
+ "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</ScalingKey>\n",
+ vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
+ }
+ fprintf(out,"\t\t\t\t</ScalingKeyList>\n");
+ }
+
+ // write rotation keys
+ if (nd->mNumRotationKeys) {
+ fprintf(out,"\t\t\t\t<RotationKeyList num=\"%u\">\n",nd->mNumRotationKeys);
+ for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
+ aiQuatKey* vc = nd->mRotationKeys+a;
+ fprintf(out,"\t\t\t\t\t<RotationKey time=\"%e\">\n"
+ "\t\t\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t\t\t</RotationKey>\n",
+ vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,vc->mValue.w);
+ }
+ fprintf(out,"\t\t\t\t</RotationKeyList>\n");
+ }
+ }
+ fprintf(out,"\t\t\t</NodeAnim>\n");
+ }
+ fprintf(out,"\t\t</NodeAnimList>\n");
+ }
+ fprintf(out,"\t</Animation>\n");
+ }
+ fprintf(out,"</AnimationList>\n");
+ }
+
+ // write meshes
+ if (scene->mNumMeshes) {
+ fprintf(out,"<MeshList num=\"%u\">\n",scene->mNumMeshes);
+ for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
+ aiMesh* mesh = scene->mMeshes[i];
+ // const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1;
+
+ // mesh header
+ fprintf(out,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%u\">\n",
+ (mesh->mPrimitiveTypes & aiPrimitiveType_POINT ? "points" : ""),
+ (mesh->mPrimitiveTypes & aiPrimitiveType_LINE ? "lines" : ""),
+ (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""),
+ (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON ? "polygons" : ""),
+ mesh->mMaterialIndex);
+
+ // bones
+ if (mesh->mNumBones) {
+ fprintf(out,"\t\t<BoneList num=\"%u\">\n",mesh->mNumBones);
+
+ for (unsigned int n = 0; n < mesh->mNumBones;++n) {
+ aiBone* bone = mesh->mBones[n];
+
+ ConvertName(name,bone->mName);
+ // bone header
+ fprintf(out,"\t\t\t<Bone name=\"%s\">\n"
+ "\t\t\t\t<Matrix4> \n"
+ "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
+ "\t\t\t\t</Matrix4> \n",
+ name.data,
+ bone->mOffsetMatrix.a1,bone->mOffsetMatrix.a2,bone->mOffsetMatrix.a3,bone->mOffsetMatrix.a4,
+ bone->mOffsetMatrix.b1,bone->mOffsetMatrix.b2,bone->mOffsetMatrix.b3,bone->mOffsetMatrix.b4,
+ bone->mOffsetMatrix.c1,bone->mOffsetMatrix.c2,bone->mOffsetMatrix.c3,bone->mOffsetMatrix.c4,
+ bone->mOffsetMatrix.d1,bone->mOffsetMatrix.d2,bone->mOffsetMatrix.d3,bone->mOffsetMatrix.d4);
+
+ if (!shortened && bone->mNumWeights) {
+ fprintf(out,"\t\t\t\t<WeightList num=\"%u\">\n",bone->mNumWeights);
+
+ // bone weights
+ for (unsigned int a = 0; a < bone->mNumWeights;++a) {
+ aiVertexWeight* wght = bone->mWeights+a;
+
+ fprintf(out,"\t\t\t\t\t<Weight index=\"%u\">\n\t\t\t\t\t\t%f\n\t\t\t\t\t</Weight>\n",
+ wght->mVertexId,wght->mWeight);
+ }
+ fprintf(out,"\t\t\t\t</WeightList>\n");
+ }
+ fprintf(out,"\t\t\t</Bone>\n");
+ }
+ fprintf(out,"\t\t</BoneList>\n");
+ }
+
+ // faces
+ if (!shortened && mesh->mNumFaces) {
+ fprintf(out,"\t\t<FaceList num=\"%u\">\n",mesh->mNumFaces);
+ for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
+ aiFace& f = mesh->mFaces[n];
+ fprintf(out,"\t\t\t<Face num=\"%u\">\n"
+ "\t\t\t\t",f.mNumIndices);
+
+ for (unsigned int j = 0; j < f.mNumIndices;++j)
+ fprintf(out,"%u ",f.mIndices[j]);
+
+ fprintf(out,"\n\t\t\t</Face>\n");
+ }
+ fprintf(out,"\t\t</FaceList>\n");
+ }
+
+ // vertex positions
+ if (mesh->HasPositions()) {
+ fprintf(out,"\t\t<Positions num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
+ if (!shortened) {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
+ mesh->mVertices[n].x,
+ mesh->mVertices[n].y,
+ mesh->mVertices[n].z);
+ }
+ }
+ fprintf(out,"\t\t</Positions>\n");
+ }
+
+ // vertex normals
+ if (mesh->HasNormals()) {
+ fprintf(out,"\t\t<Normals num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
+ if (!shortened) {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
+ mesh->mNormals[n].x,
+ mesh->mNormals[n].y,
+ mesh->mNormals[n].z);
+ }
+ }
+ else {
+ }
+ fprintf(out,"\t\t</Normals>\n");
+ }
+
+ // vertex tangents and bitangents
+ if (mesh->HasTangentsAndBitangents()) {
+ fprintf(out,"\t\t<Tangents num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
+ if (!shortened) {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
+ mesh->mTangents[n].x,
+ mesh->mTangents[n].y,
+ mesh->mTangents[n].z);
+ }
+ }
+ fprintf(out,"\t\t</Tangents>\n");
+
+ fprintf(out,"\t\t<Bitangents num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
+ if (!shortened) {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
+ mesh->mBitangents[n].x,
+ mesh->mBitangents[n].y,
+ mesh->mBitangents[n].z);
+ }
+ }
+ fprintf(out,"\t\t</Bitangents>\n");
+ }
+
+ // texture coordinates
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
+ if (!mesh->mTextureCoords[a])
+ break;
+
+ fprintf(out,"\t\t<TextureCoords num=\"%u\" set=\"%u\" num_components=\"%u\"> \n",mesh->mNumVertices,
+ a,mesh->mNumUVComponents[a]);
+
+ if (!shortened) {
+ if (mesh->mNumUVComponents[a] == 3) {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f %0 8f\n",
+ mesh->mTextureCoords[a][n].x,
+ mesh->mTextureCoords[a][n].y,
+ mesh->mTextureCoords[a][n].z);
+ }
+ }
+ else {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f\n",
+ mesh->mTextureCoords[a][n].x,
+ mesh->mTextureCoords[a][n].y);
+ }
+ }
+ }
+ fprintf(out,"\t\t</TextureCoords>\n");
+ }
+
+ // vertex colors
+ for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
+ if (!mesh->mColors[a])
+ break;
+ fprintf(out,"\t\t<Colors num=\"%u\" set=\"%u\" num_components=\"4\"> \n",mesh->mNumVertices,a);
+ if (!shortened) {
+ for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
+ fprintf(out,"\t\t%0 8f %0 8f %0 8f %0 8f\n",
+ mesh->mColors[a][n].r,
+ mesh->mColors[a][n].g,
+ mesh->mColors[a][n].b,
+ mesh->mColors[a][n].a);
+ }
+ }
+ fprintf(out,"\t\t</Colors>\n");
+ }
+ fprintf(out,"\t</Mesh>\n");
+ }
+ fprintf(out,"</MeshList>\n");
+ }
+ fprintf(out,"</Scene>\n</ASSIMP>");
+}
+
+
+// -----------------------------------------------------------------------------------
+int Assimp_Dump (const char* const* params, unsigned int num)
+{
+ const char* fail = "assimp dump: Invalid number of arguments. "
+ "See \'assimp dump --help\'\r\n";
+ if (num < 1) {
+ printf("%s", fail);
+ return 1;
+ }
+
+ // --help
+ if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) {
+ printf("%s",AICMD_MSG_DUMP_HELP);
+ return 0;
+ }
+
+ // asssimp dump in out [options]
+ if (num < 1) {
+ printf("%s", fail);
+ return 1;
+ }
+
+ std::string in = std::string(params[0]);
+ std::string out = (num > 1 ? std::string(params[1]) : std::string("-"));
+
+ // store full command line
+ std::string cmd;
+ for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) {
+ if (!params[i])continue;
+ cmd.append(params[i]);
+ cmd.append(" ");
+ }
+
+ // get import flags
+ ImportData import;
+ ProcessStandardArguments(import,params+1,num-1);
+
+ bool binary = false, shortened = false,compressed=false;
+
+ // process other flags
+ for (unsigned int i = 1; i < num;++i) {
+ if (!params[i])continue;
+ if (!strcmp( params[i], "-b") || !strcmp( params[i], "--binary")) {
+ binary = true;
+ }
+ else if (!strcmp( params[i], "-s") || !strcmp( params[i], "--short")) {
+ shortened = true;
+ }
+ else if (!strcmp( params[i], "-z") || !strcmp( params[i], "--compressed")) {
+ compressed = true;
+ }
+#if 0
+ else if (i > 2 || params[i][0] == '-') {
+ ::printf("Unknown parameter: %s\n",params[i]);
+ return 10;
+ }
+#endif
+ }
+
+ if (out[0] == '-') {
+ // take file name from input file
+ std::string::size_type s = in.find_last_of('.');
+ if (s == std::string::npos) {
+ s = in.length();
+ }
+
+ out = in.substr(0,s);
+ out.append((binary ? ".assbin" : ".assxml"));
+ if (shortened && binary) {
+ out.append(".regress");
+ }
+ }
+
+ // import the main model
+ const aiScene* scene = ImportModel(import,in);
+ if (!scene) {
+ printf("assimp dump: Unable to load input file %s\n",in.c_str());
+ return 5;
+ }
+
+ // open the output file and build the dump
+ FILE* o = ::fopen(out.c_str(),(binary ? "wb" : "wt"));
+ if (!o) {
+ printf("assimp dump: Unable to open output file %s\n",out.c_str());
+ return 12;
+ }
+
+ if (binary) {
+ WriteBinaryDump (scene,o,in.c_str(),cmd.c_str(),shortened,compressed,import);
+ }
+ else WriteDump (scene,o,in.c_str(),cmd.c_str(),shortened);
+ fclose(o);
+
+ if (compressed && binary) {
+ CompressBinaryDump(out.c_str(),ASSBIN_HEADER_LENGTH);
+ }
+
+ printf("assimp dump: Wrote output dump %s\n",out.c_str());
+ return 0;
+}
+
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc
new file mode 100644
index 0000000..e671006
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc
@@ -0,0 +1,51 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+#include "../../revision.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Deutsch (Deutschland) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ASSIMP_VIEW ICON "../shared/assimp_tools_icon.ico"
+
+
+
+
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+#endif
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp
new file mode 100644
index 0000000..8053219
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp
@@ -0,0 +1,113 @@
+/* Boost Software License - Version 1.0 - August 17th, 2003
+ *
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ *
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE. */
+
+
+#ifndef HEADER_GENERIC_INSERTER_HPP_INCLUDED
+#define HEADER_GENERIC_INSERTER_HPP_INCLUDED
+
+
+#include <ostream>
+#include <new> // bad_alloc
+
+
+template <typename char_type, typename traits_type, typename argument_type>
+std::basic_ostream<char_type, traits_type>& generic_inserter(void (*print)(std::basic_ostream<char_type, traits_type>& os, argument_type const& arg), std::basic_ostream<char_type, traits_type>& os, argument_type const& arg)
+{
+ using namespace ::std;
+
+ ios_base::iostate err = ios_base::goodbit;
+ try
+ {
+ typename basic_ostream<char_type, traits_type>::sentry sentry(os);
+ if (sentry)
+ {
+ print(os, arg);
+ err = os.rdstate();
+ os.width(0); // Reset width in case the user didn't do it.
+ }
+ }
+ catch (bad_alloc const&)
+ {
+ err |= ios_base::badbit; // bad_alloc is considered fatal
+ ios_base::iostate const exception_mask = os.exceptions();
+
+ // Two cases: 1.) badbit is not set; 2.) badbit is set
+ if (((exception_mask & ios_base::failbit) != 0) && // failbit shall throw
+ ((exception_mask & ios_base::badbit) == 0)) // badbit shall not throw
+ {
+ // Do not throw unless failbit is set.
+ // If it is set throw ios_base::failure because we don't know what caused the failbit to be set.
+ os.setstate(err);
+ }
+ else if (exception_mask & ios_base::badbit)
+ {
+ try
+ {
+ // This will set the badbit and throw ios_base::failure.
+ os.setstate(err);
+ }
+ catch (ios_base::failure const&)
+ {
+ // Do nothing since we want bad_alloc to be rethrown.
+ }
+ throw;
+ }
+ // else: no exception must get out!
+ }
+ catch (...)
+ {
+ err |= ios_base::failbit; // Any other exception is considered "only" as a failure.
+ ios_base::iostate const exception_mask = os.exceptions();
+
+ // badbit is considered more important
+ if (((exception_mask & ios_base::badbit) != 0) && // badbit shall throw
+ ((err & ios_base::badbit) != 0)) // badbit is set
+ {
+ // Throw ios_base::failure because we don't know what caused the badbit to be set.
+ os.setstate(err);
+ }
+ else if ((exception_mask & ios_base::failbit) != 0)
+ {
+ try
+ {
+ // This will set the failbit and throw the exception ios_base::failure.
+ os.setstate(err);
+ }
+ catch (ios_base::failure const&)
+ {
+ // Do nothing since we want the original exception to be rethrown.
+ }
+ throw;
+ }
+ // else: no exception must get out!
+ }
+
+ // Needed in the case that no exception has been thrown but the stream state has changed.
+ if (err)
+ os.setstate(err);
+ return os;
+}
+
+
+#endif // HEADER_GENERIC_INSERTER_HPP_INCLUDED
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h
new file mode 100644
index 0000000..c516b5e
--- /dev/null
+++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h
@@ -0,0 +1,21 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by assimp_view.rc
+//
+#define IDC_MYICON 2
+#define IDD_ASSIMP_VIEW_DIALOG 102
+#define IDD_ABOUTBOX 103
+#define IDI_ASSIMP_VIEW 107
+
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 159
+#define _APS_NEXT_COMMAND_VALUE 32831
+#define _APS_NEXT_CONTROL_VALUE 1052
+#define _APS_NEXT_SYMED_VALUE 110
+#endif
+#endif