瀏覽代碼

Refactor: Use LF line endings for source files

Richard 10 年之前
父節點
當前提交
c25690f0e4

+ 171 - 171
tools/assimp_cmd/Export.cpp

@@ -1,171 +1,171 @@
-/*
----------------------------------------------------------------------------
-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  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
- 
+/*
+---------------------------------------------------------------------------
+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  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
+ 

+ 377 - 377
tools/assimp_cmd/ImageExtractor.cpp

@@ -1,377 +1,377 @@
-/*
----------------------------------------------------------------------------
-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  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;
-}
+/*
+---------------------------------------------------------------------------
+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  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;
+}

+ 352 - 352
tools/assimp_cmd/Info.cpp

@@ -1,352 +1,352 @@
-/*
----------------------------------------------------------------------------
-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  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(1e10f,1e10f,1e10f);
-	special_points[1] = aiVector3D(-1e10f,-1e10f,-1e10f);
-
-	FindSpecialPoints(scene,scene->mRootNode,special_points);
-	special_points[2] = 0.5f*(special_points[0]+special_points[1]);
-}
-
-// -----------------------------------------------------------------------------------
-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: %i\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;
-}
-
+/*
+---------------------------------------------------------------------------
+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  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(1e10f,1e10f,1e10f);
+	special_points[1] = aiVector3D(-1e10f,-1e10f,-1e10f);
+
+	FindSpecialPoints(scene,scene->mRootNode,special_points);
+	special_points[2] = 0.5f*(special_points[0]+special_points[1]);
+}
+
+// -----------------------------------------------------------------------------------
+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: %i\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;
+}
+

+ 514 - 514
tools/assimp_cmd/Main.cpp

@@ -1,514 +1,514 @@
-/*
----------------------------------------------------------------------------
-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.cpp
- *  @brief main() function of assimp_cmd
- */
-
-#include "Main.h"
-
-const char* AICMD_MSG_ABOUT = 
-"------------------------------------------------------ \n"
-"Open Asset Import Library (\"Assimp\", http://assimp.sourceforge.net) \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\n");	
-		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
-	// -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;
-}
+/*
+---------------------------------------------------------------------------
+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.cpp
+ *  @brief main() function of assimp_cmd
+ */
+
+#include "Main.h"
+
+const char* AICMD_MSG_ABOUT = 
+"------------------------------------------------------ \n"
+"Open Asset Import Library (\"Assimp\", http://assimp.sourceforge.net) \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\n");	
+		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
+	// -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;
+}

+ 208 - 208
tools/assimp_cmd/Main.h

@@ -1,208 +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
+/*
+---------------------------------------------------------------------------
+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

+ 1393 - 1393
tools/assimp_cmd/WriteDumb.cpp

@@ -1,1393 +1,1393 @@
-/*
----------------------------------------------------------------------------
-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  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"
-#include <boost/static_assert.hpp>
-
-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)
-{
-	BOOST_STATIC_ASSERT(sizeof(float)==4);
-	fwrite(&f,4,1,out);
-	return 4;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a double
-template <>
-inline uint32_t Write<double>(const double& f)
-{
-	BOOST_STATIC_ASSERT(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<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);
-	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 += fwrite(tex->achFormatHint,1,4,out);
-
-	if(!shortened) {
-		if (!tex->mHeight) {
-			len += fwrite(tex->pcData,1,tex->mWidth,out);
-		}
-		else {
-			len += 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 += 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 += 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 += 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 += fwrite(mesh->mTangents,1,12*mesh->mNumVertices,out);
-			len += 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 += 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 += 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) {
-					BOOST_STATIC_ASSERT(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];
-
-			BOOST_STATIC_ASSERT(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 += 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 += 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 += 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 += 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<aiVector3D>((const aiVector3D&)l->mColorDiffuse);
-	len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular);
-	len += Write<aiVector3D>((const aiVector3D&)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]; 
-	strncpy(buff,src,256);
-	fwrite(buff,256,1,out);
-
-	strncpy(buff,cmd,128);
-	fwrite(buff,128,1,out);
-
-	// leave 64 bytes free for future extensions
-	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=\"%i\">\n%s\t",
-			prefix,node->mNumMeshes,prefix);
-
-		for (unsigned int i = 0; i < node->mNumMeshes;++i) {
-			fprintf(out,"%i ",node->mMeshes[i]);
-		}
-		fprintf(out,"\n%s\t</MeshRefs>\n",prefix);
-	}
-
-	if (node->mNumChildren) {
-		fprintf(out,"%s\t<NodeList num=\"%i\">\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: %i.%i.%i\n"
-		"  Source: %s\n"
-		"  Command line: %s\n"
-		"  %s\n"
-		"-->"
-		" \n\n"
-		"<Scene flags=\"%i\" 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=\"%i\">\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=\"%i\"> \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=\"%i\">\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=\"%i\">\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=\"%i\"",
-					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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\n",mesh->mNumFaces);
-				for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
-					aiFace& f = mesh->mFaces[n];
-					fprintf(out,"\t\t\t<Face num=\"%i\">\n"
-						"\t\t\t\t",f.mNumIndices);
-
-					for (unsigned int j = 0; j < f.mNumIndices;++j)
-						fprintf(out,"%i ",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=\"%i\" 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=\"%i\" 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=\"%i\" 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=\"%i\" 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=\"%i\" set=\"%i\" num_components=\"%i\"> \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=\"%i\" set=\"%i\" 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;
-}
-
+/*
+---------------------------------------------------------------------------
+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  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"
+#include <boost/static_assert.hpp>
+
+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)
+{
+	BOOST_STATIC_ASSERT(sizeof(float)==4);
+	fwrite(&f,4,1,out);
+	return 4;
+}
+
+// -----------------------------------------------------------------------------------
+// Serialize a double
+template <>
+inline uint32_t Write<double>(const double& f)
+{
+	BOOST_STATIC_ASSERT(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<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);
+	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 += fwrite(tex->achFormatHint,1,4,out);
+
+	if(!shortened) {
+		if (!tex->mHeight) {
+			len += fwrite(tex->pcData,1,tex->mWidth,out);
+		}
+		else {
+			len += 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 += 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 += 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 += 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 += fwrite(mesh->mTangents,1,12*mesh->mNumVertices,out);
+			len += 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 += 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 += 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) {
+					BOOST_STATIC_ASSERT(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];
+
+			BOOST_STATIC_ASSERT(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 += 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 += 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 += 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 += 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<aiVector3D>((const aiVector3D&)l->mColorDiffuse);
+	len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular);
+	len += Write<aiVector3D>((const aiVector3D&)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]; 
+	strncpy(buff,src,256);
+	fwrite(buff,256,1,out);
+
+	strncpy(buff,cmd,128);
+	fwrite(buff,128,1,out);
+
+	// leave 64 bytes free for future extensions
+	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=\"%i\">\n%s\t",
+			prefix,node->mNumMeshes,prefix);
+
+		for (unsigned int i = 0; i < node->mNumMeshes;++i) {
+			fprintf(out,"%i ",node->mMeshes[i]);
+		}
+		fprintf(out,"\n%s\t</MeshRefs>\n",prefix);
+	}
+
+	if (node->mNumChildren) {
+		fprintf(out,"%s\t<NodeList num=\"%i\">\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: %i.%i.%i\n"
+		"  Source: %s\n"
+		"  Command line: %s\n"
+		"  %s\n"
+		"-->"
+		" \n\n"
+		"<Scene flags=\"%i\" 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=\"%i\">\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=\"%i\"> \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=\"%i\">\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=\"%i\">\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=\"%i\"",
+					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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\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=\"%i\">\n",mesh->mNumFaces);
+				for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
+					aiFace& f = mesh->mFaces[n];
+					fprintf(out,"\t\t\t<Face num=\"%i\">\n"
+						"\t\t\t\t",f.mNumIndices);
+
+					for (unsigned int j = 0; j < f.mNumIndices;++j)
+						fprintf(out,"%i ",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=\"%i\" 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=\"%i\" 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=\"%i\" 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=\"%i\" 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=\"%i\" set=\"%i\" num_components=\"%i\"> \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=\"%i\" set=\"%i\" 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;
+}
+

+ 51 - 51
tools/assimp_cmd/assimp_cmd.rc

@@ -1,51 +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
+// 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

+ 21 - 21
tools/assimp_cmd/resource.h

@@ -1,21 +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
+//{{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

+ 1409 - 1409
tools/assimp_view/Shaders.cpp

@@ -1,1410 +1,1410 @@
-/*
----------------------------------------------------------------------------
-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.
----------------------------------------------------------------------------
-*/
-#include "assimp_view.h"
-
-namespace AssimpView  {
-
-// ------------------------------------------------------------------------------------------------
-std::string g_szNormalsShader = std::string(
-
-    // World * View * Projection matrix\n"
-    // NOTE: Assume that the material uses a WorldViewProjection matrix\n"
-    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
-    "float4 OUTPUT_COLOR;\n"
-    
-    // Vertex shader input structure
-    "struct VS_INPUT\n"
-    "{\n"
-        "// Position\n"
-        "float3 Position : POSITION;\n"
-    "};\n"
-
-    // Vertex shader output structure for pixel shader usage
-    "struct VS_OUTPUT\n"
-  "{\n"
-        "float4 Position : POSITION;\n"
-    "};\n"
-
-    // Vertex shader output structure for FixedFunction usage
-    "struct VS_OUTPUT_FF\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-    "float4 Color : COLOR;\n"
-    "};\n"
-
-    // Vertex shader for rendering normals using pixel shader
-    "VS_OUTPUT RenderNormalsVS(VS_INPUT IN)\n"
-    "{\n"
-        "// Initialize the output structure with zero\n"
-        "VS_OUTPUT Out = (VS_OUTPUT)0;\n"
-
-        "// Multiply with the WorldViewProjection matrix\n"
-        "Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
-
-        "return Out;\n"
-    "}\n"
-
-    // Vertex shader for rendering normals using fixed function pipeline
-    "VS_OUTPUT_FF RenderNormalsVS_FF(VS_INPUT IN)\n"
-  "{\n"
-        "VS_OUTPUT_FF Out;\n"
-        "Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
-    "Out.Color = OUTPUT_COLOR;\n"
-        "return Out;\n"
-    "}\n"
-
-    // Pixel shader
-    "float4 RenderNormalsPS() : COLOR\n"
-    "{\n"
-        "return OUTPUT_COLOR;\n"
-    "}\n"
-
-    // Technique for the normal rendering effect (ps_2_0)
-    "technique RenderNormals\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-        "CullMode=none;\n"
-        "PixelShader = compile ps_2_0 RenderNormalsPS();\n"
-        "VertexShader = compile vs_2_0 RenderNormalsVS();\n"
-        "}\n"
-    "};\n"
-
-    // Technique for the normal rendering effect (fixed function)
-    "technique RenderNormals_FF\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-          "CullMode=none;\n"
-          "VertexShader = compile vs_2_0 RenderNormalsVS_FF();\n"
-      "ColorOp[0] = SelectArg1;\n"
-      "ColorArg0[0] = Diffuse;\n"
-      "AlphaOp[0] = SelectArg1;\n"
-      "AlphaArg0[0] = Diffuse;\n"
-        "}\n"
-    "};\n"
-    );
-
-// ------------------------------------------------------------------------------------------------
-std::string g_szSkyboxShader = std::string(
-
-    // Sampler and texture for the skybox
-    "textureCUBE lw_tex_envmap;\n"
-    "samplerCUBE EnvironmentMapSampler = sampler_state\n"
-    "{\n"
-      "Texture = (lw_tex_envmap);\n"
-      "AddressU = CLAMP;\n"
-      "AddressV = CLAMP;\n"
-      "AddressW = CLAMP;\n"
-
-      "MAGFILTER = linear;\n"
-      "MINFILTER = linear;\n"
-    "};\n"
-
-    // World * View * Projection matrix\n"
-    // NOTE: Assume that the material uses a WorldViewProjection matrix\n"
-    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
-    
-    // Vertex shader input structure
-    "struct VS_INPUT\n"
-    "{\n"
-        "float3 Position : POSITION;\n"
-        "float3 Texture0 : TEXCOORD0;\n"
-    "};\n"
-
-    // Vertex shader output structure
-    "struct VS_OUTPUT\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-        "float3 Texture0 : TEXCOORD0;\n"
-    "};\n"
-
-    // Vertex shader
-    "VS_OUTPUT RenderSkyBoxVS(VS_INPUT IN)\n"
-    "{\n"
-        "VS_OUTPUT Out;\n"
-
-        // Multiply with the WorldViewProjection matrix
-        "Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
-
-        // Set z to w to ensure z becomes 1.0 after the division through w occurs
-        "Out.Position.z = Out.Position.w;\n"
-    
-        // Simply pass through texture coordinates
-        "Out.Texture0 = IN.Texture0;\n"
-
-        "return Out;\n"
-    "}\n"
-
-    // Pixel shader
-    "float4 RenderSkyBoxPS(float3 Texture0 : TEXCOORD0) : COLOR\n"
-    "{\n"
-        // Lookup the skybox texture
-        "return texCUBE(EnvironmentMapSampler,Texture0) ;\n"
-    "}\n"
-
-    // Technique for the skybox shader (ps_2_0)
-    "technique RenderSkyBox\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-          "ZWriteEnable = FALSE;\n"
-          "FogEnable = FALSE;\n"
-          "CullMode = NONE;\n"
-
-          "PixelShader = compile ps_2_0 RenderSkyBoxPS();\n"
-          "VertexShader = compile vs_2_0 RenderSkyBoxVS();\n"
-        "}\n"
-    "};\n"
-
-  // -------------- same for static background image -----------------
-    "texture TEXTURE_2D;\n"
-    "sampler TEXTURE_SAMPLER = sampler_state\n"
-    "{\n"
-        "Texture = (TEXTURE_2D);\n"
-    "};\n"
-
-    "struct VS_OUTPUT2\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-        "float2 TexCoord0 : TEXCOORD0;\n"
-    "};\n"
-
-    "VS_OUTPUT2 RenderImageVS(float4 INPosition : POSITION, float2 INTexCoord0 : TEXCOORD0 )\n"
-    "{\n"
-        "VS_OUTPUT2 Out;\n"
-
-        "Out.Position.xy = INPosition.xy;\n"
-        "Out.Position.z = Out.Position.w = 1.0f;\n"
-        "Out.TexCoord0 = INTexCoord0;\n"
-
-        "return Out;\n"
-    "}\n"
-
-    "float4 RenderImagePS(float2 IN : TEXCOORD0) : COLOR\n"
-    "{\n"
-        "return tex2D(TEXTURE_SAMPLER,IN);\n"
-    "}\n"
-
-    // Technique for the background image shader (ps_2_0)
-    "technique RenderImage2D\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "ZWriteEnable = FALSE;\n"
-            "FogEnable = FALSE;\n"
-            "CullMode = NONE;\n"
-    
-            "PixelShader = compile ps_2_0 RenderImagePS();\n"
-            "VertexShader = compile vs_2_0 RenderImageVS();\n"
-        "}\n"
-    "};\n"
-    );
-
-std::string g_szDefaultShader = std::string(
-
-    // World * View * Projection matrix
-    // NOTE: Assume that the material uses a WorldViewProjection matrix
-    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
-    "float4x4 World					: WORLD;\n"
-    "float4x3 WorldInverseTranspose	: WORLDINVERSETRANSPOSE;\n"
-
-    // light colors
-    "float3 afLightColor[5];\n"
-    // light direction
-    "float3 afLightDir[5];\n"
-
-    // position of the camera in worldspace\n"
-    "float3 vCameraPos : CAMERAPOSITION;\n"
-
-    // Bone matrices
-//	"#ifdef AV_SKINNING \n"
-    "float4x3 gBoneMatrix[60]; \n"
-//	"#endif // AV_SKINNING \n"
-
-    // Vertex shader input structure
-    "struct VS_INPUT\n"
-    "{\n"
-        "float3 Position : POSITION;\n"
-        "float3 Normal : NORMAL;\n"
-//		"#ifdef AV_SKINNING \n"
-            "float4 BlendIndices : BLENDINDICES;\n"
-            "float4 BlendWeights : BLENDWEIGHT;\n"
-//		"#endif // AV_SKINNING \n"
-    "};\n"
-
-    // Vertex shader output structure for pixel shader usage
-    "struct VS_OUTPUT\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-        "float3 ViewDir : TEXCOORD0;\n"
-        "float3 Normal : TEXCOORD1;\n"
-    "};\n"
-
-    // Vertex shader output structure for fixed function
-    "struct VS_OUTPUT_FF\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-        "float4 Color : COLOR;\n"
-    "};\n"
-
-    // Vertex shader for pixel shader usage
-    "VS_OUTPUT DefaultVShader(VS_INPUT IN)\n"
-    "{\n"
-        "VS_OUTPUT Out;\n"
-
-//		"#ifdef AV_SKINNING \n"
-        "float4 weights = IN.BlendWeights; \n"
-        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
-        "float4 localPos = float4( IN.Position, 1.0f); \n"
-        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
-//		"#else \n"
-//		"float3 objPos = IN.Position; \n"
-//		"#endif // AV_SKINNING \n"
-
-        // Multiply with the WorldViewProjection matrix
-        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
-        "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
-        "Out.ViewDir = vCameraPos - WorldPos;\n"
-        "Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
-
-        "return Out;\n"
-    "}\n"
-
-    // Vertex shader for fixed function pipeline
-    "VS_OUTPUT_FF DefaultVShader_FF(VS_INPUT IN)\n"
-    "{\n"
-        "VS_OUTPUT_FF Out;\n"
-
-//		"#ifdef AV_SKINNING \n"
-        "float4 weights = IN.BlendWeights; \n"
-        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
-        "float4 localPos = float4( IN.Position, 1.0f); \n"
-        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
-//		"#else \n"
-//		"float3 objPos = IN.Position; \n"
-//		"#endif // AV_SKINNING \n"
-
-        // Multiply with the WorldViewProjection matrix
-        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
-
-        "float3 worldNormal = normalize( mul( IN.Normal, (float3x3) WorldInverseTranspose)); \n"
-
-        // per-vertex lighting. We simply assume light colors of unused lights to be black
-        "Out.Color = float4( 0.2f, 0.2f, 0.2f, 1.0f); \n"
-        "for( int a = 0; a < 2; a++)\n"
-        "  Out.Color.rgb += saturate( dot( afLightDir[a], worldNormal)) * afLightColor[a].rgb; \n"
-            "return Out;\n"
-    "}\n"
-
-    // Pixel shader for one light
-    "float4 DefaultPShaderSpecular_D1(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "float3 Normal = normalize(IN.Normal);\n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-
-        "{\n"
-            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
-            "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
-            "float fHalfLambert = L1*L1;\n"
-            "OUT.rgb += afLightColor[0] * (fHalfLambert +\n"
-                "saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,ViewDir),9));\n"
-        "}\n"
-        "return OUT;\n"
-    "}\n"
-
-    // Pixel shader for two lights
-    "float4 DefaultPShaderSpecular_D2(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "float3 Normal = normalize(IN.Normal);\n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-
-        "{\n"
-            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
-            "float3 Reflect = reflect (ViewDir,Normal);\n"
-            "float fHalfLambert = L1*L1;\n"
-            "OUT.rgb += afLightColor[0] * (fHalfLambert +\n"
-            "saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,afLightDir[0]),9));\n"
-        "}\n"
-        "{\n"
-            "float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
-            "float3 Reflect = reflect (ViewDir,Normal);\n"
-            "float fHalfLambert = L1*L1;\n"
-            "OUT.rgb += afLightColor[1] * (fHalfLambert +\n"
-            "saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,afLightDir[1]),9));\n"
-        "}\n"
-        "return OUT;\n"
-    "}\n"
-    // ----------------------------------------------------------------------------
-    "float4 DefaultPShaderSpecular_PS20_D1(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "float3 Normal = normalize(IN.Normal);\n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-
-        "{\n"
-            "float L1 = dot(Normal,afLightDir[0]);\n"
-            "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
-            "OUT.rgb += afLightColor[0] * ((L1) +\n"
-            "pow(dot(Reflect,ViewDir),9));\n"
-        "}\n"
-
-        "return OUT;\n"
-    "}\n"
-    // ----------------------------------------------------------------------------
-    "float4 DefaultPShaderSpecular_PS20_D2(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "float3 Normal = normalize(IN.Normal);\n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-
-        "{\n"
-            "float L1 = dot(Normal,afLightDir[0]);\n"
-            "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
-            "OUT.rgb += afLightColor[0] * ((L1) +\n"
-            "pow(dot(Reflect,ViewDir),9));\n"
-        "}\n"
-        "{\n"
-            "float L1 = dot(Normal,afLightDir[1]);\n"
-            "float3 Reflect = reflect (Normal,afLightDir[1]);\n"
-            "OUT.rgb += afLightColor[1] * ((L1) +\n"
-            "pow(dot(Reflect,ViewDir),9));\n"
-        "}\n"
-        "return OUT;\n"
-    "}\n"
-
-
-    // Technique for the default effect
-    "technique DefaultFXSpecular_D1\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "CullMode=none;\n"
-            "PixelShader = compile ps_3_0 DefaultPShaderSpecular_D1();\n"
-            "VertexShader = compile vs_3_0 DefaultVShader();\n"
-        "}\n"
-    "};\n"
-    "technique DefaultFXSpecular_D2\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "CullMode=none;\n"
-            "PixelShader = compile ps_3_0 DefaultPShaderSpecular_D2();\n"
-            "VertexShader = compile vs_3_0 DefaultVShader();\n"
-        "}\n"
-    "};\n"
-
-    // Technique for the default effect (ps_2_0)
-    "technique DefaultFXSpecular_PS20_D1\n"
-    "{\n"
-        "pass p0\n"
-    "{\n"
-          "CullMode=none;\n"
-          "PixelShader = compile ps_2_0 DefaultPShaderSpecular_PS20_D1();\n"
-          "VertexShader = compile vs_2_0 DefaultVShader();\n"
-        "}\n"
-    "};\n"
-    "technique DefaultFXSpecular_PS20_D2\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-          "CullMode=none;\n"
-          "PixelShader = compile ps_2_0 DefaultPShaderSpecular_PS20_D2();\n"
-          "VertexShader = compile vs_2_0 DefaultVShader();\n"
-        "}\n"
-    "};\n"
-
-    // Technique for the default effect using the fixed function pixel pipeline
-    "technique DefaultFXSpecular_FF\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "CullMode=none;\n"
-            "VertexShader = compile vs_2_0 DefaultVShader_FF();\n"
-            "ColorOp[0] = SelectArg1;\n"
-            "ColorArg0[0] = Diffuse;\n"
-            "AlphaOp[0] = SelectArg1;\n"
-            "AlphaArg0[0] = Diffuse;\n"
-        "}\n"
-    "};\n"
-  );
-
-
-std::string g_szMaterialShader = std::string(
-
-    // World * View * Projection matrix
-  // NOTE: Assume that the material uses a WorldViewProjection matrix
-    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
-    "float4x4 World					: WORLD;\n"
-    "float4x3 WorldInverseTranspose	: WORLDINVERSETRANSPOSE;\n"
-
-    "#ifndef AV_DISABLESSS\n"
-    "float4x3 ViewProj;\n"
-    "float4x3 InvViewProj;\n"
-    "#endif\n"
-
-    "float4 DIFFUSE_COLOR;\n"
-    "float4 SPECULAR_COLOR;\n"
-    "float4 AMBIENT_COLOR;\n"
-    "float4 EMISSIVE_COLOR;\n"
-
-    "#ifdef AV_SPECULAR_COMPONENT\n"
-    "float SPECULARITY;\n"
-    "float SPECULAR_STRENGTH;\n"
-    "#endif\n"
-    "#ifdef AV_OPACITY\n"
-    "float TRANSPARENCY;\n"
-    "#endif\n"
-
-    // light colors (diffuse and specular)
-    "float4 afLightColor[5];\n"
-    "float4 afLightColorAmbient[5];\n"
-
-    // light direction
-    "float3 afLightDir[5];\n"
-
-    // position of the camera in worldspace
-    "float3 vCameraPos : CAMERAPOSITION;\n"
-
-    // Bone matrices
-    "#ifdef AV_SKINNING \n"
-    "float4x3 gBoneMatrix[60]; \n"
-    "#endif // AV_SKINNING \n"
-
-    "#ifdef AV_DIFFUSE_TEXTURE\n"
-        "texture DIFFUSE_TEXTURE;\n"
-        "sampler DIFFUSE_SAMPLER\n"
-        "{\n"
-          "Texture = <DIFFUSE_TEXTURE>;\n"
-          "#ifdef AV_WRAPU\n"
-          "AddressU = WRAP;\n"
-          "#endif\n"
-          "#ifdef AV_MIRRORU\n"
-          "AddressU = MIRROR;\n"
-          "#endif\n"
-          "#ifdef AV_CLAMPU\n"
-          "AddressU = CLAMP;\n"
-          "#endif\n"
-          "#ifdef AV_WRAPV\n"
-          "AddressV = WRAP;\n"
-          "#endif\n"
-          "#ifdef AV_MIRRORV\n"
-          "AddressV = MIRROR;\n"
-          "#endif\n"
-          "#ifdef AV_CLAMPV\n"
-          "AddressV = CLAMP;\n"
-          "#endif\n"
-        "};\n"
-    "#endif // AV_DIFFUSE_TEXTUR\n"
-
-    "#ifdef AV_DIFFUSE_TEXTURE2\n"
-        "texture DIFFUSE_TEXTURE2;\n"
-        "sampler DIFFUSE_SAMPLER2\n"
-        "{\n"
-          "Texture = <DIFFUSE_TEXTURE2>;\n"
-        "};\n"
-    "#endif // AV_DIFFUSE_TEXTUR2\n"
-
-    "#ifdef AV_SPECULAR_TEXTURE\n"
-        "texture SPECULAR_TEXTURE;\n"
-        "sampler SPECULAR_SAMPLER\n"
-        "{\n"
-          "Texture = <SPECULAR_TEXTURE>;\n"
-        "};\n"
-    "#endif // AV_SPECULAR_TEXTUR\n"
-
-    "#ifdef AV_AMBIENT_TEXTURE\n"
-        "texture AMBIENT_TEXTURE;\n"
-        "sampler AMBIENT_SAMPLER\n"
-        "{\n"
-          "Texture = <AMBIENT_TEXTURE>;\n"
-        "};\n"
-    "#endif // AV_AMBIENT_TEXTUR\n"
-
-    "#ifdef AV_LIGHTMAP_TEXTURE\n"
-        "texture LIGHTMAP_TEXTURE;\n"
-        "sampler LIGHTMAP_SAMPLER\n"
-        "{\n"
-          "Texture = <LIGHTMAP_TEXTURE>;\n"
-        "};\n"
-    "#endif // AV_LIGHTMAP_TEXTURE\n"
-
-    "#ifdef AV_OPACITY_TEXTURE\n"
-        "texture OPACITY_TEXTURE;\n"
-        "sampler OPACITY_SAMPLER\n"
-        "{\n"
-          "Texture = <OPACITY_TEXTURE>;\n"
-        "};\n"
-    "#endif // AV_OPACITY_TEXTURE\n"
-
-    "#ifdef AV_EMISSIVE_TEXTURE\n"
-        "texture EMISSIVE_TEXTURE;\n"
-        "sampler EMISSIVE_SAMPLER\n"
-        "{\n"
-          "Texture = <EMISSIVE_TEXTURE>;\n"
-        "};\n"
-    "#endif // AV_EMISSIVE_TEXTUR\n"
-
-    "#ifdef AV_NORMAL_TEXTURE\n"
-        "texture NORMAL_TEXTURE;\n"
-        "sampler NORMAL_SAMPLER\n"
-        "{\n"
-          "Texture = <NORMAL_TEXTURE>;\n"
-        "};\n"
-    "#endif // AV_NORMAL_TEXTURE\n"
-
-    "#ifdef AV_SKYBOX_LOOKUP\n"
-        "textureCUBE lw_tex_envmap;\n"
-        "samplerCUBE EnvironmentMapSampler = sampler_state\n"
-        "{\n"
-          "Texture = (lw_tex_envmap);\n"
-          "AddressU = CLAMP;\n"
-          "AddressV = CLAMP;\n"
-          "AddressW = CLAMP;\n"
-
-          "MAGFILTER = linear;\n"
-          "MINFILTER = linear;\n"
-        "};\n"
-    "#endif // AV_SKYBOX_LOOKUP\n"
-
-    // Vertex shader input structure
-    "struct VS_INPUT\n"
-    "{\n"
-        "float3 Position : POSITION;\n"
-        "float3 Normal : NORMAL;\n"
-        "float4 Color : COLOR0;\n"
-        "float3 Tangent   : TANGENT;\n"
-        "float3 Bitangent : BINORMAL;\n"
-        "float2 TexCoord0 : TEXCOORD0;\n"
-        "#ifdef AV_TWO_UV \n"
-        "float2 TexCoord1 : TEXCOORD1;\n"
-        "#endif \n"
-          "#ifdef AV_SKINNING \n"
-            "float4 BlendIndices : BLENDINDICES;\n"
-            "float4 BlendWeights : BLENDWEIGHT;\n"
-         "#endif // AV_SKINNING \n"
-    "};\n"
-
-    // Vertex shader output structure for pixel shader usage
-    "struct VS_OUTPUT\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-        "float3 ViewDir : TEXCOORD0;\n"
-
-        "float4 Color : COLOR0;\n"
-
-        "#ifndef AV_NORMAL_TEXTURE\n"
-        "float3 Normal  : TEXCOORD1;\n"
-        "#endif\n"
-
-        "float2 TexCoord0 : TEXCOORD2;\n"
-        "#ifdef AV_TWO_UV \n"
-        "float2 TexCoord1 : TEXCOORD3;\n"
-        "#endif \n"
-
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3 Light0 : TEXCOORD3;\n"
-        "float3 Light1 : TEXCOORD4;\n"
-        "#endif\n"
-    "};\n"
-
-    // Vertex shader output structure for fixed function pixel pipeline
-    "struct VS_OUTPUT_FF\n"
-    "{\n"
-        "float4 Position : POSITION;\n"
-        "float4 DiffuseColor : COLOR0;\n"
-        "float4 SpecularColor : COLOR1;\n"
-        "float2 TexCoord0 : TEXCOORD0;\n"
-    "};\n"
-
-
-    // Selective SuperSampling in screenspace for reflection lookups
-    "#define GetSSSCubeMap(_refl) (texCUBElod(EnvironmentMapSampler,float4(_refl,0.0f)).rgb) \n"
-
-
-    // Vertex shader for pixel shader usage and one light
-    "VS_OUTPUT MaterialVShader_D1(VS_INPUT IN)\n"
-    "{\n"
-        "VS_OUTPUT Out = (VS_OUTPUT)0;\n"
-
-        "#ifdef AV_SKINNING \n"
-        "float4 weights = IN.BlendWeights; \n"
-        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
-        "float4 localPos = float4( IN.Position, 1.0f); \n"
-        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
-        "#else \n"
-        "float3 objPos = IN.Position; \n"
-        "#endif // AV_SKINNING \n"
-
-        // Multiply with the WorldViewProjection matrix
-        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
-        "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
-        "Out.TexCoord0 = IN.TexCoord0;\n"
-        "#ifdef AV_TWO_UV \n"
-        "Out.TexCoord1 = IN.TexCoord1;\n"
-        "#endif\n"
-        "Out.Color = IN.Color;\n"
-
-        "#ifndef AV_NORMAL_TEXTURE\n"
-        "Out.ViewDir = vCameraPos - WorldPos;\n"
-        "Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
-        "#endif\n"
-        
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3x3 TBNMatrix = float3x3(IN.Tangent, IN.Bitangent, IN.Normal);\n"
-        "float3x3 WTTS      = mul(TBNMatrix, (float3x3)WorldInverseTranspose);\n"
-        "Out.Light0         = normalize(mul(WTTS, afLightDir[0] ));\n"
-        "Out.ViewDir = normalize(mul(WTTS, (vCameraPos - WorldPos)));\n"
-        "#endif\n"
-        "return Out;\n"
-    "}\n"
-
-    // Vertex shader for pixel shader usage and two lights
-    "VS_OUTPUT MaterialVShader_D2(VS_INPUT IN)\n"
-    "{\n"
-        "VS_OUTPUT Out = (VS_OUTPUT)0;\n"
-
-        "#ifdef AV_SKINNING \n"
-        "float4 weights = IN.BlendWeights; \n"
-        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
-        "float4 localPos = float4( IN.Position, 1.0f); \n"
-        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
-        "#else \n"
-        "float3 objPos = IN.Position; \n"
-        "#endif // AV_SKINNING \n"
-
-        // Multiply with the WorldViewProjection matrix
-        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
-        "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
-        "Out.TexCoord0 = IN.TexCoord0;\n"
-        "#ifdef AV_TWO_UV \n"
-        "Out.TexCoord1 = IN.TexCoord1;\n"
-        "#endif\n"
-        "Out.Color = IN.Color;\n"
-
-        "#ifndef AV_NORMAL_TEXTURE\n"
-        "Out.ViewDir = vCameraPos - WorldPos;\n"
-        "Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
-        "#endif\n"
-
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3x3 TBNMatrix = float3x3(IN.Tangent, IN.Bitangent, IN.Normal);\n"
-        "float3x3 WTTS      = mul(TBNMatrix, (float3x3)WorldInverseTranspose);\n"
-        "Out.Light0         = normalize(mul(WTTS, afLightDir[0] ));\n"
-        "Out.Light1         = normalize(mul(WTTS, afLightDir[1] ));\n"
-        "Out.ViewDir = normalize(mul(WTTS, (vCameraPos - WorldPos)));\n"
-        "#endif\n"
-        "return Out;\n"
-    "}\n"
-
-    // Vertex shader for zero to five lights using the fixed function pixel pipeline
-    "VS_OUTPUT_FF MaterialVShader_FF(VS_INPUT IN)\n"
-    "{\n"
-        "VS_OUTPUT_FF Out = (VS_OUTPUT_FF)0;\n"
-
-        "#ifdef AV_SKINNING \n"
-        "float4 weights = IN.BlendWeights; \n"
-        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
-        "float4 localPos = float4( IN.Position, 1.0f); \n"
-        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
-        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
-        "#else \n"
-        "float3 objPos = IN.Position; \n"
-        "#endif // AV_SKINNING \n"
-
-        // Multiply with the WorldViewProjection matrix
-        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
-        "float3 worldPos = mul( float4( objPos, 1.0f), World);\n"
-        "float3 worldNormal = normalize( mul( IN.Normal, (float3x3) WorldInverseTranspose)); \n"
-        "Out.TexCoord0 = IN.TexCoord0;\n"
-
-        // calculate per-vertex diffuse lighting including ambient part
-        "float4 diffuseColor = float4( 0.0f, 0.0f, 0.0f, 1.0f); \n"
-        "for( int a = 0; a < 2; a++) \n"
-        "  diffuseColor.rgb += saturate( dot( afLightDir[a], worldNormal)) * afLightColor[a].rgb; \n"
-        // factor in material properties and a bit of ambient lighting
-        "Out.DiffuseColor = diffuseColor * DIFFUSE_COLOR + float4( 0.2f, 0.2f, 0.2f, 1.0f) * AMBIENT_COLOR; ; \n"
-
-        // and specular including emissive part
-        "float4 specularColor = float4( 0.0f, 0.0f, 0.0f, 1.0f); \n"
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-        "float3 viewDir = normalize( worldPos - vCameraPos); \n"
-        "for( int a = 0; a < 2; a++) \n"
-        "{ \n"
-        "  float3 reflDir = reflect( afLightDir[a], worldNormal); \n"
-        "  float specIntensity = pow( saturate( dot( reflDir, viewDir)), SPECULARITY) * SPECULAR_STRENGTH; \n"
-        "  specularColor.rgb += afLightColor[a] * specIntensity; \n"
-        "} \n"
-        "#endif // AV_SPECULAR_COMPONENT\n"
-        // factor in material properties and the emissive part
-        "Out.SpecularColor = specularColor * SPECULAR_COLOR + EMISSIVE_COLOR; \n"
-
-        "return Out;\n"
-    "}\n"
-
-
-    // Pixel shader - one light
-    "float4 MaterialPShaderSpecular_D1(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3 IN_Light0 = normalize(IN.Light0);\n"
-        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
-        "#else\n"
-        "float3 Normal = normalize(IN.Normal);\n"
-        "#endif \n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-            "float3 Reflect = normalize(reflect (-ViewDir,Normal));\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-
-        "{\n"
-        "#ifdef AV_NORMAL_TEXTURE\n"
-            "float L1 =  dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
-            "#define AV_LIGHT_0 IN_Light0\n"
-            // would need to convert the reflection vector into world space ....
-            // simply let it ...
-        "#else\n"
-            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
-            "#define AV_LIGHT_0 afLightDir[0]\n"
-        "#endif\n"
-        "#ifdef AV_DIFFUSE_TEXTURE2\n"
-            "float fHalfLambert = 1.f;\n"
-        "#else\n"
-            "float fHalfLambert = L1*L1;\n"
-        "#endif \n"
-        "#ifdef AV_DIFFUSE_TEXTURE\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert * IN.Color.rgb +\n"
-        "#else\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert * IN.Color.rgb +\n"
-        "#endif // !AV_DIFFUSE_TEXTURE\n"
-
-        
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-            "#ifndef AV_SKYBOX_LOOKUP\n"
-                "#ifdef AV_SPECULAR_TEXTURE\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#else\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#endif // !AV_SPECULAR_TEXTURE\n"
-            "#else\n"
-                "#ifdef AV_SPECULAR_TEXTURE\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#else\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#endif // !AV_SPECULAR_TEXTURE\n"
-            "#endif // !AV_SKYBOX_LOOKUP\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-
-        "#ifdef AV_AMBIENT_TEXTURE\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
-        "#else\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb + \n"
-        "#endif // !AV_AMBIENT_TEXTURE\n"
-            "#ifdef AV_EMISSIVE_TEXTURE\n"
-            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
-        "#else \n"
-            "EMISSIVE_COLOR.rgb;\n"
-        "#endif // !AV_EMISSIVE_TEXTURE\n"
-        "}\n"
-        "#ifdef AV_OPACITY\n"
-        "OUT.a = TRANSPARENCY;\n"
-        "#endif\n"
-        "#ifdef AV_LIGHTMAP_TEXTURE\n"
-        "OUT.rgb *= tex2D(LIGHTMAP_SAMPLER,AV_LIGHTMAP_TEXTURE_UV_COORD).rgb*LM_STRENGTH;\n"
-        "#endif\n"
-        "#ifdef AV_OPACITY_TEXTURE\n"
-        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
-        "#endif\n"
-        "return OUT;\n"
-
-        "#undef AV_LIGHT_0\n"
-    "}\n"
-
-    // Pixel shader - two lights
-    "float4 MaterialPShaderSpecular_D2(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3 IN_Light0 = normalize(IN.Light0);\n"
-        "float3 IN_Light1 = normalize(IN.Light1);\n"
-        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
-        "#else\n"
-        "float3 Normal = normalize(IN.Normal);\n"
-        "#endif \n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-            "float3 Reflect = -normalize(reflect (ViewDir,Normal));\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-
-        "{\n"
-        
-        "#ifdef AV_NORMAL_TEXTURE\n"
-            "float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
-            "#define AV_LIGHT_0 IN_Light0\n"
-        "#else\n"
-            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
-            "#define AV_LIGHT_0 afLightDir[0]\n"
-        "#endif\n"
-            "float fHalfLambert = L1*L1;\n"
-            
-        "#ifdef AV_DIFFUSE_TEXTURE\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert  * IN.Color.rgb +\n"
-        "#else\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert  * IN.Color.rgb +\n"
-        "#endif // !AV_DIFFUSE_TEXTURE\n"
-
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-            "#ifndef AV_SKYBOX_LOOKUP\n"
-                "#ifdef AV_SPECULAR_TEXTURE\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#else\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#endif // !AV_SPECULAR_TEXTURE\n"
-            "#else\n"
-                "#ifdef AV_SPECULAR_TEXTURE\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#else\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
-                "#endif // !AV_SPECULAR_TEXTURE\n"
-            "#endif // !AV_SKYBOX_LOOKUP\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_AMBIENT_TEXTURE\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb + \n"
-        "#else\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb + \n"
-        "#endif // !AV_AMBIENT_TEXTURE\n"
-        "#ifdef AV_EMISSIVE_TEXTURE\n"
-            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
-        "#else \n"
-            "EMISSIVE_COLOR.rgb;\n"
-        "#endif // !AV_EMISSIVE_TEXTURE\n"
-        "}\n"
-        "{\n"
-        "#ifdef AV_NORMAL_TEXTURE\n"
-            "float L1 = dot(Normal,IN_Light1) * 0.5f + 0.5f;\n"
-            "#define AV_LIGHT_1 IN_Light1\n"
-        "#else\n"
-            "float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
-            "#define AV_LIGHT_1 afLightDir[1]\n"
-        "#endif\n"
-            "float fHalfLambert = L1*L1;\n"
-        "#ifdef AV_DIFFUSE_TEXTURE\n"
-            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert  * IN.Color.rgb +\n"
-        "#else\n"
-            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * fHalfLambert   * IN.Color.rgb +\n"
-        "#endif // !AV_DIFFUSE_TEXTURE\n"
-
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-            "#ifndef AV_SKYBOX_LOOKUP\n"
-                "#ifdef AV_SPECULAR_TEXTURE\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
-                "#else\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
-                "#endif // !AV_SPECULAR_TEXTURE\n"
-            "#else\n"
-                "#ifdef AV_SPECULAR_TEXTURE\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
-                "#else\n"
-                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
-                "#endif // !AV_SPECULAR_TEXTURE\n"
-            "#endif // !AV_SKYBOX_LOOKUP\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_AMBIENT_TEXTURE\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb + \n"
-        "#else\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb + \n"
-        "#endif // !AV_AMBIENT_TEXTURE\n"
-        "#ifdef AV_EMISSIVE_TEXTURE\n"
-            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
-        "#else \n"
-            "EMISSIVE_COLOR.rgb;\n"
-        "#endif // !AV_EMISSIVE_TEXTURE\n"
-        "}\n"
-        "#ifdef AV_OPACITY\n"
-        "OUT.a = TRANSPARENCY;\n"
-        "#endif\n"
-        "#ifdef AV_LIGHTMAP_TEXTURE\n"
-        "OUT.rgb *= tex2D(LIGHTMAP_SAMPLER,AV_LIGHTMAP_TEXTURE_UV_COORD).rgb*LM_STRENGTH;\n"
-        "#endif\n"
-        "#ifdef AV_OPACITY_TEXTURE\n"
-        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
-        "#endif\n"
-        "return OUT;\n"
-
-        "#undef AV_LIGHT_0\n"
-        "#undef AV_LIGHT_1\n"
-    "}\n"
-
-    // Same pixel shader again, one light
-    "float4 MaterialPShaderSpecular_PS20_D1(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3 IN_Light0 = normalize(IN.Light0);\n"
-        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
-        "#else\n"
-        "float3 Normal = normalize(IN.Normal);\n"
-        "#endif \n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-
-        "{\n"
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
-        "float3 Reflect = reflect (Normal,IN_Light0);\n"
-        "#else\n"
-        "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
-        "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
-        "#endif\n"
-        "#ifdef AV_DIFFUSE_TEXTURE\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
-        "#else\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
-        "#endif // !AV_DIFFUSE_TEXTURE\n"
-
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_SPECULAR_TEXTURE\n"
-            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
-        "#else\n"
-            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
-        "#endif // !AV_SPECULAR_TEXTURE\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_AMBIENT_TEXTURE\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
-        "#else\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb +\n"
-        "#endif // !AV_AMBIENT_TEXTURE\n"
-        "#ifdef AV_EMISSIVE_TEXTURE\n"
-            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
-        "#else \n"
-            "EMISSIVE_COLOR.rgb;\n"
-        "#endif // !AV_EMISSIVE_TEXTURE\n"
-        "}\n"
-
-        "#ifdef AV_OPACITY\n"
-        "OUT.a = TRANSPARENCY;\n"
-        "#endif\n"
-        "#ifdef AV_OPACITY_TEXTURE\n"
-        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
-        "#endif\n"
-        "return OUT;\n"
-    "}\n"
-
-    // Same pixel shader again, two lights
-    "float4 MaterialPShaderSpecular_PS20_D2(VS_OUTPUT IN) : COLOR\n"
-    "{\n"
-        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
-
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float3 IN_Light0 = normalize(IN.Light0);\n"
-        "float3 IN_Light1 = normalize(IN.Light1);\n"
-        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0) - 1.0f);\n"
-        "#else\n"
-        "float3 Normal = normalize(IN.Normal);\n"
-        "#endif \n"
-        "float3 ViewDir = normalize(IN.ViewDir);\n"
-
-        "{\n"
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
-        "float3 Reflect = reflect (Normal,IN_Light0);\n"
-        "#else\n"
-        "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
-        "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
-        "#endif\n"
-        "#ifdef AV_DIFFUSE_TEXTURE\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
-        "#else\n"
-            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
-        "#endif // !AV_DIFFUSE_TEXTURE\n"
-
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_SPECULAR_TEXTURE\n"
-            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
-        "#else\n"
-            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
-        "#endif // !AV_SPECULAR_TEXTURE\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_AMBIENT_TEXTURE\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
-        "#else\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb +\n"
-        "#endif // !AV_AMBIENT_TEXTURE\n"
-        "#ifdef AV_EMISSIVE_TEXTURE\n"
-            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
-        "#else \n"
-            "EMISSIVE_COLOR.rgb;\n"
-        "#endif // !AV_EMISSIVE_TEXTURE\n"
-        "}\n"
-        "{\n"
-        "#ifdef AV_NORMAL_TEXTURE\n"
-        "float L1 = dot(Normal,IN_Light1) * 0.5f + 0.5f;\n"
-        "float3 Reflect = reflect (Normal,IN_Light1);\n"
-        "#else\n"
-        "float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
-        "float3 Reflect = reflect (Normal,afLightDir[1]);\n"
-        "#endif\n"
-        "#ifdef AV_DIFFUSE_TEXTURE\n"
-            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
-        "#else\n"
-            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
-        "#endif // !AV_DIFFUSE_TEXTURE\n"
-
-        "#ifdef AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_SPECULAR_TEXTURE\n"
-            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
-        "#else\n"
-            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
-        "#endif // !AV_SPECULAR_TEXTURE\n"
-        "#endif // !AV_SPECULAR_COMPONENT\n"
-        "#ifdef AV_AMBIENT_TEXTURE\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
-        "#else\n"
-            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb + \n"
-        "#endif // !AV_AMBIENT_TEXTURE\n"
-        "#ifdef AV_EMISSIVE_TEXTURE\n"
-            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
-        "#else \n"
-            "EMISSIVE_COLOR.rgb;\n"
-        "#endif // !AV_EMISSIVE_TEXTURE\n"
-        "}\n"
-
-        "#ifdef AV_OPACITY\n"
-        "OUT.a = TRANSPARENCY;\n"
-        "#endif\n"
-        "#ifdef AV_OPACITY_TEXTURE\n"
-        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
-        "#endif\n"
-        "return OUT;\n"
-    "}\n"
-
-
-    // Technique for the material effect
-    "technique MaterialFXSpecular_D1\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "#ifdef AV_OPACITY_TEXTURE\n"
-            "AlphaBlendEnable=TRUE;"
-            "SrcBlend = srcalpha;\n"
-            "DestBlend = invsrcalpha;\n"
-            "#else\n"
-            "#ifdef AV_OPACITY\n"
-            "AlphaBlendEnable=TRUE;"
-            "SrcBlend = srcalpha;\n"
-            "DestBlend = invsrcalpha;\n"
-            "#endif \n"
-            "#endif\n"
-
-            "PixelShader = compile ps_3_0 MaterialPShaderSpecular_D1();\n"
-            "VertexShader = compile vs_3_0 MaterialVShader_D1();\n"
-        "}\n"
-    "};\n"
-    "technique MaterialFXSpecular_D2\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "#ifdef AV_OPACITY_TEXTURE\n"
-            "AlphaBlendEnable=TRUE;"
-            "SrcBlend = srcalpha;\n"
-            "DestBlend = invsrcalpha;\n"
-            "#else\n"
-            "#ifdef AV_OPACITY\n"
-            "AlphaBlendEnable=TRUE;"
-            "SrcBlend = srcalpha;\n"
-            "DestBlend = invsrcalpha;\n"
-            "#endif \n"
-            "#endif\n"
-
-            "PixelShader = compile ps_3_0 MaterialPShaderSpecular_D2();\n"
-            "VertexShader = compile vs_3_0 MaterialVShader_D2();\n"
-        "}\n"
-    "};\n"
-
-    // Technique for the material effect (ps_2_0)
-    "technique MaterialFXSpecular_PS20_D1\n"
-    "{\n"
-        "pass p0\n"
-    "{\n"
-          "#ifdef AV_OPACITY_TEXTURE\n"
-          "AlphaBlendEnable=TRUE;"
-          "SrcBlend = srcalpha;\n"
-          "DestBlend = invsrcalpha;\n"
-          "#else\n"
-          "#ifdef AV_OPACITY\n"
-          "AlphaBlendEnable=TRUE;"
-          "SrcBlend = srcalpha;\n"
-          "DestBlend = invsrcalpha;\n"
-          "#endif \n"
-          "#endif\n"
-
-          "PixelShader = compile ps_2_0 MaterialPShaderSpecular_PS20_D1();\n"
-          "VertexShader = compile vs_2_0 MaterialVShader_D1();\n"
-        "}\n"
-    "};\n"
-
-    "technique MaterialFXSpecular_PS20_D2\n"
-    "{\n"
-        "pass p0\n"
-      "{\n"
-          "//CullMode=none;\n"
-
-          "#ifdef AV_OPACITY_TEXTURE\n"
-          "AlphaBlendEnable=TRUE;"
-          "SrcBlend = srcalpha;\n"
-          "DestBlend = invsrcalpha;\n"
-          "#else\n"
-          "#ifdef AV_OPACITY\n"
-          "AlphaBlendEnable=TRUE;"
-          "SrcBlend = srcalpha;\n"
-          "DestBlend = invsrcalpha;\n"
-          "#endif \n"
-          "#endif\n"
-
-          "PixelShader = compile ps_2_0 MaterialPShaderSpecular_PS20_D2();\n"
-          "VertexShader = compile vs_2_0 MaterialVShader_D2();\n"
-        "}\n"
-    "};\n"
-
-    // Technique for the material effect using fixed function pixel pipeline
-    "technique MaterialFX_FF\n"
-    "{\n"
-        "pass p0\n"
-        "{\n"
-            "//CullMode=none;\n"
-            "SpecularEnable = true; \n"
-            "VertexShader = compile vs_2_0 MaterialVShader_FF();\n"
-            "ColorOp[0] = Modulate;\n"
-            "ColorArg0[0] = Texture;\n"
-            "ColorArg1[0] = Diffuse;\n"
-            "AlphaOp[0] = Modulate;\n"
-            "AlphaArg0[0] = Texture;\n"
-            "AlphaArg1[0] = Diffuse;\n"
-        "}\n"
-    "};\n"
-    );
-
-std::string g_szPassThroughShader = std::string(
-        "texture TEXTURE_2D;\n"
-        "sampler TEXTURE_SAMPLER = sampler_state\n"
-        "{\n"
-            "Texture = (TEXTURE_2D);\n"
-            "MinFilter = POINT;\n"
-            "MagFilter = POINT;\n"
-        "};\n"
-
-    // Vertex Shader output for pixel shader usage
-        "struct VS_OUTPUT\n"
-        "{\n"
-            "float4 Position : POSITION;\n"
-            "float2 TexCoord0 : TEXCOORD0;\n"
-        "};\n"
-
-    // vertex shader for pixel shader usage
-        "VS_OUTPUT DefaultVShader(float4 INPosition : POSITION, float2 INTexCoord0 : TEXCOORD0 )\n"
-        "{\n"
-            "VS_OUTPUT Out;\n"
-
-            "Out.Position = INPosition;\n"
-            "Out.TexCoord0 = INTexCoord0;\n"
-
-            "return Out;\n"
-        "}\n"
-
-        // simply lookup a texture
-        "float4 PassThrough_PS(float2 IN : TEXCOORD0) : COLOR\n"
-        "{\n"
-        "  return tex2D(TEXTURE_SAMPLER,IN);\n"
-        "}\n"
-
-        // visualize the alpha channel (in black) -> use a
-        "float4 PassThroughAlphaA_PS(float2 IN : TEXCOORD0) : COLOR\n"
-        "{\n"
-        "  return float4(0.0f,0.0f,0.0f,tex2D(TEXTURE_SAMPLER,IN).a);\n"
-        "}\n"
-
-        // visualize the alpha channel (in black) -> use r
-        "float4 PassThroughAlphaR_PS(float2 IN : TEXCOORD0) : COLOR\n"
-        "{\n"
-        "  return float4(0.0f,0.0f,0.0f,tex2D(TEXTURE_SAMPLER,IN).r);\n"
-        "}\n"
-
-        // Simple pass-through technique
-        "technique PassThrough\n"
-        "{\n"
-            "pass p0\n"
-            "{\n"
-                "FillMode=Solid;\n"
-                "ZEnable = FALSE;\n"
-                "CullMode = none;\n"
-                "AlphaBlendEnable = TRUE;\n"
-                "SrcBlend =srcalpha;\n"
-                "DestBlend =invsrcalpha;\n"
-                "PixelShader = compile ps_2_0 PassThrough_PS();\n"
-                "VertexShader = compile vs_2_0 DefaultVShader();\n"
-            "}\n"
-        "};\n"
-
-        // Pass-through technique which visualizes the texture's alpha channel
-        "technique PassThroughAlphaFromA\n"
-        "{\n"
-            "pass p0\n"
-            "{\n"
-                "FillMode=Solid;\n"
-                "ZEnable = FALSE;\n"
-                "CullMode = none;\n"
-                "AlphaBlendEnable = TRUE;\n"
-                "SrcBlend =srcalpha;\n"
-                "DestBlend =invsrcalpha;\n"
-                "PixelShader = compile ps_2_0 PassThroughAlphaA_PS();\n"
-                "VertexShader = compile vs_2_0 DefaultVShader();\n"
-            "}\n"
-        "};\n"
-
-        // Pass-through technique which visualizes the texture's red channel
-        "technique PassThroughAlphaFromR\n"
-        "{\n"
-            "pass p0\n"
-            "{\n"
-                "FillMode=Solid;\n"
-                "ZEnable = FALSE;\n"
-                "CullMode = none;\n"
-                "AlphaBlendEnable = TRUE;\n"
-                "SrcBlend =srcalpha;\n"
-                "DestBlend =invsrcalpha;\n"
-                "PixelShader = compile ps_2_0 PassThroughAlphaR_PS();\n"
-                "VertexShader = compile vs_2_0 DefaultVShader();\n"
-            "}\n"
-        "};\n"
-
-        // technique for fixed function pixel pipeline
-        "technique PassThrough_FF\n"
-        "{\n"
-            "pass p0\n"
-            "{\n"
-                "ZEnable = FALSE;\n"
-                "CullMode = none;\n"
-                "AlphaBlendEnable = TRUE;\n"
-                "SrcBlend =srcalpha;\n"
-                "DestBlend =invsrcalpha;\n"
-                "VertexShader = compile vs_2_0 DefaultVShader();\n"
-        "ColorOp[0] = SelectArg1;\n"
-        "ColorArg0[0] = Texture;\n"
-        "AlphaOp[0] = SelectArg1;\n"
-        "AlphaArg0[0] = Texture;\n"
-            "}\n"
-        "};\n"
-    );
-
-std::string g_szCheckerBackgroundShader = std::string(
-
-        // the two colors used to draw the checker pattern
-        "float3 COLOR_ONE = float3(0.4f,0.4f,0.4f);\n"
-        "float3 COLOR_TWO = float3(0.6f,0.6f,0.6f);\n"
-
-        // size of a square in both x and y direction
-        "float SQUARE_SIZE = 10.0f;\n"
-
-    // vertex shader output structure
-        "struct VS_OUTPUT\n"
-        "{\n"
-            "float4 Position : POSITION;\n"	
-        "};\n"
-
-    // vertex shader 
-        "VS_OUTPUT DefaultVShader(float4 INPosition : POSITION, float2 INTexCoord0 : TEXCOORD0 )\n"
-        "{\n"
-            "VS_OUTPUT Out;\n"
-
-            "Out.Position = INPosition;\n"
-            "return Out;\n"
-        "}\n"
-
-        // pixel shader
-        "float4 MakePattern_PS(float2 IN : VPOS) : COLOR\n"
-        "{\n"
-          "float2 fDiv = IN / SQUARE_SIZE;\n"
-          "float3 fColor = COLOR_ONE;\n"
-          "if (0 == round(fmod(round(fDiv.x),2)))\n"
-          "{\n"
-          "  if (0 == round(fmod(round(fDiv.y),2))) fColor = COLOR_TWO;\n"
-          "}\n"
-          "else if (0 != round(fmod(round(fDiv.y),2)))fColor = COLOR_TWO;\n"
-          "return float4(fColor,1.0f);"
-        "}\n"
-    
-        // technique to generate a pattern
-        "technique MakePattern\n"
-        "{\n"
-          "pass p0\n"
-          "{\n"
-            "FillMode=Solid;\n"
-            "ZEnable = FALSE;\n"
-            "CullMode = none;\n"
-            "PixelShader = compile ps_3_0 MakePattern_PS();\n"
-            "VertexShader = compile vs_3_0 DefaultVShader();\n"
-          "}\n"
-        "};\n"
-        );
+/*
+---------------------------------------------------------------------------
+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.
+---------------------------------------------------------------------------
+*/
+#include "assimp_view.h"
+
+namespace AssimpView  {
+
+// ------------------------------------------------------------------------------------------------
+std::string g_szNormalsShader = std::string(
+
+    // World * View * Projection matrix\n"
+    // NOTE: Assume that the material uses a WorldViewProjection matrix\n"
+    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
+    "float4 OUTPUT_COLOR;\n"
+    
+    // Vertex shader input structure
+    "struct VS_INPUT\n"
+    "{\n"
+        "// Position\n"
+        "float3 Position : POSITION;\n"
+    "};\n"
+
+    // Vertex shader output structure for pixel shader usage
+    "struct VS_OUTPUT\n"
+  "{\n"
+        "float4 Position : POSITION;\n"
+    "};\n"
+
+    // Vertex shader output structure for FixedFunction usage
+    "struct VS_OUTPUT_FF\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+    "float4 Color : COLOR;\n"
+    "};\n"
+
+    // Vertex shader for rendering normals using pixel shader
+    "VS_OUTPUT RenderNormalsVS(VS_INPUT IN)\n"
+    "{\n"
+        "// Initialize the output structure with zero\n"
+        "VS_OUTPUT Out = (VS_OUTPUT)0;\n"
+
+        "// Multiply with the WorldViewProjection matrix\n"
+        "Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
+
+        "return Out;\n"
+    "}\n"
+
+    // Vertex shader for rendering normals using fixed function pipeline
+    "VS_OUTPUT_FF RenderNormalsVS_FF(VS_INPUT IN)\n"
+  "{\n"
+        "VS_OUTPUT_FF Out;\n"
+        "Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
+    "Out.Color = OUTPUT_COLOR;\n"
+        "return Out;\n"
+    "}\n"
+
+    // Pixel shader
+    "float4 RenderNormalsPS() : COLOR\n"
+    "{\n"
+        "return OUTPUT_COLOR;\n"
+    "}\n"
+
+    // Technique for the normal rendering effect (ps_2_0)
+    "technique RenderNormals\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+        "CullMode=none;\n"
+        "PixelShader = compile ps_2_0 RenderNormalsPS();\n"
+        "VertexShader = compile vs_2_0 RenderNormalsVS();\n"
+        "}\n"
+    "};\n"
+
+    // Technique for the normal rendering effect (fixed function)
+    "technique RenderNormals_FF\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+          "CullMode=none;\n"
+          "VertexShader = compile vs_2_0 RenderNormalsVS_FF();\n"
+      "ColorOp[0] = SelectArg1;\n"
+      "ColorArg0[0] = Diffuse;\n"
+      "AlphaOp[0] = SelectArg1;\n"
+      "AlphaArg0[0] = Diffuse;\n"
+        "}\n"
+    "};\n"
+    );
+
+// ------------------------------------------------------------------------------------------------
+std::string g_szSkyboxShader = std::string(
+
+    // Sampler and texture for the skybox
+    "textureCUBE lw_tex_envmap;\n"
+    "samplerCUBE EnvironmentMapSampler = sampler_state\n"
+    "{\n"
+      "Texture = (lw_tex_envmap);\n"
+      "AddressU = CLAMP;\n"
+      "AddressV = CLAMP;\n"
+      "AddressW = CLAMP;\n"
+
+      "MAGFILTER = linear;\n"
+      "MINFILTER = linear;\n"
+    "};\n"
+
+    // World * View * Projection matrix\n"
+    // NOTE: Assume that the material uses a WorldViewProjection matrix\n"
+    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
+    
+    // Vertex shader input structure
+    "struct VS_INPUT\n"
+    "{\n"
+        "float3 Position : POSITION;\n"
+        "float3 Texture0 : TEXCOORD0;\n"
+    "};\n"
+
+    // Vertex shader output structure
+    "struct VS_OUTPUT\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+        "float3 Texture0 : TEXCOORD0;\n"
+    "};\n"
+
+    // Vertex shader
+    "VS_OUTPUT RenderSkyBoxVS(VS_INPUT IN)\n"
+    "{\n"
+        "VS_OUTPUT Out;\n"
+
+        // Multiply with the WorldViewProjection matrix
+        "Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
+
+        // Set z to w to ensure z becomes 1.0 after the division through w occurs
+        "Out.Position.z = Out.Position.w;\n"
+    
+        // Simply pass through texture coordinates
+        "Out.Texture0 = IN.Texture0;\n"
+
+        "return Out;\n"
+    "}\n"
+
+    // Pixel shader
+    "float4 RenderSkyBoxPS(float3 Texture0 : TEXCOORD0) : COLOR\n"
+    "{\n"
+        // Lookup the skybox texture
+        "return texCUBE(EnvironmentMapSampler,Texture0) ;\n"
+    "}\n"
+
+    // Technique for the skybox shader (ps_2_0)
+    "technique RenderSkyBox\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+          "ZWriteEnable = FALSE;\n"
+          "FogEnable = FALSE;\n"
+          "CullMode = NONE;\n"
+
+          "PixelShader = compile ps_2_0 RenderSkyBoxPS();\n"
+          "VertexShader = compile vs_2_0 RenderSkyBoxVS();\n"
+        "}\n"
+    "};\n"
+
+  // -------------- same for static background image -----------------
+    "texture TEXTURE_2D;\n"
+    "sampler TEXTURE_SAMPLER = sampler_state\n"
+    "{\n"
+        "Texture = (TEXTURE_2D);\n"
+    "};\n"
+
+    "struct VS_OUTPUT2\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+        "float2 TexCoord0 : TEXCOORD0;\n"
+    "};\n"
+
+    "VS_OUTPUT2 RenderImageVS(float4 INPosition : POSITION, float2 INTexCoord0 : TEXCOORD0 )\n"
+    "{\n"
+        "VS_OUTPUT2 Out;\n"
+
+        "Out.Position.xy = INPosition.xy;\n"
+        "Out.Position.z = Out.Position.w = 1.0f;\n"
+        "Out.TexCoord0 = INTexCoord0;\n"
+
+        "return Out;\n"
+    "}\n"
+
+    "float4 RenderImagePS(float2 IN : TEXCOORD0) : COLOR\n"
+    "{\n"
+        "return tex2D(TEXTURE_SAMPLER,IN);\n"
+    "}\n"
+
+    // Technique for the background image shader (ps_2_0)
+    "technique RenderImage2D\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "ZWriteEnable = FALSE;\n"
+            "FogEnable = FALSE;\n"
+            "CullMode = NONE;\n"
+    
+            "PixelShader = compile ps_2_0 RenderImagePS();\n"
+            "VertexShader = compile vs_2_0 RenderImageVS();\n"
+        "}\n"
+    "};\n"
+    );
+
+std::string g_szDefaultShader = std::string(
+
+    // World * View * Projection matrix
+    // NOTE: Assume that the material uses a WorldViewProjection matrix
+    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
+    "float4x4 World					: WORLD;\n"
+    "float4x3 WorldInverseTranspose	: WORLDINVERSETRANSPOSE;\n"
+
+    // light colors
+    "float3 afLightColor[5];\n"
+    // light direction
+    "float3 afLightDir[5];\n"
+
+    // position of the camera in worldspace\n"
+    "float3 vCameraPos : CAMERAPOSITION;\n"
+
+    // Bone matrices
+//	"#ifdef AV_SKINNING \n"
+    "float4x3 gBoneMatrix[60]; \n"
+//	"#endif // AV_SKINNING \n"
+
+    // Vertex shader input structure
+    "struct VS_INPUT\n"
+    "{\n"
+        "float3 Position : POSITION;\n"
+        "float3 Normal : NORMAL;\n"
+//		"#ifdef AV_SKINNING \n"
+            "float4 BlendIndices : BLENDINDICES;\n"
+            "float4 BlendWeights : BLENDWEIGHT;\n"
+//		"#endif // AV_SKINNING \n"
+    "};\n"
+
+    // Vertex shader output structure for pixel shader usage
+    "struct VS_OUTPUT\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+        "float3 ViewDir : TEXCOORD0;\n"
+        "float3 Normal : TEXCOORD1;\n"
+    "};\n"
+
+    // Vertex shader output structure for fixed function
+    "struct VS_OUTPUT_FF\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+        "float4 Color : COLOR;\n"
+    "};\n"
+
+    // Vertex shader for pixel shader usage
+    "VS_OUTPUT DefaultVShader(VS_INPUT IN)\n"
+    "{\n"
+        "VS_OUTPUT Out;\n"
+
+//		"#ifdef AV_SKINNING \n"
+        "float4 weights = IN.BlendWeights; \n"
+        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
+        "float4 localPos = float4( IN.Position, 1.0f); \n"
+        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
+//		"#else \n"
+//		"float3 objPos = IN.Position; \n"
+//		"#endif // AV_SKINNING \n"
+
+        // Multiply with the WorldViewProjection matrix
+        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
+        "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
+        "Out.ViewDir = vCameraPos - WorldPos;\n"
+        "Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
+
+        "return Out;\n"
+    "}\n"
+
+    // Vertex shader for fixed function pipeline
+    "VS_OUTPUT_FF DefaultVShader_FF(VS_INPUT IN)\n"
+    "{\n"
+        "VS_OUTPUT_FF Out;\n"
+
+//		"#ifdef AV_SKINNING \n"
+        "float4 weights = IN.BlendWeights; \n"
+        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
+        "float4 localPos = float4( IN.Position, 1.0f); \n"
+        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
+//		"#else \n"
+//		"float3 objPos = IN.Position; \n"
+//		"#endif // AV_SKINNING \n"
+
+        // Multiply with the WorldViewProjection matrix
+        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
+
+        "float3 worldNormal = normalize( mul( IN.Normal, (float3x3) WorldInverseTranspose)); \n"
+
+        // per-vertex lighting. We simply assume light colors of unused lights to be black
+        "Out.Color = float4( 0.2f, 0.2f, 0.2f, 1.0f); \n"
+        "for( int a = 0; a < 2; a++)\n"
+        "  Out.Color.rgb += saturate( dot( afLightDir[a], worldNormal)) * afLightColor[a].rgb; \n"
+            "return Out;\n"
+    "}\n"
+
+    // Pixel shader for one light
+    "float4 DefaultPShaderSpecular_D1(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "float3 Normal = normalize(IN.Normal);\n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+
+        "{\n"
+            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
+            "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
+            "float fHalfLambert = L1*L1;\n"
+            "OUT.rgb += afLightColor[0] * (fHalfLambert +\n"
+                "saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,ViewDir),9));\n"
+        "}\n"
+        "return OUT;\n"
+    "}\n"
+
+    // Pixel shader for two lights
+    "float4 DefaultPShaderSpecular_D2(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "float3 Normal = normalize(IN.Normal);\n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+
+        "{\n"
+            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
+            "float3 Reflect = reflect (ViewDir,Normal);\n"
+            "float fHalfLambert = L1*L1;\n"
+            "OUT.rgb += afLightColor[0] * (fHalfLambert +\n"
+            "saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,afLightDir[0]),9));\n"
+        "}\n"
+        "{\n"
+            "float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
+            "float3 Reflect = reflect (ViewDir,Normal);\n"
+            "float fHalfLambert = L1*L1;\n"
+            "OUT.rgb += afLightColor[1] * (fHalfLambert +\n"
+            "saturate(fHalfLambert * 4.0f) * pow(dot(Reflect,afLightDir[1]),9));\n"
+        "}\n"
+        "return OUT;\n"
+    "}\n"
+    // ----------------------------------------------------------------------------
+    "float4 DefaultPShaderSpecular_PS20_D1(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "float3 Normal = normalize(IN.Normal);\n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+
+        "{\n"
+            "float L1 = dot(Normal,afLightDir[0]);\n"
+            "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
+            "OUT.rgb += afLightColor[0] * ((L1) +\n"
+            "pow(dot(Reflect,ViewDir),9));\n"
+        "}\n"
+
+        "return OUT;\n"
+    "}\n"
+    // ----------------------------------------------------------------------------
+    "float4 DefaultPShaderSpecular_PS20_D2(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "float3 Normal = normalize(IN.Normal);\n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+
+        "{\n"
+            "float L1 = dot(Normal,afLightDir[0]);\n"
+            "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
+            "OUT.rgb += afLightColor[0] * ((L1) +\n"
+            "pow(dot(Reflect,ViewDir),9));\n"
+        "}\n"
+        "{\n"
+            "float L1 = dot(Normal,afLightDir[1]);\n"
+            "float3 Reflect = reflect (Normal,afLightDir[1]);\n"
+            "OUT.rgb += afLightColor[1] * ((L1) +\n"
+            "pow(dot(Reflect,ViewDir),9));\n"
+        "}\n"
+        "return OUT;\n"
+    "}\n"
+
+
+    // Technique for the default effect
+    "technique DefaultFXSpecular_D1\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "CullMode=none;\n"
+            "PixelShader = compile ps_3_0 DefaultPShaderSpecular_D1();\n"
+            "VertexShader = compile vs_3_0 DefaultVShader();\n"
+        "}\n"
+    "};\n"
+    "technique DefaultFXSpecular_D2\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "CullMode=none;\n"
+            "PixelShader = compile ps_3_0 DefaultPShaderSpecular_D2();\n"
+            "VertexShader = compile vs_3_0 DefaultVShader();\n"
+        "}\n"
+    "};\n"
+
+    // Technique for the default effect (ps_2_0)
+    "technique DefaultFXSpecular_PS20_D1\n"
+    "{\n"
+        "pass p0\n"
+    "{\n"
+          "CullMode=none;\n"
+          "PixelShader = compile ps_2_0 DefaultPShaderSpecular_PS20_D1();\n"
+          "VertexShader = compile vs_2_0 DefaultVShader();\n"
+        "}\n"
+    "};\n"
+    "technique DefaultFXSpecular_PS20_D2\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+          "CullMode=none;\n"
+          "PixelShader = compile ps_2_0 DefaultPShaderSpecular_PS20_D2();\n"
+          "VertexShader = compile vs_2_0 DefaultVShader();\n"
+        "}\n"
+    "};\n"
+
+    // Technique for the default effect using the fixed function pixel pipeline
+    "technique DefaultFXSpecular_FF\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "CullMode=none;\n"
+            "VertexShader = compile vs_2_0 DefaultVShader_FF();\n"
+            "ColorOp[0] = SelectArg1;\n"
+            "ColorArg0[0] = Diffuse;\n"
+            "AlphaOp[0] = SelectArg1;\n"
+            "AlphaArg0[0] = Diffuse;\n"
+        "}\n"
+    "};\n"
+  );
+
+
+std::string g_szMaterialShader = std::string(
+
+    // World * View * Projection matrix
+  // NOTE: Assume that the material uses a WorldViewProjection matrix
+    "float4x4 WorldViewProjection	: WORLDVIEWPROJECTION;\n"
+    "float4x4 World					: WORLD;\n"
+    "float4x3 WorldInverseTranspose	: WORLDINVERSETRANSPOSE;\n"
+
+    "#ifndef AV_DISABLESSS\n"
+    "float4x3 ViewProj;\n"
+    "float4x3 InvViewProj;\n"
+    "#endif\n"
+
+    "float4 DIFFUSE_COLOR;\n"
+    "float4 SPECULAR_COLOR;\n"
+    "float4 AMBIENT_COLOR;\n"
+    "float4 EMISSIVE_COLOR;\n"
+
+    "#ifdef AV_SPECULAR_COMPONENT\n"
+    "float SPECULARITY;\n"
+    "float SPECULAR_STRENGTH;\n"
+    "#endif\n"
+    "#ifdef AV_OPACITY\n"
+    "float TRANSPARENCY;\n"
+    "#endif\n"
+
+    // light colors (diffuse and specular)
+    "float4 afLightColor[5];\n"
+    "float4 afLightColorAmbient[5];\n"
+
+    // light direction
+    "float3 afLightDir[5];\n"
+
+    // position of the camera in worldspace
+    "float3 vCameraPos : CAMERAPOSITION;\n"
+
+    // Bone matrices
+    "#ifdef AV_SKINNING \n"
+    "float4x3 gBoneMatrix[60]; \n"
+    "#endif // AV_SKINNING \n"
+
+    "#ifdef AV_DIFFUSE_TEXTURE\n"
+        "texture DIFFUSE_TEXTURE;\n"
+        "sampler DIFFUSE_SAMPLER\n"
+        "{\n"
+          "Texture = <DIFFUSE_TEXTURE>;\n"
+          "#ifdef AV_WRAPU\n"
+          "AddressU = WRAP;\n"
+          "#endif\n"
+          "#ifdef AV_MIRRORU\n"
+          "AddressU = MIRROR;\n"
+          "#endif\n"
+          "#ifdef AV_CLAMPU\n"
+          "AddressU = CLAMP;\n"
+          "#endif\n"
+          "#ifdef AV_WRAPV\n"
+          "AddressV = WRAP;\n"
+          "#endif\n"
+          "#ifdef AV_MIRRORV\n"
+          "AddressV = MIRROR;\n"
+          "#endif\n"
+          "#ifdef AV_CLAMPV\n"
+          "AddressV = CLAMP;\n"
+          "#endif\n"
+        "};\n"
+    "#endif // AV_DIFFUSE_TEXTUR\n"
+
+    "#ifdef AV_DIFFUSE_TEXTURE2\n"
+        "texture DIFFUSE_TEXTURE2;\n"
+        "sampler DIFFUSE_SAMPLER2\n"
+        "{\n"
+          "Texture = <DIFFUSE_TEXTURE2>;\n"
+        "};\n"
+    "#endif // AV_DIFFUSE_TEXTUR2\n"
+
+    "#ifdef AV_SPECULAR_TEXTURE\n"
+        "texture SPECULAR_TEXTURE;\n"
+        "sampler SPECULAR_SAMPLER\n"
+        "{\n"
+          "Texture = <SPECULAR_TEXTURE>;\n"
+        "};\n"
+    "#endif // AV_SPECULAR_TEXTUR\n"
+
+    "#ifdef AV_AMBIENT_TEXTURE\n"
+        "texture AMBIENT_TEXTURE;\n"
+        "sampler AMBIENT_SAMPLER\n"
+        "{\n"
+          "Texture = <AMBIENT_TEXTURE>;\n"
+        "};\n"
+    "#endif // AV_AMBIENT_TEXTUR\n"
+
+    "#ifdef AV_LIGHTMAP_TEXTURE\n"
+        "texture LIGHTMAP_TEXTURE;\n"
+        "sampler LIGHTMAP_SAMPLER\n"
+        "{\n"
+          "Texture = <LIGHTMAP_TEXTURE>;\n"
+        "};\n"
+    "#endif // AV_LIGHTMAP_TEXTURE\n"
+
+    "#ifdef AV_OPACITY_TEXTURE\n"
+        "texture OPACITY_TEXTURE;\n"
+        "sampler OPACITY_SAMPLER\n"
+        "{\n"
+          "Texture = <OPACITY_TEXTURE>;\n"
+        "};\n"
+    "#endif // AV_OPACITY_TEXTURE\n"
+
+    "#ifdef AV_EMISSIVE_TEXTURE\n"
+        "texture EMISSIVE_TEXTURE;\n"
+        "sampler EMISSIVE_SAMPLER\n"
+        "{\n"
+          "Texture = <EMISSIVE_TEXTURE>;\n"
+        "};\n"
+    "#endif // AV_EMISSIVE_TEXTUR\n"
+
+    "#ifdef AV_NORMAL_TEXTURE\n"
+        "texture NORMAL_TEXTURE;\n"
+        "sampler NORMAL_SAMPLER\n"
+        "{\n"
+          "Texture = <NORMAL_TEXTURE>;\n"
+        "};\n"
+    "#endif // AV_NORMAL_TEXTURE\n"
+
+    "#ifdef AV_SKYBOX_LOOKUP\n"
+        "textureCUBE lw_tex_envmap;\n"
+        "samplerCUBE EnvironmentMapSampler = sampler_state\n"
+        "{\n"
+          "Texture = (lw_tex_envmap);\n"
+          "AddressU = CLAMP;\n"
+          "AddressV = CLAMP;\n"
+          "AddressW = CLAMP;\n"
+
+          "MAGFILTER = linear;\n"
+          "MINFILTER = linear;\n"
+        "};\n"
+    "#endif // AV_SKYBOX_LOOKUP\n"
+
+    // Vertex shader input structure
+    "struct VS_INPUT\n"
+    "{\n"
+        "float3 Position : POSITION;\n"
+        "float3 Normal : NORMAL;\n"
+        "float4 Color : COLOR0;\n"
+        "float3 Tangent   : TANGENT;\n"
+        "float3 Bitangent : BINORMAL;\n"
+        "float2 TexCoord0 : TEXCOORD0;\n"
+        "#ifdef AV_TWO_UV \n"
+        "float2 TexCoord1 : TEXCOORD1;\n"
+        "#endif \n"
+          "#ifdef AV_SKINNING \n"
+            "float4 BlendIndices : BLENDINDICES;\n"
+            "float4 BlendWeights : BLENDWEIGHT;\n"
+         "#endif // AV_SKINNING \n"
+    "};\n"
+
+    // Vertex shader output structure for pixel shader usage
+    "struct VS_OUTPUT\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+        "float3 ViewDir : TEXCOORD0;\n"
+
+        "float4 Color : COLOR0;\n"
+
+        "#ifndef AV_NORMAL_TEXTURE\n"
+        "float3 Normal  : TEXCOORD1;\n"
+        "#endif\n"
+
+        "float2 TexCoord0 : TEXCOORD2;\n"
+        "#ifdef AV_TWO_UV \n"
+        "float2 TexCoord1 : TEXCOORD3;\n"
+        "#endif \n"
+
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3 Light0 : TEXCOORD3;\n"
+        "float3 Light1 : TEXCOORD4;\n"
+        "#endif\n"
+    "};\n"
+
+    // Vertex shader output structure for fixed function pixel pipeline
+    "struct VS_OUTPUT_FF\n"
+    "{\n"
+        "float4 Position : POSITION;\n"
+        "float4 DiffuseColor : COLOR0;\n"
+        "float4 SpecularColor : COLOR1;\n"
+        "float2 TexCoord0 : TEXCOORD0;\n"
+    "};\n"
+
+
+    // Selective SuperSampling in screenspace for reflection lookups
+    "#define GetSSSCubeMap(_refl) (texCUBElod(EnvironmentMapSampler,float4(_refl,0.0f)).rgb) \n"
+
+
+    // Vertex shader for pixel shader usage and one light
+    "VS_OUTPUT MaterialVShader_D1(VS_INPUT IN)\n"
+    "{\n"
+        "VS_OUTPUT Out = (VS_OUTPUT)0;\n"
+
+        "#ifdef AV_SKINNING \n"
+        "float4 weights = IN.BlendWeights; \n"
+        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
+        "float4 localPos = float4( IN.Position, 1.0f); \n"
+        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
+        "#else \n"
+        "float3 objPos = IN.Position; \n"
+        "#endif // AV_SKINNING \n"
+
+        // Multiply with the WorldViewProjection matrix
+        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
+        "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
+        "Out.TexCoord0 = IN.TexCoord0;\n"
+        "#ifdef AV_TWO_UV \n"
+        "Out.TexCoord1 = IN.TexCoord1;\n"
+        "#endif\n"
+        "Out.Color = IN.Color;\n"
+
+        "#ifndef AV_NORMAL_TEXTURE\n"
+        "Out.ViewDir = vCameraPos - WorldPos;\n"
+        "Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
+        "#endif\n"
+        
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3x3 TBNMatrix = float3x3(IN.Tangent, IN.Bitangent, IN.Normal);\n"
+        "float3x3 WTTS      = mul(TBNMatrix, (float3x3)WorldInverseTranspose);\n"
+        "Out.Light0         = normalize(mul(WTTS, afLightDir[0] ));\n"
+        "Out.ViewDir = normalize(mul(WTTS, (vCameraPos - WorldPos)));\n"
+        "#endif\n"
+        "return Out;\n"
+    "}\n"
+
+    // Vertex shader for pixel shader usage and two lights
+    "VS_OUTPUT MaterialVShader_D2(VS_INPUT IN)\n"
+    "{\n"
+        "VS_OUTPUT Out = (VS_OUTPUT)0;\n"
+
+        "#ifdef AV_SKINNING \n"
+        "float4 weights = IN.BlendWeights; \n"
+        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
+        "float4 localPos = float4( IN.Position, 1.0f); \n"
+        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
+        "#else \n"
+        "float3 objPos = IN.Position; \n"
+        "#endif // AV_SKINNING \n"
+
+        // Multiply with the WorldViewProjection matrix
+        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
+        "float3 WorldPos = mul( float4( objPos, 1.0f), World);\n"
+        "Out.TexCoord0 = IN.TexCoord0;\n"
+        "#ifdef AV_TWO_UV \n"
+        "Out.TexCoord1 = IN.TexCoord1;\n"
+        "#endif\n"
+        "Out.Color = IN.Color;\n"
+
+        "#ifndef AV_NORMAL_TEXTURE\n"
+        "Out.ViewDir = vCameraPos - WorldPos;\n"
+        "Out.Normal = mul(IN.Normal,WorldInverseTranspose);\n"
+        "#endif\n"
+
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3x3 TBNMatrix = float3x3(IN.Tangent, IN.Bitangent, IN.Normal);\n"
+        "float3x3 WTTS      = mul(TBNMatrix, (float3x3)WorldInverseTranspose);\n"
+        "Out.Light0         = normalize(mul(WTTS, afLightDir[0] ));\n"
+        "Out.Light1         = normalize(mul(WTTS, afLightDir[1] ));\n"
+        "Out.ViewDir = normalize(mul(WTTS, (vCameraPos - WorldPos)));\n"
+        "#endif\n"
+        "return Out;\n"
+    "}\n"
+
+    // Vertex shader for zero to five lights using the fixed function pixel pipeline
+    "VS_OUTPUT_FF MaterialVShader_FF(VS_INPUT IN)\n"
+    "{\n"
+        "VS_OUTPUT_FF Out = (VS_OUTPUT_FF)0;\n"
+
+        "#ifdef AV_SKINNING \n"
+        "float4 weights = IN.BlendWeights; \n"
+        "weights.w = 1.0f - dot( weights.xyz, float3( 1, 1, 1)); \n"
+        "float4 localPos = float4( IN.Position, 1.0f); \n"
+        "float3 objPos = mul( localPos, gBoneMatrix[IN.BlendIndices.x]) * weights.x; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.y]) * weights.y; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.z]) * weights.z; \n"
+        "objPos += mul( localPos, gBoneMatrix[IN.BlendIndices.w]) * weights.w; \n"
+        "#else \n"
+        "float3 objPos = IN.Position; \n"
+        "#endif // AV_SKINNING \n"
+
+        // Multiply with the WorldViewProjection matrix
+        "Out.Position = mul( float4( objPos, 1.0f), WorldViewProjection);\n"
+        "float3 worldPos = mul( float4( objPos, 1.0f), World);\n"
+        "float3 worldNormal = normalize( mul( IN.Normal, (float3x3) WorldInverseTranspose)); \n"
+        "Out.TexCoord0 = IN.TexCoord0;\n"
+
+        // calculate per-vertex diffuse lighting including ambient part
+        "float4 diffuseColor = float4( 0.0f, 0.0f, 0.0f, 1.0f); \n"
+        "for( int a = 0; a < 2; a++) \n"
+        "  diffuseColor.rgb += saturate( dot( afLightDir[a], worldNormal)) * afLightColor[a].rgb; \n"
+        // factor in material properties and a bit of ambient lighting
+        "Out.DiffuseColor = diffuseColor * DIFFUSE_COLOR + float4( 0.2f, 0.2f, 0.2f, 1.0f) * AMBIENT_COLOR; ; \n"
+
+        // and specular including emissive part
+        "float4 specularColor = float4( 0.0f, 0.0f, 0.0f, 1.0f); \n"
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+        "float3 viewDir = normalize( worldPos - vCameraPos); \n"
+        "for( int a = 0; a < 2; a++) \n"
+        "{ \n"
+        "  float3 reflDir = reflect( afLightDir[a], worldNormal); \n"
+        "  float specIntensity = pow( saturate( dot( reflDir, viewDir)), SPECULARITY) * SPECULAR_STRENGTH; \n"
+        "  specularColor.rgb += afLightColor[a] * specIntensity; \n"
+        "} \n"
+        "#endif // AV_SPECULAR_COMPONENT\n"
+        // factor in material properties and the emissive part
+        "Out.SpecularColor = specularColor * SPECULAR_COLOR + EMISSIVE_COLOR; \n"
+
+        "return Out;\n"
+    "}\n"
+
+
+    // Pixel shader - one light
+    "float4 MaterialPShaderSpecular_D1(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3 IN_Light0 = normalize(IN.Light0);\n"
+        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
+        "#else\n"
+        "float3 Normal = normalize(IN.Normal);\n"
+        "#endif \n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+            "float3 Reflect = normalize(reflect (-ViewDir,Normal));\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+
+        "{\n"
+        "#ifdef AV_NORMAL_TEXTURE\n"
+            "float L1 =  dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
+            "#define AV_LIGHT_0 IN_Light0\n"
+            // would need to convert the reflection vector into world space ....
+            // simply let it ...
+        "#else\n"
+            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
+            "#define AV_LIGHT_0 afLightDir[0]\n"
+        "#endif\n"
+        "#ifdef AV_DIFFUSE_TEXTURE2\n"
+            "float fHalfLambert = 1.f;\n"
+        "#else\n"
+            "float fHalfLambert = L1*L1;\n"
+        "#endif \n"
+        "#ifdef AV_DIFFUSE_TEXTURE\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert * IN.Color.rgb +\n"
+        "#else\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert * IN.Color.rgb +\n"
+        "#endif // !AV_DIFFUSE_TEXTURE\n"
+
+        
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+            "#ifndef AV_SKYBOX_LOOKUP\n"
+                "#ifdef AV_SPECULAR_TEXTURE\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#else\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#endif // !AV_SPECULAR_TEXTURE\n"
+            "#else\n"
+                "#ifdef AV_SPECULAR_TEXTURE\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#else\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#endif // !AV_SPECULAR_TEXTURE\n"
+            "#endif // !AV_SKYBOX_LOOKUP\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+
+        "#ifdef AV_AMBIENT_TEXTURE\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
+        "#else\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb + \n"
+        "#endif // !AV_AMBIENT_TEXTURE\n"
+            "#ifdef AV_EMISSIVE_TEXTURE\n"
+            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
+        "#else \n"
+            "EMISSIVE_COLOR.rgb;\n"
+        "#endif // !AV_EMISSIVE_TEXTURE\n"
+        "}\n"
+        "#ifdef AV_OPACITY\n"
+        "OUT.a = TRANSPARENCY;\n"
+        "#endif\n"
+        "#ifdef AV_LIGHTMAP_TEXTURE\n"
+        "OUT.rgb *= tex2D(LIGHTMAP_SAMPLER,AV_LIGHTMAP_TEXTURE_UV_COORD).rgb*LM_STRENGTH;\n"
+        "#endif\n"
+        "#ifdef AV_OPACITY_TEXTURE\n"
+        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
+        "#endif\n"
+        "return OUT;\n"
+
+        "#undef AV_LIGHT_0\n"
+    "}\n"
+
+    // Pixel shader - two lights
+    "float4 MaterialPShaderSpecular_D2(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3 IN_Light0 = normalize(IN.Light0);\n"
+        "float3 IN_Light1 = normalize(IN.Light1);\n"
+        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
+        "#else\n"
+        "float3 Normal = normalize(IN.Normal);\n"
+        "#endif \n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+            "float3 Reflect = -normalize(reflect (ViewDir,Normal));\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+
+        "{\n"
+        
+        "#ifdef AV_NORMAL_TEXTURE\n"
+            "float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
+            "#define AV_LIGHT_0 IN_Light0\n"
+        "#else\n"
+            "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
+            "#define AV_LIGHT_0 afLightDir[0]\n"
+        "#endif\n"
+            "float fHalfLambert = L1*L1;\n"
+            
+        "#ifdef AV_DIFFUSE_TEXTURE\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert  * IN.Color.rgb +\n"
+        "#else\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * fHalfLambert  * IN.Color.rgb +\n"
+        "#endif // !AV_DIFFUSE_TEXTURE\n"
+
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+            "#ifndef AV_SKYBOX_LOOKUP\n"
+                "#ifdef AV_SPECULAR_TEXTURE\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#else\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#endif // !AV_SPECULAR_TEXTURE\n"
+            "#else\n"
+                "#ifdef AV_SPECULAR_TEXTURE\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#else\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_0),SPECULARITY)) + \n"
+                "#endif // !AV_SPECULAR_TEXTURE\n"
+            "#endif // !AV_SKYBOX_LOOKUP\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_AMBIENT_TEXTURE\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb + \n"
+        "#else\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb + \n"
+        "#endif // !AV_AMBIENT_TEXTURE\n"
+        "#ifdef AV_EMISSIVE_TEXTURE\n"
+            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
+        "#else \n"
+            "EMISSIVE_COLOR.rgb;\n"
+        "#endif // !AV_EMISSIVE_TEXTURE\n"
+        "}\n"
+        "{\n"
+        "#ifdef AV_NORMAL_TEXTURE\n"
+            "float L1 = dot(Normal,IN_Light1) * 0.5f + 0.5f;\n"
+            "#define AV_LIGHT_1 IN_Light1\n"
+        "#else\n"
+            "float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
+            "#define AV_LIGHT_1 afLightDir[1]\n"
+        "#endif\n"
+            "float fHalfLambert = L1*L1;\n"
+        "#ifdef AV_DIFFUSE_TEXTURE\n"
+            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * fHalfLambert  * IN.Color.rgb +\n"
+        "#else\n"
+            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * fHalfLambert   * IN.Color.rgb +\n"
+        "#endif // !AV_DIFFUSE_TEXTURE\n"
+
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+            "#ifndef AV_SKYBOX_LOOKUP\n"
+                "#ifdef AV_SPECULAR_TEXTURE\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
+                "#else\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
+                "#endif // !AV_SPECULAR_TEXTURE\n"
+            "#else\n"
+                "#ifdef AV_SPECULAR_TEXTURE\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
+                "#else\n"
+                    "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * GetSSSCubeMap(Reflect) * (saturate(fHalfLambert * 2.0f) * pow(dot(Reflect,AV_LIGHT_1),SPECULARITY)) + \n"
+                "#endif // !AV_SPECULAR_TEXTURE\n"
+            "#endif // !AV_SKYBOX_LOOKUP\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_AMBIENT_TEXTURE\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb + \n"
+        "#else\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb + \n"
+        "#endif // !AV_AMBIENT_TEXTURE\n"
+        "#ifdef AV_EMISSIVE_TEXTURE\n"
+            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
+        "#else \n"
+            "EMISSIVE_COLOR.rgb;\n"
+        "#endif // !AV_EMISSIVE_TEXTURE\n"
+        "}\n"
+        "#ifdef AV_OPACITY\n"
+        "OUT.a = TRANSPARENCY;\n"
+        "#endif\n"
+        "#ifdef AV_LIGHTMAP_TEXTURE\n"
+        "OUT.rgb *= tex2D(LIGHTMAP_SAMPLER,AV_LIGHTMAP_TEXTURE_UV_COORD).rgb*LM_STRENGTH;\n"
+        "#endif\n"
+        "#ifdef AV_OPACITY_TEXTURE\n"
+        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
+        "#endif\n"
+        "return OUT;\n"
+
+        "#undef AV_LIGHT_0\n"
+        "#undef AV_LIGHT_1\n"
+    "}\n"
+
+    // Same pixel shader again, one light
+    "float4 MaterialPShaderSpecular_PS20_D1(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3 IN_Light0 = normalize(IN.Light0);\n"
+        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0).rgb - 1.0f);\n"
+        "#else\n"
+        "float3 Normal = normalize(IN.Normal);\n"
+        "#endif \n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+
+        "{\n"
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
+        "float3 Reflect = reflect (Normal,IN_Light0);\n"
+        "#else\n"
+        "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
+        "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
+        "#endif\n"
+        "#ifdef AV_DIFFUSE_TEXTURE\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
+        "#else\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
+        "#endif // !AV_DIFFUSE_TEXTURE\n"
+
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_SPECULAR_TEXTURE\n"
+            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
+        "#else\n"
+            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
+        "#endif // !AV_SPECULAR_TEXTURE\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_AMBIENT_TEXTURE\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
+        "#else\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb +\n"
+        "#endif // !AV_AMBIENT_TEXTURE\n"
+        "#ifdef AV_EMISSIVE_TEXTURE\n"
+            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
+        "#else \n"
+            "EMISSIVE_COLOR.rgb;\n"
+        "#endif // !AV_EMISSIVE_TEXTURE\n"
+        "}\n"
+
+        "#ifdef AV_OPACITY\n"
+        "OUT.a = TRANSPARENCY;\n"
+        "#endif\n"
+        "#ifdef AV_OPACITY_TEXTURE\n"
+        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
+        "#endif\n"
+        "return OUT;\n"
+    "}\n"
+
+    // Same pixel shader again, two lights
+    "float4 MaterialPShaderSpecular_PS20_D2(VS_OUTPUT IN) : COLOR\n"
+    "{\n"
+        "float4 OUT = float4(0.0f,0.0f,0.0f,1.0f);\n"
+
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float3 IN_Light0 = normalize(IN.Light0);\n"
+        "float3 IN_Light1 = normalize(IN.Light1);\n"
+        "float3 Normal  =  normalize(2.0f * tex2D(NORMAL_SAMPLER, IN.TexCoord0) - 1.0f);\n"
+        "#else\n"
+        "float3 Normal = normalize(IN.Normal);\n"
+        "#endif \n"
+        "float3 ViewDir = normalize(IN.ViewDir);\n"
+
+        "{\n"
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float L1 = dot(Normal,IN_Light0) * 0.5f + 0.5f;\n"
+        "float3 Reflect = reflect (Normal,IN_Light0);\n"
+        "#else\n"
+        "float L1 = dot(Normal,afLightDir[0]) * 0.5f + 0.5f;\n"
+        "float3 Reflect = reflect (Normal,afLightDir[0]);\n"
+        "#endif\n"
+        "#ifdef AV_DIFFUSE_TEXTURE\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
+        "#else\n"
+            "OUT.rgb += afLightColor[0].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
+        "#endif // !AV_DIFFUSE_TEXTURE\n"
+
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_SPECULAR_TEXTURE\n"
+            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
+        "#else\n"
+            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[0].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
+        "#endif // !AV_SPECULAR_TEXTURE\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_AMBIENT_TEXTURE\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
+        "#else\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[0].rgb +\n"
+        "#endif // !AV_AMBIENT_TEXTURE\n"
+        "#ifdef AV_EMISSIVE_TEXTURE\n"
+            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
+        "#else \n"
+            "EMISSIVE_COLOR.rgb;\n"
+        "#endif // !AV_EMISSIVE_TEXTURE\n"
+        "}\n"
+        "{\n"
+        "#ifdef AV_NORMAL_TEXTURE\n"
+        "float L1 = dot(Normal,IN_Light1) * 0.5f + 0.5f;\n"
+        "float3 Reflect = reflect (Normal,IN_Light1);\n"
+        "#else\n"
+        "float L1 = dot(Normal,afLightDir[1]) * 0.5f + 0.5f;\n"
+        "float3 Reflect = reflect (Normal,afLightDir[1]);\n"
+        "#endif\n"
+        "#ifdef AV_DIFFUSE_TEXTURE\n"
+            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * tex2D(DIFFUSE_SAMPLER,IN.TexCoord0).rgb * L1 +\n"
+        "#else\n"
+            "OUT.rgb += afLightColor[1].rgb * DIFFUSE_COLOR.rgb * L1 +\n"
+        "#endif // !AV_DIFFUSE_TEXTURE\n"
+
+        "#ifdef AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_SPECULAR_TEXTURE\n"
+            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * tex2D(SPECULAR_SAMPLER,IN.TexCoord0).rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
+        "#else\n"
+            "SPECULAR_COLOR.rgb * SPECULAR_STRENGTH * afLightColor[1].rgb * (saturate(L1 * 4.0f) * pow(dot(Reflect,ViewDir),SPECULARITY)) + \n"
+        "#endif // !AV_SPECULAR_TEXTURE\n"
+        "#endif // !AV_SPECULAR_COMPONENT\n"
+        "#ifdef AV_AMBIENT_TEXTURE\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb * tex2D(AMBIENT_SAMPLER,IN.TexCoord0).rgb +\n"
+        "#else\n"
+            "AMBIENT_COLOR.rgb * afLightColorAmbient[1].rgb + \n"
+        "#endif // !AV_AMBIENT_TEXTURE\n"
+        "#ifdef AV_EMISSIVE_TEXTURE\n"
+            "EMISSIVE_COLOR.rgb * tex2D(EMISSIVE_SAMPLER,IN.TexCoord0).rgb;\n"
+        "#else \n"
+            "EMISSIVE_COLOR.rgb;\n"
+        "#endif // !AV_EMISSIVE_TEXTURE\n"
+        "}\n"
+
+        "#ifdef AV_OPACITY\n"
+        "OUT.a = TRANSPARENCY;\n"
+        "#endif\n"
+        "#ifdef AV_OPACITY_TEXTURE\n"
+        "OUT.a *= tex2D(OPACITY_SAMPLER,IN.TexCoord0). AV_OPACITY_TEXTURE_REGISTER_MASK;\n"
+        "#endif\n"
+        "return OUT;\n"
+    "}\n"
+
+
+    // Technique for the material effect
+    "technique MaterialFXSpecular_D1\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "#ifdef AV_OPACITY_TEXTURE\n"
+            "AlphaBlendEnable=TRUE;"
+            "SrcBlend = srcalpha;\n"
+            "DestBlend = invsrcalpha;\n"
+            "#else\n"
+            "#ifdef AV_OPACITY\n"
+            "AlphaBlendEnable=TRUE;"
+            "SrcBlend = srcalpha;\n"
+            "DestBlend = invsrcalpha;\n"
+            "#endif \n"
+            "#endif\n"
+
+            "PixelShader = compile ps_3_0 MaterialPShaderSpecular_D1();\n"
+            "VertexShader = compile vs_3_0 MaterialVShader_D1();\n"
+        "}\n"
+    "};\n"
+    "technique MaterialFXSpecular_D2\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "#ifdef AV_OPACITY_TEXTURE\n"
+            "AlphaBlendEnable=TRUE;"
+            "SrcBlend = srcalpha;\n"
+            "DestBlend = invsrcalpha;\n"
+            "#else\n"
+            "#ifdef AV_OPACITY\n"
+            "AlphaBlendEnable=TRUE;"
+            "SrcBlend = srcalpha;\n"
+            "DestBlend = invsrcalpha;\n"
+            "#endif \n"
+            "#endif\n"
+
+            "PixelShader = compile ps_3_0 MaterialPShaderSpecular_D2();\n"
+            "VertexShader = compile vs_3_0 MaterialVShader_D2();\n"
+        "}\n"
+    "};\n"
+
+    // Technique for the material effect (ps_2_0)
+    "technique MaterialFXSpecular_PS20_D1\n"
+    "{\n"
+        "pass p0\n"
+    "{\n"
+          "#ifdef AV_OPACITY_TEXTURE\n"
+          "AlphaBlendEnable=TRUE;"
+          "SrcBlend = srcalpha;\n"
+          "DestBlend = invsrcalpha;\n"
+          "#else\n"
+          "#ifdef AV_OPACITY\n"
+          "AlphaBlendEnable=TRUE;"
+          "SrcBlend = srcalpha;\n"
+          "DestBlend = invsrcalpha;\n"
+          "#endif \n"
+          "#endif\n"
+
+          "PixelShader = compile ps_2_0 MaterialPShaderSpecular_PS20_D1();\n"
+          "VertexShader = compile vs_2_0 MaterialVShader_D1();\n"
+        "}\n"
+    "};\n"
+
+    "technique MaterialFXSpecular_PS20_D2\n"
+    "{\n"
+        "pass p0\n"
+      "{\n"
+          "//CullMode=none;\n"
+
+          "#ifdef AV_OPACITY_TEXTURE\n"
+          "AlphaBlendEnable=TRUE;"
+          "SrcBlend = srcalpha;\n"
+          "DestBlend = invsrcalpha;\n"
+          "#else\n"
+          "#ifdef AV_OPACITY\n"
+          "AlphaBlendEnable=TRUE;"
+          "SrcBlend = srcalpha;\n"
+          "DestBlend = invsrcalpha;\n"
+          "#endif \n"
+          "#endif\n"
+
+          "PixelShader = compile ps_2_0 MaterialPShaderSpecular_PS20_D2();\n"
+          "VertexShader = compile vs_2_0 MaterialVShader_D2();\n"
+        "}\n"
+    "};\n"
+
+    // Technique for the material effect using fixed function pixel pipeline
+    "technique MaterialFX_FF\n"
+    "{\n"
+        "pass p0\n"
+        "{\n"
+            "//CullMode=none;\n"
+            "SpecularEnable = true; \n"
+            "VertexShader = compile vs_2_0 MaterialVShader_FF();\n"
+            "ColorOp[0] = Modulate;\n"
+            "ColorArg0[0] = Texture;\n"
+            "ColorArg1[0] = Diffuse;\n"
+            "AlphaOp[0] = Modulate;\n"
+            "AlphaArg0[0] = Texture;\n"
+            "AlphaArg1[0] = Diffuse;\n"
+        "}\n"
+    "};\n"
+    );
+
+std::string g_szPassThroughShader = std::string(
+        "texture TEXTURE_2D;\n"
+        "sampler TEXTURE_SAMPLER = sampler_state\n"
+        "{\n"
+            "Texture = (TEXTURE_2D);\n"
+            "MinFilter = POINT;\n"
+            "MagFilter = POINT;\n"
+        "};\n"
+
+    // Vertex Shader output for pixel shader usage
+        "struct VS_OUTPUT\n"
+        "{\n"
+            "float4 Position : POSITION;\n"
+            "float2 TexCoord0 : TEXCOORD0;\n"
+        "};\n"
+
+    // vertex shader for pixel shader usage
+        "VS_OUTPUT DefaultVShader(float4 INPosition : POSITION, float2 INTexCoord0 : TEXCOORD0 )\n"
+        "{\n"
+            "VS_OUTPUT Out;\n"
+
+            "Out.Position = INPosition;\n"
+            "Out.TexCoord0 = INTexCoord0;\n"
+
+            "return Out;\n"
+        "}\n"
+
+        // simply lookup a texture
+        "float4 PassThrough_PS(float2 IN : TEXCOORD0) : COLOR\n"
+        "{\n"
+        "  return tex2D(TEXTURE_SAMPLER,IN);\n"
+        "}\n"
+
+        // visualize the alpha channel (in black) -> use a
+        "float4 PassThroughAlphaA_PS(float2 IN : TEXCOORD0) : COLOR\n"
+        "{\n"
+        "  return float4(0.0f,0.0f,0.0f,tex2D(TEXTURE_SAMPLER,IN).a);\n"
+        "}\n"
+
+        // visualize the alpha channel (in black) -> use r
+        "float4 PassThroughAlphaR_PS(float2 IN : TEXCOORD0) : COLOR\n"
+        "{\n"
+        "  return float4(0.0f,0.0f,0.0f,tex2D(TEXTURE_SAMPLER,IN).r);\n"
+        "}\n"
+
+        // Simple pass-through technique
+        "technique PassThrough\n"
+        "{\n"
+            "pass p0\n"
+            "{\n"
+                "FillMode=Solid;\n"
+                "ZEnable = FALSE;\n"
+                "CullMode = none;\n"
+                "AlphaBlendEnable = TRUE;\n"
+                "SrcBlend =srcalpha;\n"
+                "DestBlend =invsrcalpha;\n"
+                "PixelShader = compile ps_2_0 PassThrough_PS();\n"
+                "VertexShader = compile vs_2_0 DefaultVShader();\n"
+            "}\n"
+        "};\n"
+
+        // Pass-through technique which visualizes the texture's alpha channel
+        "technique PassThroughAlphaFromA\n"
+        "{\n"
+            "pass p0\n"
+            "{\n"
+                "FillMode=Solid;\n"
+                "ZEnable = FALSE;\n"
+                "CullMode = none;\n"
+                "AlphaBlendEnable = TRUE;\n"
+                "SrcBlend =srcalpha;\n"
+                "DestBlend =invsrcalpha;\n"
+                "PixelShader = compile ps_2_0 PassThroughAlphaA_PS();\n"
+                "VertexShader = compile vs_2_0 DefaultVShader();\n"
+            "}\n"
+        "};\n"
+
+        // Pass-through technique which visualizes the texture's red channel
+        "technique PassThroughAlphaFromR\n"
+        "{\n"
+            "pass p0\n"
+            "{\n"
+                "FillMode=Solid;\n"
+                "ZEnable = FALSE;\n"
+                "CullMode = none;\n"
+                "AlphaBlendEnable = TRUE;\n"
+                "SrcBlend =srcalpha;\n"
+                "DestBlend =invsrcalpha;\n"
+                "PixelShader = compile ps_2_0 PassThroughAlphaR_PS();\n"
+                "VertexShader = compile vs_2_0 DefaultVShader();\n"
+            "}\n"
+        "};\n"
+
+        // technique for fixed function pixel pipeline
+        "technique PassThrough_FF\n"
+        "{\n"
+            "pass p0\n"
+            "{\n"
+                "ZEnable = FALSE;\n"
+                "CullMode = none;\n"
+                "AlphaBlendEnable = TRUE;\n"
+                "SrcBlend =srcalpha;\n"
+                "DestBlend =invsrcalpha;\n"
+                "VertexShader = compile vs_2_0 DefaultVShader();\n"
+        "ColorOp[0] = SelectArg1;\n"
+        "ColorArg0[0] = Texture;\n"
+        "AlphaOp[0] = SelectArg1;\n"
+        "AlphaArg0[0] = Texture;\n"
+            "}\n"
+        "};\n"
+    );
+
+std::string g_szCheckerBackgroundShader = std::string(
+
+        // the two colors used to draw the checker pattern
+        "float3 COLOR_ONE = float3(0.4f,0.4f,0.4f);\n"
+        "float3 COLOR_TWO = float3(0.6f,0.6f,0.6f);\n"
+
+        // size of a square in both x and y direction
+        "float SQUARE_SIZE = 10.0f;\n"
+
+    // vertex shader output structure
+        "struct VS_OUTPUT\n"
+        "{\n"
+            "float4 Position : POSITION;\n"	
+        "};\n"
+
+    // vertex shader 
+        "VS_OUTPUT DefaultVShader(float4 INPosition : POSITION, float2 INTexCoord0 : TEXCOORD0 )\n"
+        "{\n"
+            "VS_OUTPUT Out;\n"
+
+            "Out.Position = INPosition;\n"
+            "return Out;\n"
+        "}\n"
+
+        // pixel shader
+        "float4 MakePattern_PS(float2 IN : VPOS) : COLOR\n"
+        "{\n"
+          "float2 fDiv = IN / SQUARE_SIZE;\n"
+          "float3 fColor = COLOR_ONE;\n"
+          "if (0 == round(fmod(round(fDiv.x),2)))\n"
+          "{\n"
+          "  if (0 == round(fmod(round(fDiv.y),2))) fColor = COLOR_TWO;\n"
+          "}\n"
+          "else if (0 != round(fmod(round(fDiv.y),2)))fColor = COLOR_TWO;\n"
+          "return float4(fColor,1.0f);"
+        "}\n"
+    
+        // technique to generate a pattern
+        "technique MakePattern\n"
+        "{\n"
+          "pass p0\n"
+          "{\n"
+            "FillMode=Solid;\n"
+            "ZEnable = FALSE;\n"
+            "CullMode = none;\n"
+            "PixelShader = compile ps_3_0 MakePattern_PS();\n"
+            "VertexShader = compile vs_3_0 DefaultVShader();\n"
+          "}\n"
+        "};\n"
+        );
     };

+ 1189 - 1189
tools/assimp_view/assimp_view.cpp

@@ -1,1189 +1,1189 @@
-/*
----------------------------------------------------------------------------
-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.
----------------------------------------------------------------------------
-*/
-
-
-#include "assimp_view.h"
-#include <map>
-
-using namespace std;
-
-namespace AssimpView {
-
-extern std::string g_szNormalsShader;
-extern std::string g_szDefaultShader;
-extern std::string g_szPassThroughShader;
-
-//-------------------------------------------------------------------------------
-HINSTANCE g_hInstance				= NULL;
-HWND g_hDlg							= NULL;
-IDirect3D9* g_piD3D					= NULL;
-IDirect3DDevice9* g_piDevice		= NULL;
-IDirect3DVertexDeclaration9* gDefaultVertexDecl = NULL;
-double g_fFPS						= 0.0f;
-char g_szFileName[MAX_PATH];
-ID3DXEffect* g_piDefaultEffect		= NULL;
-ID3DXEffect* g_piNormalsEffect		= NULL;
-ID3DXEffect* g_piPassThroughEffect	= NULL;
-ID3DXEffect* g_piPatternEffect		= NULL;
-bool g_bMousePressed				= false;
-bool g_bMousePressedR				= false;
-bool g_bMousePressedM				= false;
-bool g_bMousePressedBoth			= false;
-float g_fElpasedTime				= 0.0f;
-D3DCAPS9 g_sCaps;
-bool g_bLoadingFinished				= false;
-HANDLE g_hThreadHandle				= NULL;
-float g_fWheelPos					= -10.0f;
-bool g_bLoadingCanceled				= false;
-IDirect3DTexture9* g_pcTexture		= NULL;
-bool g_bPlay						= false;
-double g_dCurrent = 0.;
-
-// default pp steps
-unsigned int ppsteps = aiProcess_CalcTangentSpace | // calculate tangents and bitangents if possible
-        aiProcess_JoinIdenticalVertices    | // join identical vertices/ optimize indexing
-        aiProcess_ValidateDataStructure    | // perform a full validation of the loader's output
-        aiProcess_ImproveCacheLocality     | // improve the cache locality of the output vertices
-        aiProcess_RemoveRedundantMaterials | // remove redundant materials
-        aiProcess_FindDegenerates          | // remove degenerated polygons from the import
-        aiProcess_FindInvalidData          | // detect invalid model data, such as invalid normal vectors
-        aiProcess_GenUVCoords              | // convert spherical, cylindrical, box and planar mapping to proper UVs
-        aiProcess_TransformUVCoords        | // preprocess UV transformations (scaling, translation ...)
-        aiProcess_FindInstances            | // search for instanced meshes and remove them by references to one master
-        aiProcess_LimitBoneWeights         | // limit bone weights to 4 per vertex
-        aiProcess_OptimizeMeshes		   | // join small meshes, if possible;
-        aiProcess_SplitByBoneCount         | // split meshes with too many bones. Necessary for our (limited) hardware skinning shader
-        0;
-
-unsigned int ppstepsdefault = ppsteps;
-
-bool nopointslines = false;
-
-extern bool g_bWasFlipped			/*= false*/;
-
-aiMatrix4x4 g_mWorld;
-aiMatrix4x4 g_mWorldRotate;
-aiVector3D g_vRotateSpeed			= aiVector3D(0.5f,0.5f,0.5f);
-
-// NOTE: The second light direction is now computed from the first
-aiVector3D g_avLightDirs[1] = 
-{	aiVector3D(-0.5f,0.6f,0.2f)  };
-
-D3DCOLOR g_avLightColors[3] = 
-{
-    D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0xFF),
-    D3DCOLOR_ARGB(0xFF,0xFF,0x00,0x00),
-    D3DCOLOR_ARGB(0xFF,0x05,0x05,0x05),
-};
-
-POINT g_mousePos;
-POINT g_LastmousePos;
-bool g_bFPSView						= false;
-bool g_bInvert						= false;
-EClickPos g_eClick					= EClickPos_Circle;
-unsigned int g_iCurrentColor		= 0;
-
-float g_fLightIntensity				= 1.0f;
-float g_fLightColor					= 1.0f;
-
-RenderOptions g_sOptions;
-Camera g_sCamera;
-AssetHelper *g_pcAsset				= NULL;
-
-//
-// Contains the mask image for the HUD 
-// (used to determine the position of a click)
-//
-unsigned char* g_szImageMask		= NULL;
-
-float g_fLoadTime = 0.0f;
-
-
-//-------------------------------------------------------------------------------
-// Entry point for the loader thread
-// The laoder thread loads the asset while the progress dialog displays the
-// smart progress bar
-//-------------------------------------------------------------------------------
-DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
-{
-    UNREFERENCED_PARAMETER(lpParameter);
-
-    // get current time
-    double fCur = (double)timeGetTime();
-
-    aiPropertyStore* props = aiCreatePropertyStore();
-    aiSetImportPropertyInteger(props,AI_CONFIG_IMPORT_TER_MAKE_UVS,1);
-    aiSetImportPropertyFloat(props,AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,g_smoothAngle);
-    aiSetImportPropertyInteger(props,AI_CONFIG_PP_SBP_REMOVE,nopointslines ? aiPrimitiveType_LINE | aiPrimitiveType_POINT : 0 );
-
-    aiSetImportPropertyInteger(props,AI_CONFIG_GLOB_MEASURE_TIME,1);
-    //aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
-
-    // Call ASSIMPs C-API to load the file
-    g_pcAsset->pcScene = (aiScene*)aiImportFileExWithProperties(g_szFileName,
-
-        ppsteps | /* configurable pp steps */
-        aiProcess_GenSmoothNormals		   | // generate smooth normal vectors if not existing
-        aiProcess_SplitLargeMeshes         | // split large, unrenderable meshes into submeshes
-        aiProcess_Triangulate			   | // triangulate polygons with more than 3 edges
-        aiProcess_ConvertToLeftHanded	   | // convert everything to D3D left handed space
-        aiProcess_SortByPType              | // make 'clean' meshes which consist of a single typ of primitives
-        0,
-        NULL,
-        props);
-
-    aiReleasePropertyStore(props);
-
-    // get the end time of zje operation, calculate delta t
-    double fEnd = (double)timeGetTime();
-    g_fLoadTime = (float)((fEnd - fCur) / 1000);
-//	char szTemp[128];
-    g_bLoadingFinished = true;
-
-    // check whether the loading process has failed ...
-    if (NULL == g_pcAsset->pcScene)
-    {
-        CLogDisplay::Instance().AddEntry("[ERROR] Unable to load this asset:",
-            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
-
-        // print ASSIMPs error string to the log display
-        CLogDisplay::Instance().AddEntry(aiGetErrorString(),
-            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
-        return 1;
-    }
-
-    return 0;
-}
-
-//-------------------------------------------------------------------------------
-// load the current asset
-// THe path to the asset is specified in the global path variable
-//-------------------------------------------------------------------------------
-int LoadAsset(void)
-{
-    // set the world and world rotation matrices to the identuty
-    g_mWorldRotate = aiMatrix4x4();
-    g_mWorld = aiMatrix4x4();
-
-//	char szTemp[MAX_PATH+64];
-//	sprintf(szTemp,"Starting to load %s",g_szFileName);
-    CLogWindow::Instance().WriteLine(
-        "----------------------------------------------------------------------------");
-//	CLogWindow::Instance().WriteLine(szTemp);
-//	CLogWindow::Instance().WriteLine(
-//		"----------------------------------------------------------------------------");
-    CLogWindow::Instance().SetAutoUpdate(false);
-
-    // create a helper thread to load the asset
-    DWORD dwID;
-    g_bLoadingCanceled = false;
-    g_pcAsset = new AssetHelper();
-    g_hThreadHandle = CreateThread(NULL,0,&LoadThreadProc,NULL,0,&dwID);
-
-    if (!g_hThreadHandle)
-    {
-        CLogDisplay::Instance().AddEntry(
-            "[ERROR] Unable to create helper thread for loading",
-            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
-        return 0;
-    }
-
-    // show the progress bar dialog
-    DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_LOADDIALOG),
-        g_hDlg,&ProgressMessageProc);
-
-    // update the log window
-    CLogWindow::Instance().SetAutoUpdate(true);
-    CLogWindow::Instance().Update();
-
-    // now we should have loaded the asset. Check this ...
-    g_bLoadingFinished = false;
-    if (!g_pcAsset || !g_pcAsset->pcScene)
-    {
-        if (g_pcAsset)
-        {
-            delete g_pcAsset;
-            g_pcAsset = NULL;
-        }
-        return 0;
-    }
-
-    // allocate a new MeshHelper array and build a new instance
-    // for each mesh in the original asset
-    g_pcAsset->apcMeshes = new AssetHelper::MeshHelper*[g_pcAsset->pcScene->mNumMeshes]();
-    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
-        g_pcAsset->apcMeshes[i] = new AssetHelper::MeshHelper();
-
-
-    // create animator
-    g_pcAsset->mAnimator = new SceneAnimator( g_pcAsset->pcScene);
-
-    // build a new caption string for the viewer
-    char szOut[MAX_PATH + 10];
-    sprintf(szOut,AI_VIEW_CAPTION_BASE " [%s]",g_szFileName);
-    SetWindowText(g_hDlg,szOut);
-
-    // scale the asset vertices to fit into the viewer window
-    ScaleAsset();
-
-    // reset the camera view to the default position
-    g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
-    g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
-    g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
-    g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
-
-    // build native D3D vertex/index buffers, textures, materials
-    if( 1 != CreateAssetData())
-        return 0;
-
-    if (!g_pcAsset->pcScene->HasAnimations()) {
-        EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),FALSE);
-        EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),FALSE);
-    }
-    else {
-        EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),TRUE);
-        EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),TRUE);
-    }
-
-    CLogDisplay::Instance().AddEntry("[OK] The asset has been loaded successfully");
-    CDisplay::Instance().FillDisplayList();
-    CDisplay::Instance().FillAnimList();
-
-    CDisplay::Instance().FillDefaultStatistics();
-    
-    // render the scene once
-    CDisplay::Instance().OnRender();
-
-    g_pcAsset->iNormalSet = AssetHelper::ORIGINAL;
-    g_bWasFlipped = false;
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-// Delete the loaded asset
-// The function does nothing is no asset is loaded
-//-------------------------------------------------------------------------------
-int DeleteAsset(void)
-{
-    if (!g_pcAsset)return 0;
-
-    // don't anymore know why this was necessary ...
-    CDisplay::Instance().OnRender();
-
-    // delete everything
-    DeleteAssetData();
-    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
-    {
-        delete g_pcAsset->apcMeshes[i];
-    }
-    aiReleaseImport(g_pcAsset->pcScene);
-    delete[] g_pcAsset->apcMeshes;
-    delete g_pcAsset->mAnimator;
-    delete g_pcAsset;
-    g_pcAsset = NULL;
-
-    // reset the caption of the viewer window
-    SetWindowText(g_hDlg,AI_VIEW_CAPTION_BASE);
-
-    // clear UI
-    CDisplay::Instance().ClearAnimList();
-    CDisplay::Instance().ClearDisplayList();
-
-    CMaterialManager::Instance().Reset();
-    UpdateWindow(g_hDlg);
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-// Calculate the boundaries of a given node and all of its children
-// The boundaries are in Worldspace (AABB)
-// piNode Input node
-// p_avOut Receives the min/max boundaries. Must point to 2 vec3s
-// piMatrix Transformation matrix of the graph at this position
-//-------------------------------------------------------------------------------
-int CalculateBounds(aiNode* piNode, aiVector3D* p_avOut, 
-    const aiMatrix4x4& piMatrix)
-{
-    ai_assert(NULL != piNode);
-    ai_assert(NULL != p_avOut);
-
-    aiMatrix4x4 mTemp = piNode->mTransformation;
-    mTemp.Transpose();
-    aiMatrix4x4 aiMe = mTemp * piMatrix;
-
-    for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
-    {
-        for( unsigned int a = 0; a < g_pcAsset->pcScene->mMeshes[
-            piNode->mMeshes[i]]->mNumVertices;++a)
-        {
-            aiVector3D pc =g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mVertices[a];
-
-            aiVector3D pc1;
-            D3DXVec3TransformCoord((D3DXVECTOR3*)&pc1,(D3DXVECTOR3*)&pc,
-                (D3DXMATRIX*)&aiMe);
-
-            p_avOut[0].x = min( p_avOut[0].x, pc1.x);
-            p_avOut[0].y = min( p_avOut[0].y, pc1.y);
-            p_avOut[0].z = min( p_avOut[0].z, pc1.z);
-            p_avOut[1].x = max( p_avOut[1].x, pc1.x);
-            p_avOut[1].y = max( p_avOut[1].y, pc1.y);
-            p_avOut[1].z = max( p_avOut[1].z, pc1.z);
-        }
-    }
-    for (unsigned int i = 0; i < piNode->mNumChildren;++i)
-    {
-        CalculateBounds( piNode->mChildren[i], p_avOut, aiMe );
-    }
-    return 1;
-}
-//-------------------------------------------------------------------------------
-// Scale the asset that it fits perfectly into the viewer window
-// The function calculates the boundaries of the mesh and modifies the
-// global world transformation matrix according to the aset AABB
-//-------------------------------------------------------------------------------
-int ScaleAsset(void)
-{
-    aiVector3D aiVecs[2] = {aiVector3D( 1e10f, 1e10f, 1e10f),
-        aiVector3D( -1e10f, -1e10f, -1e10f) };
-
-    if (g_pcAsset->pcScene->mRootNode)
-    {
-        aiMatrix4x4 m;
-        CalculateBounds(g_pcAsset->pcScene->mRootNode,aiVecs,m);
-    }
-
-    aiVector3D vDelta = aiVecs[1]-aiVecs[0];
-    aiVector3D vHalf =  aiVecs[0] + (vDelta / 2.0f);
-    float fScale = 10.0f / vDelta.Length();
-
-    g_mWorld =  aiMatrix4x4(
-        1.0f,0.0f,0.0f,0.0f,
-        0.0f,1.0f,0.0f,0.0f,
-        0.0f,0.0f,1.0f,0.0f,
-        -vHalf.x,-vHalf.y,-vHalf.z,1.0f) *
-        aiMatrix4x4(
-        fScale,0.0f,0.0f,0.0f,
-        0.0f,fScale,0.0f,0.0f,
-        0.0f,0.0f,fScale,0.0f,
-        0.0f,0.0f,0.0f,1.0f);
-    return 1;
-}
-
-//-------------------------------------------------------------------------------
-// Generate a vertex buffer which holds the normals of the asset as
-// a list of unconnected lines
-// pcMesh Input mesh
-// pcSource Source mesh from ASSIMP
-//-------------------------------------------------------------------------------
-int GenerateNormalsAsLineList(AssetHelper::MeshHelper* pcMesh,const aiMesh* pcSource)
-{
-    ai_assert(NULL != pcMesh);
-    ai_assert(NULL != pcSource);
-
-    if (!pcSource->mNormals)return 0;
-
-    // create vertex buffer
-    if(FAILED( g_piDevice->CreateVertexBuffer(sizeof(AssetHelper::LineVertex) *
-        pcSource->mNumVertices * 2,
-        D3DUSAGE_WRITEONLY,
-        AssetHelper::LineVertex::GetFVF(),
-        D3DPOOL_DEFAULT, &pcMesh->piVBNormals,NULL)))
-    {
-        CLogDisplay::Instance().AddEntry("Failed to create vertex buffer for the normal list",
-            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
-        return 2;
-    }
-
-    // now fill the vertex buffer with data
-    AssetHelper::LineVertex* pbData2;
-    pcMesh->piVBNormals->Lock(0,0,(void**)&pbData2,0);
-    for (unsigned int x = 0; x < pcSource->mNumVertices;++x)
-    {
-        pbData2->vPosition = pcSource->mVertices[x];
-
-        ++pbData2;
-
-        aiVector3D vNormal = pcSource->mNormals[x];
-        vNormal.Normalize();
-
-        // scalo with the inverse of the world scaling to make sure
-        // the normals have equal length in each case
-        // TODO: Check whether this works in every case, I don't think so
-        vNormal.x /= g_mWorld.a1*4;
-        vNormal.y /= g_mWorld.b2*4;
-        vNormal.z /= g_mWorld.c3*4;
-
-        pbData2->vPosition = pcSource->mVertices[x] + vNormal;
-
-        ++pbData2;
-    }
-    pcMesh->piVBNormals->Unlock();
-    return 1;
-}
-
-//-------------------------------------------------------------------------------
-// Create the native D3D representation of the asset: vertex buffers,
-// index buffers, materials ...
-//-------------------------------------------------------------------------------
-int CreateAssetData()
-{
-    if (!g_pcAsset)return 0;
-
-    // reset all subsystems
-    CMaterialManager::Instance().Reset();
-    CDisplay::Instance().Reset();
-
-    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
-    {
-        const aiMesh* mesh = g_pcAsset->pcScene->mMeshes[i];
-
-        // create the material for the mesh
-        if (!g_pcAsset->apcMeshes[i]->piEffect)	{
-            CMaterialManager::Instance().CreateMaterial(
-                g_pcAsset->apcMeshes[i],mesh);
-        }
-
-        // create vertex buffer
-        if(FAILED( g_piDevice->CreateVertexBuffer(sizeof(AssetHelper::Vertex) *
-            mesh->mNumVertices,
-            D3DUSAGE_WRITEONLY,
-            0,
-            D3DPOOL_DEFAULT, &g_pcAsset->apcMeshes[i]->piVB,NULL)))	{
-            MessageBox(g_hDlg,"Failed to create vertex buffer",
-                "ASSIMP Viewer Utility",MB_OK);
-            return 2;
-        }
-
-        DWORD dwUsage = 0;
-        if (g_pcAsset->apcMeshes[i]->piOpacityTexture || 1.0f != g_pcAsset->apcMeshes[i]->fOpacity)
-            dwUsage |= D3DUSAGE_DYNAMIC;
-
-        unsigned int nidx;
-        switch (mesh->mPrimitiveTypes) {
-            case aiPrimitiveType_POINT:
-                nidx = 1;break;
-            case aiPrimitiveType_LINE:
-                nidx = 2;break;
-            case aiPrimitiveType_TRIANGLE:
-                nidx = 3;break;
-            default: ai_assert(false);
-        };
-
-        // check whether we can use 16 bit indices
-        if (mesh->mNumFaces * 3 >= 65536)	{
-            // create 32 bit index buffer
-            if(FAILED( g_piDevice->CreateIndexBuffer( 4 *
-                mesh->mNumFaces * nidx,
-                D3DUSAGE_WRITEONLY | dwUsage,
-                D3DFMT_INDEX32,
-                D3DPOOL_DEFAULT, 
-                &g_pcAsset->apcMeshes[i]->piIB,
-                NULL)))
-            {
-                MessageBox(g_hDlg,"Failed to create 32 Bit index buffer",
-                    "ASSIMP Viewer Utility",MB_OK);
-                return 2;
-            }
-
-            // now fill the index buffer
-            unsigned int* pbData;
-            g_pcAsset->apcMeshes[i]->piIB->Lock(0,0,(void**)&pbData,0);
-            for (unsigned int x = 0; x < mesh->mNumFaces;++x)
-            {
-                for (unsigned int a = 0; a < nidx;++a)
-                {
-                    *pbData++ = mesh->mFaces[x].mIndices[a];
-                }
-            }
-        }
-        else	{
-            // create 16 bit index buffer
-            if(FAILED( g_piDevice->CreateIndexBuffer( 2 *
-                mesh->mNumFaces * nidx,
-                D3DUSAGE_WRITEONLY | dwUsage,
-                D3DFMT_INDEX16,
-                D3DPOOL_DEFAULT,
-                &g_pcAsset->apcMeshes[i]->piIB,
-                NULL)))
-            {
-                MessageBox(g_hDlg,"Failed to create 16 Bit index buffer",
-                    "ASSIMP Viewer Utility",MB_OK);
-                return 2;
-            }
-
-            // now fill the index buffer
-            uint16_t* pbData;
-            g_pcAsset->apcMeshes[i]->piIB->Lock(0,0,(void**)&pbData,0);
-            for (unsigned int x = 0; x < mesh->mNumFaces;++x)
-            {
-                for (unsigned int a = 0; a < nidx;++a)
-                {
-                    *pbData++ = (uint16_t)mesh->mFaces[x].mIndices[a];
-                }
-            }
-        }
-        g_pcAsset->apcMeshes[i]->piIB->Unlock();
-
-        // collect weights on all vertices. Quick and careless
-        std::vector<std::vector<aiVertexWeight> > weightsPerVertex( mesh->mNumVertices);
-        for( unsigned int a = 0; a < mesh->mNumBones; a++)	{
-            const aiBone* bone = mesh->mBones[a];
-            for( unsigned int b = 0; b < bone->mNumWeights; b++)
-                weightsPerVertex[bone->mWeights[b].mVertexId].push_back( aiVertexWeight( a, bone->mWeights[b].mWeight));
-        }
-
-        // now fill the vertex buffer
-        AssetHelper::Vertex* pbData2;
-        g_pcAsset->apcMeshes[i]->piVB->Lock(0,0,(void**)&pbData2,0);
-        for (unsigned int x = 0; x < mesh->mNumVertices;++x)
-        {
-            pbData2->vPosition = mesh->mVertices[x];
-
-            if (NULL == mesh->mNormals)
-                pbData2->vNormal = aiVector3D(0.0f,0.0f,0.0f);
-            else pbData2->vNormal = mesh->mNormals[x];
-
-            if (NULL == mesh->mTangents)	{
-                pbData2->vTangent = aiVector3D(0.0f,0.0f,0.0f);
-                pbData2->vBitangent = aiVector3D(0.0f,0.0f,0.0f);
-            }
-            else	{
-                pbData2->vTangent = mesh->mTangents[x];
-                pbData2->vBitangent = mesh->mBitangents[x];
-            }
-
-            if (mesh->HasVertexColors( 0))	{
-                pbData2->dColorDiffuse = D3DCOLOR_ARGB(
-                    ((unsigned char)max( min( mesh->mColors[0][x].a * 255.0f, 255.0f),0.0f)),
-                    ((unsigned char)max( min( mesh->mColors[0][x].r * 255.0f, 255.0f),0.0f)),
-                    ((unsigned char)max( min( mesh->mColors[0][x].g * 255.0f, 255.0f),0.0f)),
-                    ((unsigned char)max( min( mesh->mColors[0][x].b * 255.0f, 255.0f),0.0f)));
-            }
-            else pbData2->dColorDiffuse = D3DCOLOR_ARGB(0xFF,0xff,0xff,0xff);
-
-            // ignore a third texture coordinate component
-            if (mesh->HasTextureCoords( 0))	{
-                pbData2->vTextureUV = aiVector2D(
-                    mesh->mTextureCoords[0][x].x,
-                    mesh->mTextureCoords[0][x].y);
-            }
-            else pbData2->vTextureUV = aiVector2D(0.5f,0.5f);
-
-            if (mesh->HasTextureCoords( 1))	{
-                pbData2->vTextureUV2 = aiVector2D(
-                    mesh->mTextureCoords[1][x].x,
-                    mesh->mTextureCoords[1][x].y);
-            }
-            else pbData2->vTextureUV2 = aiVector2D(0.5f,0.5f);
-
-            // Bone indices and weights
-            if( mesh->HasBones())	{
-                unsigned char boneIndices[4] = { 0, 0, 0, 0 };
-                unsigned char boneWeights[4] = { 0, 0, 0, 0 };
-                ai_assert( weightsPerVertex[x].size() <= 4);
-                for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++)
-                {
-                    boneIndices[a] = weightsPerVertex[x][a].mVertexId;
-                    boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f);
-                }
-
-                memcpy( pbData2->mBoneIndices, boneIndices, sizeof( boneIndices));
-                memcpy( pbData2->mBoneWeights, boneWeights, sizeof( boneWeights));
-            } else
-            {
-                memset( pbData2->mBoneIndices, 0, sizeof( pbData2->mBoneIndices));
-                memset( pbData2->mBoneWeights, 0, sizeof( pbData2->mBoneWeights));
-            }
-
-            ++pbData2;
-        }
-        g_pcAsset->apcMeshes[i]->piVB->Unlock();
-
-        // now generate the second vertex buffer, holding all normals
-        if (!g_pcAsset->apcMeshes[i]->piVBNormals)	{
-            GenerateNormalsAsLineList(g_pcAsset->apcMeshes[i],mesh);
-        }
-    }
-    return 1;
-}
-
-//-------------------------------------------------------------------------------
-// Delete all effects, textures, vertex buffers ... associated with
-// an asset
-//-------------------------------------------------------------------------------
-int DeleteAssetData(bool bNoMaterials)
-{
-    if (!g_pcAsset)return 0;
-
-    // TODO: Move this to a proper destructor
-    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
-    {
-        if(g_pcAsset->apcMeshes[i]->piVB)
-        {
-            g_pcAsset->apcMeshes[i]->piVB->Release();
-            g_pcAsset->apcMeshes[i]->piVB = NULL;
-        }
-        if(g_pcAsset->apcMeshes[i]->piVBNormals)
-        {
-            g_pcAsset->apcMeshes[i]->piVBNormals->Release();
-            g_pcAsset->apcMeshes[i]->piVBNormals = NULL;
-        }
-        if(g_pcAsset->apcMeshes[i]->piIB)
-        {
-            g_pcAsset->apcMeshes[i]->piIB->Release();
-            g_pcAsset->apcMeshes[i]->piIB = NULL;
-        }
-
-        // TODO ... unfixed memory leak
-        // delete storage eventually allocated to hold a copy
-        // of the original vertex normals
-        //if (g_pcAsset->apcMeshes[i]->pvOriginalNormals)
-        //{
-        //	delete[] g_pcAsset->apcMeshes[i]->pvOriginalNormals;
-        //}
-
-        if (!bNoMaterials)
-        {
-            if(g_pcAsset->apcMeshes[i]->piEffect)
-            {
-                g_pcAsset->apcMeshes[i]->piEffect->Release();
-                g_pcAsset->apcMeshes[i]->piEffect = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piDiffuseTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piDiffuseTexture->Release();
-                g_pcAsset->apcMeshes[i]->piDiffuseTexture = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piNormalTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piNormalTexture->Release();
-                g_pcAsset->apcMeshes[i]->piNormalTexture = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piSpecularTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piSpecularTexture->Release();
-                g_pcAsset->apcMeshes[i]->piSpecularTexture = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piAmbientTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piAmbientTexture->Release();
-                g_pcAsset->apcMeshes[i]->piAmbientTexture = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piEmissiveTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piEmissiveTexture->Release();
-                g_pcAsset->apcMeshes[i]->piEmissiveTexture = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piOpacityTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piOpacityTexture->Release();
-                g_pcAsset->apcMeshes[i]->piOpacityTexture = NULL;
-            }
-            if(g_pcAsset->apcMeshes[i]->piShininessTexture)
-            {
-                g_pcAsset->apcMeshes[i]->piShininessTexture->Release();
-                g_pcAsset->apcMeshes[i]->piShininessTexture = NULL;
-            }
-        }
-    }
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-// Switch beetween zoom/rotate view and the standatd FPS view
-// g_bFPSView specifies the view mode to setup
-//-------------------------------------------------------------------------------
-int SetupFPSView()
-{
-    if (!g_bFPSView)
-    {
-        g_sCamera.vPos = aiVector3D(0.0f,0.0f,g_fWheelPos);
-        g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
-        g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
-        g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
-    }
-    else
-    {
-        g_fWheelPos = g_sCamera.vPos.z;
-        g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
-        g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
-        g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
-        g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
-    }
-    return 1;
-}
-
-//-------------------------------------------------------------------------------
-// Initialize the IDIrect3D interface
-// Called by the WinMain
-//-------------------------------------------------------------------------------
-int InitD3D(void)
-{
-    if (NULL == g_piD3D)
-    {
-        g_piD3D = Direct3DCreate9(D3D_SDK_VERSION);
-        if (NULL == g_piD3D)return 0;
-    }
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-// Release the IDirect3D interface.
-// NOTE: Assumes that the device has already been deleted
-//-------------------------------------------------------------------------------
-int ShutdownD3D(void)
-{
-    ShutdownDevice();
-    if (NULL != g_piD3D)
-    {
-        g_piD3D->Release();
-        g_piD3D = NULL;
-    }
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-// Shutdown the D3D devie object and all resources associated with it
-// NOTE: Assumes that the asset has already been deleted
-//-------------------------------------------------------------------------------
-int ShutdownDevice(void)
-{
-    // release other subsystems
-    CBackgroundPainter::Instance().ReleaseNativeResource();
-    CLogDisplay::Instance().ReleaseNativeResource();
-
-    // release global shaders that have been allocazed
-    if (NULL != g_piDefaultEffect)
-    {
-        g_piDefaultEffect->Release();
-        g_piDefaultEffect = NULL;
-    }
-    if (NULL != g_piNormalsEffect)
-    {
-        g_piNormalsEffect->Release();
-        g_piNormalsEffect = NULL;
-    }
-    if (NULL != g_piPassThroughEffect)
-    {
-        g_piPassThroughEffect->Release();
-        g_piPassThroughEffect = NULL;
-    }
-    if (NULL != g_piPatternEffect)
-    {
-        g_piPatternEffect->Release();
-        g_piPatternEffect = NULL;
-    }
-    if (NULL != g_pcTexture)
-    {
-        g_pcTexture->Release();
-        g_pcTexture = NULL;
-    }
-
-    if( NULL != gDefaultVertexDecl)
-    {
-        gDefaultVertexDecl->Release();
-        gDefaultVertexDecl = NULL;
-    }
-
-    // delete the main D3D device object
-    if (NULL != g_piDevice)
-    {
-        g_piDevice->Release();
-        g_piDevice = NULL;
-    }
-
-    // deleted the one channel image allocated to hold the HUD mask
-    delete[] g_szImageMask;
-    g_szImageMask = NULL;
-
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------
-int CreateHUDTexture()
-{
-    // lock the memory resource ourselves
-    HRSRC res = FindResource(NULL,MAKEINTRESOURCE(IDR_HUD),RT_RCDATA);
-    HGLOBAL hg = LoadResource(NULL,res);
-    void* pData = LockResource(hg);
-
-    if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_piDevice,
-        pData,SizeofResource(NULL,res),
-        D3DX_DEFAULT_NONPOW2,
-        D3DX_DEFAULT_NONPOW2,
-        1,
-        0,
-        D3DFMT_A8R8G8B8,
-        D3DPOOL_MANAGED,
-        D3DX_DEFAULT,
-        D3DX_DEFAULT,
-        0,
-        NULL,
-        NULL,
-        &g_pcTexture)))
-    {
-        CLogDisplay::Instance().AddEntry("[ERROR] Unable to load HUD texture",
-            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
-
-        g_pcTexture  = NULL;
-        g_szImageMask = NULL;
-
-        FreeResource(hg);
-        return 0;
-    }
-
-    FreeResource(hg);
-
-    D3DSURFACE_DESC sDesc;
-    g_pcTexture->GetLevelDesc(0,&sDesc);
-
-
-    // lock the memory resource ourselves
-    res = FindResource(NULL,MAKEINTRESOURCE(IDR_HUDMASK),RT_RCDATA);
-    hg = LoadResource(NULL,res);
-    pData = LockResource(hg);
-
-    IDirect3DTexture9* pcTex;
-    if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_piDevice,
-        pData,SizeofResource(NULL,res),
-        sDesc.Width,
-        sDesc.Height,
-        1,
-        0,
-        D3DFMT_L8,
-        D3DPOOL_MANAGED, // unnecessary
-        D3DX_DEFAULT,
-        D3DX_DEFAULT,
-        0,
-        NULL,
-        NULL,
-        &pcTex)))
-    {
-        CLogDisplay::Instance().AddEntry("[ERROR] Unable to load HUD mask texture",
-            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
-        g_szImageMask = NULL;
-
-        FreeResource(hg);
-        return 0;
-    }
-
-    FreeResource(hg);
-
-    // lock the texture and copy it to get a pointer
-    D3DLOCKED_RECT sRect;
-    pcTex->LockRect(0,&sRect,NULL,D3DLOCK_READONLY);
-
-    unsigned char* szOut = new unsigned char[sDesc.Width * sDesc.Height];
-    unsigned char* _szOut = szOut;
-
-    unsigned char* szCur = (unsigned char*) sRect.pBits;
-    for (unsigned int y = 0; y < sDesc.Height;++y)
-    {
-        memcpy(_szOut,szCur,sDesc.Width);
-
-        szCur += sRect.Pitch;
-        _szOut += sDesc.Width;
-    }
-    pcTex->UnlockRect(0);
-    pcTex->Release();
-
-    g_szImageMask = szOut;
-    return 1;
-}
-
-//-------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------
-int CreateDevice (bool p_bMultiSample,bool p_bSuperSample,bool bHW /*= true*/)
-{
-    D3DDEVTYPE eType = bHW ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;
-
-    // get the client rectangle of the window.
-    RECT sRect;
-    GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
-    sRect.right -= sRect.left;
-    sRect.bottom -= sRect.top;
-
-    D3DPRESENT_PARAMETERS sParams;
-    memset(&sParams,0,sizeof(D3DPRESENT_PARAMETERS));
-
-    // get the current display mode
-    D3DDISPLAYMODE sMode;
-    g_piD3D->GetAdapterDisplayMode(0,&sMode);
-
-    // fill the presentation parameter structure
-    sParams.Windowed				= TRUE;
-    sParams.hDeviceWindow			= GetDlgItem( g_hDlg, IDC_RT );
-    sParams.EnableAutoDepthStencil	= TRUE;
-    sParams.PresentationInterval	= D3DPRESENT_INTERVAL_ONE;
-    sParams.BackBufferWidth			= (UINT)sRect.right;
-    sParams.BackBufferHeight		= (UINT)sRect.bottom;
-    sParams.SwapEffect				= D3DSWAPEFFECT_DISCARD;
-    sParams.BackBufferCount			= 1;
-
-    // check whether we can use a D32 depth buffer format
-    if (SUCCEEDED ( g_piD3D->CheckDepthStencilMatch(0,eType,
-        D3DFMT_X8R8G8B8,D3DFMT_X8R8G8B8,D3DFMT_D32)))
-    {
-        sParams.AutoDepthStencilFormat = D3DFMT_D32;
-    }
-    else sParams.AutoDepthStencilFormat = D3DFMT_D24X8;
-
-    // find the highest multisample type available on this device
-    D3DMULTISAMPLE_TYPE sMS = D3DMULTISAMPLE_2_SAMPLES;
-    D3DMULTISAMPLE_TYPE sMSOut = D3DMULTISAMPLE_NONE;
-    DWORD dwQuality = 0;
-    if (p_bMultiSample)
-    {
-        while ((D3DMULTISAMPLE_TYPE)(D3DMULTISAMPLE_16_SAMPLES + 1)  != 
-            (sMS = (D3DMULTISAMPLE_TYPE)(sMS + 1)))
-        {
-            if(SUCCEEDED( g_piD3D->CheckDeviceMultiSampleType(0,eType,
-                sMode.Format,TRUE,sMS,&dwQuality)))
-            {
-                sMSOut = sMS;
-            }
-        }
-        if (0 != dwQuality)dwQuality -= 1;
-
-
-        sParams.MultiSampleQuality = dwQuality;
-        sParams.MultiSampleType = sMSOut;
-    }
-
-    // preget the device capabilities. If the hardware vertex shader is too old, we prefer software vertex processing
-    g_piD3D->GetDeviceCaps( 0, D3DDEVTYPE_HAL, &g_sCaps);
-    DWORD creationFlags = D3DCREATE_MULTITHREADED;
-    if( g_sCaps.VertexShaderVersion >= D3DVS_VERSION( 2, 0))
-        creationFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
-    else
-        creationFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
-
-    // create the D3D9 device object. with software-vertexprocessing if VS2.0 isn`t supported in hardware
-    if(FAILED(g_piD3D->CreateDevice(0,eType, g_hDlg, creationFlags ,&sParams,&g_piDevice)))
-    {
-        // if hardware fails use software rendering instead
-        if (bHW)return CreateDevice(p_bMultiSample,p_bSuperSample,false);
-        return 0;
-    }
-
-    // create a vertex declaration to match the vertex
-    D3DVERTEXELEMENT9* vdecl = AssetHelper::Vertex::GetDeclarationElements();
-    if( FAILED( g_piDevice->CreateVertexDeclaration( vdecl, &gDefaultVertexDecl)))
-    {
-        MessageBox( g_hDlg, "Failed to create vertex declaration", "Init", MB_OK);
-        return 0;
-    }
-    g_piDevice->SetVertexDeclaration( gDefaultVertexDecl);
-
-    // get the capabilities of the device object
-    g_piDevice->GetDeviceCaps(&g_sCaps);
-    if(g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0))
-    {
-        EnableWindow(GetDlgItem(g_hDlg,IDC_LOWQUALITY),FALSE);
-    }
-
-    // compile the default material shader (gray gouraud/phong)
-    ID3DXBuffer* piBuffer = NULL;
-    if(FAILED( D3DXCreateEffect(g_piDevice,
-        g_szDefaultShader.c_str(),
-        (UINT)g_szDefaultShader.length(),
-        NULL,
-        NULL,
-        AI_SHADER_COMPILE_FLAGS,
-        NULL,
-        &g_piDefaultEffect,&piBuffer)))
-    {
-        if( piBuffer) 
-        {
-            MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
-            piBuffer->Release();
-        }
-        return 0;
-    }
-    if( piBuffer) 
-    {
-        piBuffer->Release();
-        piBuffer = NULL;
-    }
-
-    // use Fixed Function effect when working with shaderless cards
-    if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
-        g_piDefaultEffect->SetTechnique( "DefaultFXSpecular_FF");
-
-    // create the shader used to draw the HUD
-    if(FAILED( D3DXCreateEffect(g_piDevice,
-        g_szPassThroughShader.c_str(),(UINT)g_szPassThroughShader.length(),
-        NULL,NULL,AI_SHADER_COMPILE_FLAGS,NULL,&g_piPassThroughEffect,&piBuffer)))
-    {
-        if( piBuffer) 
-        {
-            MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
-            piBuffer->Release();
-        }
-        return 0;
-    }
-    if( piBuffer) 
-    {
-        piBuffer->Release();
-        piBuffer = NULL;
-    }
-
-    // use Fixed Function effect when working with shaderless cards
-    if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
-        g_piPassThroughEffect->SetTechnique( "PassThrough_FF");
-
-    // create the shader used to visualize normal vectors
-    if(FAILED( D3DXCreateEffect(g_piDevice,
-        g_szNormalsShader.c_str(),(UINT)g_szNormalsShader.length(),
-        NULL,NULL,AI_SHADER_COMPILE_FLAGS,NULL,&g_piNormalsEffect, &piBuffer)))
-    {
-        if( piBuffer) 
-        {
-            MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
-            piBuffer->Release();
-        }
-        return 0;
-    }
-    if( piBuffer) 
-    {
-        piBuffer->Release();
-        piBuffer = NULL;
-    }
-
-    //MessageBox( g_hDlg, "Failed to create vertex declaration", "Init", MB_OK);
-
-    // use Fixed Function effect when working with shaderless cards
-    if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
-        g_piNormalsEffect->SetTechnique( "RenderNormals_FF");
-
-    g_piDevice->SetRenderState(D3DRS_DITHERENABLE,TRUE);
-
-    // create the texture for the HUD
-    CreateHUDTexture();
-    CBackgroundPainter::Instance().RecreateNativeResource();
-    CLogDisplay::Instance().RecreateNativeResource();
-
-    g_piPassThroughEffect->SetTexture("TEXTURE_2D",g_pcTexture);
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------
-int CreateDevice (void)
-{
-    return CreateDevice(g_sOptions.bMultiSample,
-        g_sOptions.bSuperSample);
-}
-
-
-//-------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------
-int GetProjectionMatrix (aiMatrix4x4& p_mOut)
-{
-    const float fFarPlane = 100.0f;
-    const float fNearPlane = 0.1f;
-    const float fFOV = (float)(45.0 * 0.0174532925);
-
-    const float s = 1.0f / tanf(fFOV * 0.5f);
-    const float Q = fFarPlane / (fFarPlane - fNearPlane);
-
-    RECT sRect;
-    GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
-    sRect.right -= sRect.left;
-    sRect.bottom -= sRect.top;
-    const float fAspect = (float)sRect.right / (float)sRect.bottom;
-
-    p_mOut = aiMatrix4x4(
-        s / fAspect, 0.0f, 0.0f, 0.0f,
-        0.0f, s, 0.0f, 0.0f,
-        0.0f, 0.0f, Q, 1.0f,
-        0.0f, 0.0f, -Q * fNearPlane, 0.0f);
-    return 1;
-}
-
-
-//-------------------------------------------------------------------------------
-//-------------------------------------------------------------------------------
-aiVector3D GetCameraMatrix (aiMatrix4x4& p_mOut)
-{
-    D3DXMATRIX view;
-    D3DXMatrixIdentity( &view );
-
-    D3DXVec3Normalize( (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vLookAt );
-    D3DXVec3Cross( (D3DXVECTOR3*)&g_sCamera.vRight, (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vLookAt );
-    D3DXVec3Normalize( (D3DXVECTOR3*)&g_sCamera.vRight, (D3DXVECTOR3*)&g_sCamera.vRight );
-    D3DXVec3Cross( (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vRight );
-    D3DXVec3Normalize( (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vUp );
-
-    view._11 = g_sCamera.vRight.x;
-    view._12 = g_sCamera.vUp.x;
-    view._13 = g_sCamera.vLookAt.x;
-    view._14 = 0.0f;
-
-    view._21 = g_sCamera.vRight.y;
-    view._22 = g_sCamera.vUp.y;
-    view._23 = g_sCamera.vLookAt.y;
-    view._24 = 0.0f;
-
-    view._31 = g_sCamera.vRight.z;
-    view._32 = g_sCamera.vUp.z;
-    view._33 = g_sCamera.vLookAt.z;
-    view._34 = 0.0f;
-
-    view._41 = -D3DXVec3Dot( (D3DXVECTOR3*)&g_sCamera.vPos, (D3DXVECTOR3*)&g_sCamera.vRight );
-    view._42 = -D3DXVec3Dot( (D3DXVECTOR3*)&g_sCamera.vPos, (D3DXVECTOR3*)&g_sCamera.vUp );
-    view._43 = -D3DXVec3Dot( (D3DXVECTOR3*)&g_sCamera.vPos, (D3DXVECTOR3*)&g_sCamera.vLookAt );
-    view._44 =  1.0f;
-
-    memcpy(&p_mOut,&view,sizeof(aiMatrix4x4));
-
-    return g_sCamera.vPos;
-}
-
-}
+/*
+---------------------------------------------------------------------------
+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.
+---------------------------------------------------------------------------
+*/
+
+
+#include "assimp_view.h"
+#include <map>
+
+using namespace std;
+
+namespace AssimpView {
+
+extern std::string g_szNormalsShader;
+extern std::string g_szDefaultShader;
+extern std::string g_szPassThroughShader;
+
+//-------------------------------------------------------------------------------
+HINSTANCE g_hInstance				= NULL;
+HWND g_hDlg							= NULL;
+IDirect3D9* g_piD3D					= NULL;
+IDirect3DDevice9* g_piDevice		= NULL;
+IDirect3DVertexDeclaration9* gDefaultVertexDecl = NULL;
+double g_fFPS						= 0.0f;
+char g_szFileName[MAX_PATH];
+ID3DXEffect* g_piDefaultEffect		= NULL;
+ID3DXEffect* g_piNormalsEffect		= NULL;
+ID3DXEffect* g_piPassThroughEffect	= NULL;
+ID3DXEffect* g_piPatternEffect		= NULL;
+bool g_bMousePressed				= false;
+bool g_bMousePressedR				= false;
+bool g_bMousePressedM				= false;
+bool g_bMousePressedBoth			= false;
+float g_fElpasedTime				= 0.0f;
+D3DCAPS9 g_sCaps;
+bool g_bLoadingFinished				= false;
+HANDLE g_hThreadHandle				= NULL;
+float g_fWheelPos					= -10.0f;
+bool g_bLoadingCanceled				= false;
+IDirect3DTexture9* g_pcTexture		= NULL;
+bool g_bPlay						= false;
+double g_dCurrent = 0.;
+
+// default pp steps
+unsigned int ppsteps = aiProcess_CalcTangentSpace | // calculate tangents and bitangents if possible
+        aiProcess_JoinIdenticalVertices    | // join identical vertices/ optimize indexing
+        aiProcess_ValidateDataStructure    | // perform a full validation of the loader's output
+        aiProcess_ImproveCacheLocality     | // improve the cache locality of the output vertices
+        aiProcess_RemoveRedundantMaterials | // remove redundant materials
+        aiProcess_FindDegenerates          | // remove degenerated polygons from the import
+        aiProcess_FindInvalidData          | // detect invalid model data, such as invalid normal vectors
+        aiProcess_GenUVCoords              | // convert spherical, cylindrical, box and planar mapping to proper UVs
+        aiProcess_TransformUVCoords        | // preprocess UV transformations (scaling, translation ...)
+        aiProcess_FindInstances            | // search for instanced meshes and remove them by references to one master
+        aiProcess_LimitBoneWeights         | // limit bone weights to 4 per vertex
+        aiProcess_OptimizeMeshes		   | // join small meshes, if possible;
+        aiProcess_SplitByBoneCount         | // split meshes with too many bones. Necessary for our (limited) hardware skinning shader
+        0;
+
+unsigned int ppstepsdefault = ppsteps;
+
+bool nopointslines = false;
+
+extern bool g_bWasFlipped			/*= false*/;
+
+aiMatrix4x4 g_mWorld;
+aiMatrix4x4 g_mWorldRotate;
+aiVector3D g_vRotateSpeed			= aiVector3D(0.5f,0.5f,0.5f);
+
+// NOTE: The second light direction is now computed from the first
+aiVector3D g_avLightDirs[1] = 
+{	aiVector3D(-0.5f,0.6f,0.2f)  };
+
+D3DCOLOR g_avLightColors[3] = 
+{
+    D3DCOLOR_ARGB(0xFF,0xFF,0xFF,0xFF),
+    D3DCOLOR_ARGB(0xFF,0xFF,0x00,0x00),
+    D3DCOLOR_ARGB(0xFF,0x05,0x05,0x05),
+};
+
+POINT g_mousePos;
+POINT g_LastmousePos;
+bool g_bFPSView						= false;
+bool g_bInvert						= false;
+EClickPos g_eClick					= EClickPos_Circle;
+unsigned int g_iCurrentColor		= 0;
+
+float g_fLightIntensity				= 1.0f;
+float g_fLightColor					= 1.0f;
+
+RenderOptions g_sOptions;
+Camera g_sCamera;
+AssetHelper *g_pcAsset				= NULL;
+
+//
+// Contains the mask image for the HUD 
+// (used to determine the position of a click)
+//
+unsigned char* g_szImageMask		= NULL;
+
+float g_fLoadTime = 0.0f;
+
+
+//-------------------------------------------------------------------------------
+// Entry point for the loader thread
+// The laoder thread loads the asset while the progress dialog displays the
+// smart progress bar
+//-------------------------------------------------------------------------------
+DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
+{
+    UNREFERENCED_PARAMETER(lpParameter);
+
+    // get current time
+    double fCur = (double)timeGetTime();
+
+    aiPropertyStore* props = aiCreatePropertyStore();
+    aiSetImportPropertyInteger(props,AI_CONFIG_IMPORT_TER_MAKE_UVS,1);
+    aiSetImportPropertyFloat(props,AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,g_smoothAngle);
+    aiSetImportPropertyInteger(props,AI_CONFIG_PP_SBP_REMOVE,nopointslines ? aiPrimitiveType_LINE | aiPrimitiveType_POINT : 0 );
+
+    aiSetImportPropertyInteger(props,AI_CONFIG_GLOB_MEASURE_TIME,1);
+    //aiSetImportPropertyInteger(props,AI_CONFIG_PP_PTV_KEEP_HIERARCHY,1);
+
+    // Call ASSIMPs C-API to load the file
+    g_pcAsset->pcScene = (aiScene*)aiImportFileExWithProperties(g_szFileName,
+
+        ppsteps | /* configurable pp steps */
+        aiProcess_GenSmoothNormals		   | // generate smooth normal vectors if not existing
+        aiProcess_SplitLargeMeshes         | // split large, unrenderable meshes into submeshes
+        aiProcess_Triangulate			   | // triangulate polygons with more than 3 edges
+        aiProcess_ConvertToLeftHanded	   | // convert everything to D3D left handed space
+        aiProcess_SortByPType              | // make 'clean' meshes which consist of a single typ of primitives
+        0,
+        NULL,
+        props);
+
+    aiReleasePropertyStore(props);
+
+    // get the end time of zje operation, calculate delta t
+    double fEnd = (double)timeGetTime();
+    g_fLoadTime = (float)((fEnd - fCur) / 1000);
+//	char szTemp[128];
+    g_bLoadingFinished = true;
+
+    // check whether the loading process has failed ...
+    if (NULL == g_pcAsset->pcScene)
+    {
+        CLogDisplay::Instance().AddEntry("[ERROR] Unable to load this asset:",
+            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
+
+        // print ASSIMPs error string to the log display
+        CLogDisplay::Instance().AddEntry(aiGetErrorString(),
+            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
+        return 1;
+    }
+
+    return 0;
+}
+
+//-------------------------------------------------------------------------------
+// load the current asset
+// THe path to the asset is specified in the global path variable
+//-------------------------------------------------------------------------------
+int LoadAsset(void)
+{
+    // set the world and world rotation matrices to the identuty
+    g_mWorldRotate = aiMatrix4x4();
+    g_mWorld = aiMatrix4x4();
+
+//	char szTemp[MAX_PATH+64];
+//	sprintf(szTemp,"Starting to load %s",g_szFileName);
+    CLogWindow::Instance().WriteLine(
+        "----------------------------------------------------------------------------");
+//	CLogWindow::Instance().WriteLine(szTemp);
+//	CLogWindow::Instance().WriteLine(
+//		"----------------------------------------------------------------------------");
+    CLogWindow::Instance().SetAutoUpdate(false);
+
+    // create a helper thread to load the asset
+    DWORD dwID;
+    g_bLoadingCanceled = false;
+    g_pcAsset = new AssetHelper();
+    g_hThreadHandle = CreateThread(NULL,0,&LoadThreadProc,NULL,0,&dwID);
+
+    if (!g_hThreadHandle)
+    {
+        CLogDisplay::Instance().AddEntry(
+            "[ERROR] Unable to create helper thread for loading",
+            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
+        return 0;
+    }
+
+    // show the progress bar dialog
+    DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_LOADDIALOG),
+        g_hDlg,&ProgressMessageProc);
+
+    // update the log window
+    CLogWindow::Instance().SetAutoUpdate(true);
+    CLogWindow::Instance().Update();
+
+    // now we should have loaded the asset. Check this ...
+    g_bLoadingFinished = false;
+    if (!g_pcAsset || !g_pcAsset->pcScene)
+    {
+        if (g_pcAsset)
+        {
+            delete g_pcAsset;
+            g_pcAsset = NULL;
+        }
+        return 0;
+    }
+
+    // allocate a new MeshHelper array and build a new instance
+    // for each mesh in the original asset
+    g_pcAsset->apcMeshes = new AssetHelper::MeshHelper*[g_pcAsset->pcScene->mNumMeshes]();
+    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
+        g_pcAsset->apcMeshes[i] = new AssetHelper::MeshHelper();
+
+
+    // create animator
+    g_pcAsset->mAnimator = new SceneAnimator( g_pcAsset->pcScene);
+
+    // build a new caption string for the viewer
+    char szOut[MAX_PATH + 10];
+    sprintf(szOut,AI_VIEW_CAPTION_BASE " [%s]",g_szFileName);
+    SetWindowText(g_hDlg,szOut);
+
+    // scale the asset vertices to fit into the viewer window
+    ScaleAsset();
+
+    // reset the camera view to the default position
+    g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
+    g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
+    g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
+    g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
+
+    // build native D3D vertex/index buffers, textures, materials
+    if( 1 != CreateAssetData())
+        return 0;
+
+    if (!g_pcAsset->pcScene->HasAnimations()) {
+        EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),FALSE);
+        EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),FALSE);
+    }
+    else {
+        EnableWindow(GetDlgItem(g_hDlg,IDC_PLAY),TRUE);
+        EnableWindow(GetDlgItem(g_hDlg,IDC_SLIDERANIM),TRUE);
+    }
+
+    CLogDisplay::Instance().AddEntry("[OK] The asset has been loaded successfully");
+    CDisplay::Instance().FillDisplayList();
+    CDisplay::Instance().FillAnimList();
+
+    CDisplay::Instance().FillDefaultStatistics();
+    
+    // render the scene once
+    CDisplay::Instance().OnRender();
+
+    g_pcAsset->iNormalSet = AssetHelper::ORIGINAL;
+    g_bWasFlipped = false;
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+// Delete the loaded asset
+// The function does nothing is no asset is loaded
+//-------------------------------------------------------------------------------
+int DeleteAsset(void)
+{
+    if (!g_pcAsset)return 0;
+
+    // don't anymore know why this was necessary ...
+    CDisplay::Instance().OnRender();
+
+    // delete everything
+    DeleteAssetData();
+    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
+    {
+        delete g_pcAsset->apcMeshes[i];
+    }
+    aiReleaseImport(g_pcAsset->pcScene);
+    delete[] g_pcAsset->apcMeshes;
+    delete g_pcAsset->mAnimator;
+    delete g_pcAsset;
+    g_pcAsset = NULL;
+
+    // reset the caption of the viewer window
+    SetWindowText(g_hDlg,AI_VIEW_CAPTION_BASE);
+
+    // clear UI
+    CDisplay::Instance().ClearAnimList();
+    CDisplay::Instance().ClearDisplayList();
+
+    CMaterialManager::Instance().Reset();
+    UpdateWindow(g_hDlg);
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+// Calculate the boundaries of a given node and all of its children
+// The boundaries are in Worldspace (AABB)
+// piNode Input node
+// p_avOut Receives the min/max boundaries. Must point to 2 vec3s
+// piMatrix Transformation matrix of the graph at this position
+//-------------------------------------------------------------------------------
+int CalculateBounds(aiNode* piNode, aiVector3D* p_avOut, 
+    const aiMatrix4x4& piMatrix)
+{
+    ai_assert(NULL != piNode);
+    ai_assert(NULL != p_avOut);
+
+    aiMatrix4x4 mTemp = piNode->mTransformation;
+    mTemp.Transpose();
+    aiMatrix4x4 aiMe = mTemp * piMatrix;
+
+    for (unsigned int i = 0; i < piNode->mNumMeshes;++i)
+    {
+        for( unsigned int a = 0; a < g_pcAsset->pcScene->mMeshes[
+            piNode->mMeshes[i]]->mNumVertices;++a)
+        {
+            aiVector3D pc =g_pcAsset->pcScene->mMeshes[piNode->mMeshes[i]]->mVertices[a];
+
+            aiVector3D pc1;
+            D3DXVec3TransformCoord((D3DXVECTOR3*)&pc1,(D3DXVECTOR3*)&pc,
+                (D3DXMATRIX*)&aiMe);
+
+            p_avOut[0].x = min( p_avOut[0].x, pc1.x);
+            p_avOut[0].y = min( p_avOut[0].y, pc1.y);
+            p_avOut[0].z = min( p_avOut[0].z, pc1.z);
+            p_avOut[1].x = max( p_avOut[1].x, pc1.x);
+            p_avOut[1].y = max( p_avOut[1].y, pc1.y);
+            p_avOut[1].z = max( p_avOut[1].z, pc1.z);
+        }
+    }
+    for (unsigned int i = 0; i < piNode->mNumChildren;++i)
+    {
+        CalculateBounds( piNode->mChildren[i], p_avOut, aiMe );
+    }
+    return 1;
+}
+//-------------------------------------------------------------------------------
+// Scale the asset that it fits perfectly into the viewer window
+// The function calculates the boundaries of the mesh and modifies the
+// global world transformation matrix according to the aset AABB
+//-------------------------------------------------------------------------------
+int ScaleAsset(void)
+{
+    aiVector3D aiVecs[2] = {aiVector3D( 1e10f, 1e10f, 1e10f),
+        aiVector3D( -1e10f, -1e10f, -1e10f) };
+
+    if (g_pcAsset->pcScene->mRootNode)
+    {
+        aiMatrix4x4 m;
+        CalculateBounds(g_pcAsset->pcScene->mRootNode,aiVecs,m);
+    }
+
+    aiVector3D vDelta = aiVecs[1]-aiVecs[0];
+    aiVector3D vHalf =  aiVecs[0] + (vDelta / 2.0f);
+    float fScale = 10.0f / vDelta.Length();
+
+    g_mWorld =  aiMatrix4x4(
+        1.0f,0.0f,0.0f,0.0f,
+        0.0f,1.0f,0.0f,0.0f,
+        0.0f,0.0f,1.0f,0.0f,
+        -vHalf.x,-vHalf.y,-vHalf.z,1.0f) *
+        aiMatrix4x4(
+        fScale,0.0f,0.0f,0.0f,
+        0.0f,fScale,0.0f,0.0f,
+        0.0f,0.0f,fScale,0.0f,
+        0.0f,0.0f,0.0f,1.0f);
+    return 1;
+}
+
+//-------------------------------------------------------------------------------
+// Generate a vertex buffer which holds the normals of the asset as
+// a list of unconnected lines
+// pcMesh Input mesh
+// pcSource Source mesh from ASSIMP
+//-------------------------------------------------------------------------------
+int GenerateNormalsAsLineList(AssetHelper::MeshHelper* pcMesh,const aiMesh* pcSource)
+{
+    ai_assert(NULL != pcMesh);
+    ai_assert(NULL != pcSource);
+
+    if (!pcSource->mNormals)return 0;
+
+    // create vertex buffer
+    if(FAILED( g_piDevice->CreateVertexBuffer(sizeof(AssetHelper::LineVertex) *
+        pcSource->mNumVertices * 2,
+        D3DUSAGE_WRITEONLY,
+        AssetHelper::LineVertex::GetFVF(),
+        D3DPOOL_DEFAULT, &pcMesh->piVBNormals,NULL)))
+    {
+        CLogDisplay::Instance().AddEntry("Failed to create vertex buffer for the normal list",
+            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
+        return 2;
+    }
+
+    // now fill the vertex buffer with data
+    AssetHelper::LineVertex* pbData2;
+    pcMesh->piVBNormals->Lock(0,0,(void**)&pbData2,0);
+    for (unsigned int x = 0; x < pcSource->mNumVertices;++x)
+    {
+        pbData2->vPosition = pcSource->mVertices[x];
+
+        ++pbData2;
+
+        aiVector3D vNormal = pcSource->mNormals[x];
+        vNormal.Normalize();
+
+        // scalo with the inverse of the world scaling to make sure
+        // the normals have equal length in each case
+        // TODO: Check whether this works in every case, I don't think so
+        vNormal.x /= g_mWorld.a1*4;
+        vNormal.y /= g_mWorld.b2*4;
+        vNormal.z /= g_mWorld.c3*4;
+
+        pbData2->vPosition = pcSource->mVertices[x] + vNormal;
+
+        ++pbData2;
+    }
+    pcMesh->piVBNormals->Unlock();
+    return 1;
+}
+
+//-------------------------------------------------------------------------------
+// Create the native D3D representation of the asset: vertex buffers,
+// index buffers, materials ...
+//-------------------------------------------------------------------------------
+int CreateAssetData()
+{
+    if (!g_pcAsset)return 0;
+
+    // reset all subsystems
+    CMaterialManager::Instance().Reset();
+    CDisplay::Instance().Reset();
+
+    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
+    {
+        const aiMesh* mesh = g_pcAsset->pcScene->mMeshes[i];
+
+        // create the material for the mesh
+        if (!g_pcAsset->apcMeshes[i]->piEffect)	{
+            CMaterialManager::Instance().CreateMaterial(
+                g_pcAsset->apcMeshes[i],mesh);
+        }
+
+        // create vertex buffer
+        if(FAILED( g_piDevice->CreateVertexBuffer(sizeof(AssetHelper::Vertex) *
+            mesh->mNumVertices,
+            D3DUSAGE_WRITEONLY,
+            0,
+            D3DPOOL_DEFAULT, &g_pcAsset->apcMeshes[i]->piVB,NULL)))	{
+            MessageBox(g_hDlg,"Failed to create vertex buffer",
+                "ASSIMP Viewer Utility",MB_OK);
+            return 2;
+        }
+
+        DWORD dwUsage = 0;
+        if (g_pcAsset->apcMeshes[i]->piOpacityTexture || 1.0f != g_pcAsset->apcMeshes[i]->fOpacity)
+            dwUsage |= D3DUSAGE_DYNAMIC;
+
+        unsigned int nidx;
+        switch (mesh->mPrimitiveTypes) {
+            case aiPrimitiveType_POINT:
+                nidx = 1;break;
+            case aiPrimitiveType_LINE:
+                nidx = 2;break;
+            case aiPrimitiveType_TRIANGLE:
+                nidx = 3;break;
+            default: ai_assert(false);
+        };
+
+        // check whether we can use 16 bit indices
+        if (mesh->mNumFaces * 3 >= 65536)	{
+            // create 32 bit index buffer
+            if(FAILED( g_piDevice->CreateIndexBuffer( 4 *
+                mesh->mNumFaces * nidx,
+                D3DUSAGE_WRITEONLY | dwUsage,
+                D3DFMT_INDEX32,
+                D3DPOOL_DEFAULT, 
+                &g_pcAsset->apcMeshes[i]->piIB,
+                NULL)))
+            {
+                MessageBox(g_hDlg,"Failed to create 32 Bit index buffer",
+                    "ASSIMP Viewer Utility",MB_OK);
+                return 2;
+            }
+
+            // now fill the index buffer
+            unsigned int* pbData;
+            g_pcAsset->apcMeshes[i]->piIB->Lock(0,0,(void**)&pbData,0);
+            for (unsigned int x = 0; x < mesh->mNumFaces;++x)
+            {
+                for (unsigned int a = 0; a < nidx;++a)
+                {
+                    *pbData++ = mesh->mFaces[x].mIndices[a];
+                }
+            }
+        }
+        else	{
+            // create 16 bit index buffer
+            if(FAILED( g_piDevice->CreateIndexBuffer( 2 *
+                mesh->mNumFaces * nidx,
+                D3DUSAGE_WRITEONLY | dwUsage,
+                D3DFMT_INDEX16,
+                D3DPOOL_DEFAULT,
+                &g_pcAsset->apcMeshes[i]->piIB,
+                NULL)))
+            {
+                MessageBox(g_hDlg,"Failed to create 16 Bit index buffer",
+                    "ASSIMP Viewer Utility",MB_OK);
+                return 2;
+            }
+
+            // now fill the index buffer
+            uint16_t* pbData;
+            g_pcAsset->apcMeshes[i]->piIB->Lock(0,0,(void**)&pbData,0);
+            for (unsigned int x = 0; x < mesh->mNumFaces;++x)
+            {
+                for (unsigned int a = 0; a < nidx;++a)
+                {
+                    *pbData++ = (uint16_t)mesh->mFaces[x].mIndices[a];
+                }
+            }
+        }
+        g_pcAsset->apcMeshes[i]->piIB->Unlock();
+
+        // collect weights on all vertices. Quick and careless
+        std::vector<std::vector<aiVertexWeight> > weightsPerVertex( mesh->mNumVertices);
+        for( unsigned int a = 0; a < mesh->mNumBones; a++)	{
+            const aiBone* bone = mesh->mBones[a];
+            for( unsigned int b = 0; b < bone->mNumWeights; b++)
+                weightsPerVertex[bone->mWeights[b].mVertexId].push_back( aiVertexWeight( a, bone->mWeights[b].mWeight));
+        }
+
+        // now fill the vertex buffer
+        AssetHelper::Vertex* pbData2;
+        g_pcAsset->apcMeshes[i]->piVB->Lock(0,0,(void**)&pbData2,0);
+        for (unsigned int x = 0; x < mesh->mNumVertices;++x)
+        {
+            pbData2->vPosition = mesh->mVertices[x];
+
+            if (NULL == mesh->mNormals)
+                pbData2->vNormal = aiVector3D(0.0f,0.0f,0.0f);
+            else pbData2->vNormal = mesh->mNormals[x];
+
+            if (NULL == mesh->mTangents)	{
+                pbData2->vTangent = aiVector3D(0.0f,0.0f,0.0f);
+                pbData2->vBitangent = aiVector3D(0.0f,0.0f,0.0f);
+            }
+            else	{
+                pbData2->vTangent = mesh->mTangents[x];
+                pbData2->vBitangent = mesh->mBitangents[x];
+            }
+
+            if (mesh->HasVertexColors( 0))	{
+                pbData2->dColorDiffuse = D3DCOLOR_ARGB(
+                    ((unsigned char)max( min( mesh->mColors[0][x].a * 255.0f, 255.0f),0.0f)),
+                    ((unsigned char)max( min( mesh->mColors[0][x].r * 255.0f, 255.0f),0.0f)),
+                    ((unsigned char)max( min( mesh->mColors[0][x].g * 255.0f, 255.0f),0.0f)),
+                    ((unsigned char)max( min( mesh->mColors[0][x].b * 255.0f, 255.0f),0.0f)));
+            }
+            else pbData2->dColorDiffuse = D3DCOLOR_ARGB(0xFF,0xff,0xff,0xff);
+
+            // ignore a third texture coordinate component
+            if (mesh->HasTextureCoords( 0))	{
+                pbData2->vTextureUV = aiVector2D(
+                    mesh->mTextureCoords[0][x].x,
+                    mesh->mTextureCoords[0][x].y);
+            }
+            else pbData2->vTextureUV = aiVector2D(0.5f,0.5f);
+
+            if (mesh->HasTextureCoords( 1))	{
+                pbData2->vTextureUV2 = aiVector2D(
+                    mesh->mTextureCoords[1][x].x,
+                    mesh->mTextureCoords[1][x].y);
+            }
+            else pbData2->vTextureUV2 = aiVector2D(0.5f,0.5f);
+
+            // Bone indices and weights
+            if( mesh->HasBones())	{
+                unsigned char boneIndices[4] = { 0, 0, 0, 0 };
+                unsigned char boneWeights[4] = { 0, 0, 0, 0 };
+                ai_assert( weightsPerVertex[x].size() <= 4);
+                for( unsigned int a = 0; a < weightsPerVertex[x].size(); a++)
+                {
+                    boneIndices[a] = weightsPerVertex[x][a].mVertexId;
+                    boneWeights[a] = (unsigned char) (weightsPerVertex[x][a].mWeight * 255.0f);
+                }
+
+                memcpy( pbData2->mBoneIndices, boneIndices, sizeof( boneIndices));
+                memcpy( pbData2->mBoneWeights, boneWeights, sizeof( boneWeights));
+            } else
+            {
+                memset( pbData2->mBoneIndices, 0, sizeof( pbData2->mBoneIndices));
+                memset( pbData2->mBoneWeights, 0, sizeof( pbData2->mBoneWeights));
+            }
+
+            ++pbData2;
+        }
+        g_pcAsset->apcMeshes[i]->piVB->Unlock();
+
+        // now generate the second vertex buffer, holding all normals
+        if (!g_pcAsset->apcMeshes[i]->piVBNormals)	{
+            GenerateNormalsAsLineList(g_pcAsset->apcMeshes[i],mesh);
+        }
+    }
+    return 1;
+}
+
+//-------------------------------------------------------------------------------
+// Delete all effects, textures, vertex buffers ... associated with
+// an asset
+//-------------------------------------------------------------------------------
+int DeleteAssetData(bool bNoMaterials)
+{
+    if (!g_pcAsset)return 0;
+
+    // TODO: Move this to a proper destructor
+    for (unsigned int i = 0; i < g_pcAsset->pcScene->mNumMeshes;++i)
+    {
+        if(g_pcAsset->apcMeshes[i]->piVB)
+        {
+            g_pcAsset->apcMeshes[i]->piVB->Release();
+            g_pcAsset->apcMeshes[i]->piVB = NULL;
+        }
+        if(g_pcAsset->apcMeshes[i]->piVBNormals)
+        {
+            g_pcAsset->apcMeshes[i]->piVBNormals->Release();
+            g_pcAsset->apcMeshes[i]->piVBNormals = NULL;
+        }
+        if(g_pcAsset->apcMeshes[i]->piIB)
+        {
+            g_pcAsset->apcMeshes[i]->piIB->Release();
+            g_pcAsset->apcMeshes[i]->piIB = NULL;
+        }
+
+        // TODO ... unfixed memory leak
+        // delete storage eventually allocated to hold a copy
+        // of the original vertex normals
+        //if (g_pcAsset->apcMeshes[i]->pvOriginalNormals)
+        //{
+        //	delete[] g_pcAsset->apcMeshes[i]->pvOriginalNormals;
+        //}
+
+        if (!bNoMaterials)
+        {
+            if(g_pcAsset->apcMeshes[i]->piEffect)
+            {
+                g_pcAsset->apcMeshes[i]->piEffect->Release();
+                g_pcAsset->apcMeshes[i]->piEffect = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piDiffuseTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piDiffuseTexture->Release();
+                g_pcAsset->apcMeshes[i]->piDiffuseTexture = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piNormalTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piNormalTexture->Release();
+                g_pcAsset->apcMeshes[i]->piNormalTexture = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piSpecularTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piSpecularTexture->Release();
+                g_pcAsset->apcMeshes[i]->piSpecularTexture = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piAmbientTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piAmbientTexture->Release();
+                g_pcAsset->apcMeshes[i]->piAmbientTexture = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piEmissiveTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piEmissiveTexture->Release();
+                g_pcAsset->apcMeshes[i]->piEmissiveTexture = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piOpacityTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piOpacityTexture->Release();
+                g_pcAsset->apcMeshes[i]->piOpacityTexture = NULL;
+            }
+            if(g_pcAsset->apcMeshes[i]->piShininessTexture)
+            {
+                g_pcAsset->apcMeshes[i]->piShininessTexture->Release();
+                g_pcAsset->apcMeshes[i]->piShininessTexture = NULL;
+            }
+        }
+    }
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+// Switch beetween zoom/rotate view and the standatd FPS view
+// g_bFPSView specifies the view mode to setup
+//-------------------------------------------------------------------------------
+int SetupFPSView()
+{
+    if (!g_bFPSView)
+    {
+        g_sCamera.vPos = aiVector3D(0.0f,0.0f,g_fWheelPos);
+        g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
+        g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
+        g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
+    }
+    else
+    {
+        g_fWheelPos = g_sCamera.vPos.z;
+        g_sCamera.vPos = aiVector3D(0.0f,0.0f,-10.0f);
+        g_sCamera.vLookAt = aiVector3D(0.0f,0.0f,1.0f);
+        g_sCamera.vUp = aiVector3D(0.0f,1.0f,0.0f);
+        g_sCamera.vRight = aiVector3D(0.0f,1.0f,0.0f);
+    }
+    return 1;
+}
+
+//-------------------------------------------------------------------------------
+// Initialize the IDIrect3D interface
+// Called by the WinMain
+//-------------------------------------------------------------------------------
+int InitD3D(void)
+{
+    if (NULL == g_piD3D)
+    {
+        g_piD3D = Direct3DCreate9(D3D_SDK_VERSION);
+        if (NULL == g_piD3D)return 0;
+    }
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+// Release the IDirect3D interface.
+// NOTE: Assumes that the device has already been deleted
+//-------------------------------------------------------------------------------
+int ShutdownD3D(void)
+{
+    ShutdownDevice();
+    if (NULL != g_piD3D)
+    {
+        g_piD3D->Release();
+        g_piD3D = NULL;
+    }
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+// Shutdown the D3D devie object and all resources associated with it
+// NOTE: Assumes that the asset has already been deleted
+//-------------------------------------------------------------------------------
+int ShutdownDevice(void)
+{
+    // release other subsystems
+    CBackgroundPainter::Instance().ReleaseNativeResource();
+    CLogDisplay::Instance().ReleaseNativeResource();
+
+    // release global shaders that have been allocazed
+    if (NULL != g_piDefaultEffect)
+    {
+        g_piDefaultEffect->Release();
+        g_piDefaultEffect = NULL;
+    }
+    if (NULL != g_piNormalsEffect)
+    {
+        g_piNormalsEffect->Release();
+        g_piNormalsEffect = NULL;
+    }
+    if (NULL != g_piPassThroughEffect)
+    {
+        g_piPassThroughEffect->Release();
+        g_piPassThroughEffect = NULL;
+    }
+    if (NULL != g_piPatternEffect)
+    {
+        g_piPatternEffect->Release();
+        g_piPatternEffect = NULL;
+    }
+    if (NULL != g_pcTexture)
+    {
+        g_pcTexture->Release();
+        g_pcTexture = NULL;
+    }
+
+    if( NULL != gDefaultVertexDecl)
+    {
+        gDefaultVertexDecl->Release();
+        gDefaultVertexDecl = NULL;
+    }
+
+    // delete the main D3D device object
+    if (NULL != g_piDevice)
+    {
+        g_piDevice->Release();
+        g_piDevice = NULL;
+    }
+
+    // deleted the one channel image allocated to hold the HUD mask
+    delete[] g_szImageMask;
+    g_szImageMask = NULL;
+
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+int CreateHUDTexture()
+{
+    // lock the memory resource ourselves
+    HRSRC res = FindResource(NULL,MAKEINTRESOURCE(IDR_HUD),RT_RCDATA);
+    HGLOBAL hg = LoadResource(NULL,res);
+    void* pData = LockResource(hg);
+
+    if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_piDevice,
+        pData,SizeofResource(NULL,res),
+        D3DX_DEFAULT_NONPOW2,
+        D3DX_DEFAULT_NONPOW2,
+        1,
+        0,
+        D3DFMT_A8R8G8B8,
+        D3DPOOL_MANAGED,
+        D3DX_DEFAULT,
+        D3DX_DEFAULT,
+        0,
+        NULL,
+        NULL,
+        &g_pcTexture)))
+    {
+        CLogDisplay::Instance().AddEntry("[ERROR] Unable to load HUD texture",
+            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
+
+        g_pcTexture  = NULL;
+        g_szImageMask = NULL;
+
+        FreeResource(hg);
+        return 0;
+    }
+
+    FreeResource(hg);
+
+    D3DSURFACE_DESC sDesc;
+    g_pcTexture->GetLevelDesc(0,&sDesc);
+
+
+    // lock the memory resource ourselves
+    res = FindResource(NULL,MAKEINTRESOURCE(IDR_HUDMASK),RT_RCDATA);
+    hg = LoadResource(NULL,res);
+    pData = LockResource(hg);
+
+    IDirect3DTexture9* pcTex;
+    if(FAILED(D3DXCreateTextureFromFileInMemoryEx(g_piDevice,
+        pData,SizeofResource(NULL,res),
+        sDesc.Width,
+        sDesc.Height,
+        1,
+        0,
+        D3DFMT_L8,
+        D3DPOOL_MANAGED, // unnecessary
+        D3DX_DEFAULT,
+        D3DX_DEFAULT,
+        0,
+        NULL,
+        NULL,
+        &pcTex)))
+    {
+        CLogDisplay::Instance().AddEntry("[ERROR] Unable to load HUD mask texture",
+            D3DCOLOR_ARGB(0xFF,0xFF,0,0));
+        g_szImageMask = NULL;
+
+        FreeResource(hg);
+        return 0;
+    }
+
+    FreeResource(hg);
+
+    // lock the texture and copy it to get a pointer
+    D3DLOCKED_RECT sRect;
+    pcTex->LockRect(0,&sRect,NULL,D3DLOCK_READONLY);
+
+    unsigned char* szOut = new unsigned char[sDesc.Width * sDesc.Height];
+    unsigned char* _szOut = szOut;
+
+    unsigned char* szCur = (unsigned char*) sRect.pBits;
+    for (unsigned int y = 0; y < sDesc.Height;++y)
+    {
+        memcpy(_szOut,szCur,sDesc.Width);
+
+        szCur += sRect.Pitch;
+        _szOut += sDesc.Width;
+    }
+    pcTex->UnlockRect(0);
+    pcTex->Release();
+
+    g_szImageMask = szOut;
+    return 1;
+}
+
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+int CreateDevice (bool p_bMultiSample,bool p_bSuperSample,bool bHW /*= true*/)
+{
+    D3DDEVTYPE eType = bHW ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF;
+
+    // get the client rectangle of the window.
+    RECT sRect;
+    GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
+    sRect.right -= sRect.left;
+    sRect.bottom -= sRect.top;
+
+    D3DPRESENT_PARAMETERS sParams;
+    memset(&sParams,0,sizeof(D3DPRESENT_PARAMETERS));
+
+    // get the current display mode
+    D3DDISPLAYMODE sMode;
+    g_piD3D->GetAdapterDisplayMode(0,&sMode);
+
+    // fill the presentation parameter structure
+    sParams.Windowed				= TRUE;
+    sParams.hDeviceWindow			= GetDlgItem( g_hDlg, IDC_RT );
+    sParams.EnableAutoDepthStencil	= TRUE;
+    sParams.PresentationInterval	= D3DPRESENT_INTERVAL_ONE;
+    sParams.BackBufferWidth			= (UINT)sRect.right;
+    sParams.BackBufferHeight		= (UINT)sRect.bottom;
+    sParams.SwapEffect				= D3DSWAPEFFECT_DISCARD;
+    sParams.BackBufferCount			= 1;
+
+    // check whether we can use a D32 depth buffer format
+    if (SUCCEEDED ( g_piD3D->CheckDepthStencilMatch(0,eType,
+        D3DFMT_X8R8G8B8,D3DFMT_X8R8G8B8,D3DFMT_D32)))
+    {
+        sParams.AutoDepthStencilFormat = D3DFMT_D32;
+    }
+    else sParams.AutoDepthStencilFormat = D3DFMT_D24X8;
+
+    // find the highest multisample type available on this device
+    D3DMULTISAMPLE_TYPE sMS = D3DMULTISAMPLE_2_SAMPLES;
+    D3DMULTISAMPLE_TYPE sMSOut = D3DMULTISAMPLE_NONE;
+    DWORD dwQuality = 0;
+    if (p_bMultiSample)
+    {
+        while ((D3DMULTISAMPLE_TYPE)(D3DMULTISAMPLE_16_SAMPLES + 1)  != 
+            (sMS = (D3DMULTISAMPLE_TYPE)(sMS + 1)))
+        {
+            if(SUCCEEDED( g_piD3D->CheckDeviceMultiSampleType(0,eType,
+                sMode.Format,TRUE,sMS,&dwQuality)))
+            {
+                sMSOut = sMS;
+            }
+        }
+        if (0 != dwQuality)dwQuality -= 1;
+
+
+        sParams.MultiSampleQuality = dwQuality;
+        sParams.MultiSampleType = sMSOut;
+    }
+
+    // preget the device capabilities. If the hardware vertex shader is too old, we prefer software vertex processing
+    g_piD3D->GetDeviceCaps( 0, D3DDEVTYPE_HAL, &g_sCaps);
+    DWORD creationFlags = D3DCREATE_MULTITHREADED;
+    if( g_sCaps.VertexShaderVersion >= D3DVS_VERSION( 2, 0))
+        creationFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
+    else
+        creationFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+
+    // create the D3D9 device object. with software-vertexprocessing if VS2.0 isn`t supported in hardware
+    if(FAILED(g_piD3D->CreateDevice(0,eType, g_hDlg, creationFlags ,&sParams,&g_piDevice)))
+    {
+        // if hardware fails use software rendering instead
+        if (bHW)return CreateDevice(p_bMultiSample,p_bSuperSample,false);
+        return 0;
+    }
+
+    // create a vertex declaration to match the vertex
+    D3DVERTEXELEMENT9* vdecl = AssetHelper::Vertex::GetDeclarationElements();
+    if( FAILED( g_piDevice->CreateVertexDeclaration( vdecl, &gDefaultVertexDecl)))
+    {
+        MessageBox( g_hDlg, "Failed to create vertex declaration", "Init", MB_OK);
+        return 0;
+    }
+    g_piDevice->SetVertexDeclaration( gDefaultVertexDecl);
+
+    // get the capabilities of the device object
+    g_piDevice->GetDeviceCaps(&g_sCaps);
+    if(g_sCaps.PixelShaderVersion < D3DPS_VERSION(3,0))
+    {
+        EnableWindow(GetDlgItem(g_hDlg,IDC_LOWQUALITY),FALSE);
+    }
+
+    // compile the default material shader (gray gouraud/phong)
+    ID3DXBuffer* piBuffer = NULL;
+    if(FAILED( D3DXCreateEffect(g_piDevice,
+        g_szDefaultShader.c_str(),
+        (UINT)g_szDefaultShader.length(),
+        NULL,
+        NULL,
+        AI_SHADER_COMPILE_FLAGS,
+        NULL,
+        &g_piDefaultEffect,&piBuffer)))
+    {
+        if( piBuffer) 
+        {
+            MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
+            piBuffer->Release();
+        }
+        return 0;
+    }
+    if( piBuffer) 
+    {
+        piBuffer->Release();
+        piBuffer = NULL;
+    }
+
+    // use Fixed Function effect when working with shaderless cards
+    if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
+        g_piDefaultEffect->SetTechnique( "DefaultFXSpecular_FF");
+
+    // create the shader used to draw the HUD
+    if(FAILED( D3DXCreateEffect(g_piDevice,
+        g_szPassThroughShader.c_str(),(UINT)g_szPassThroughShader.length(),
+        NULL,NULL,AI_SHADER_COMPILE_FLAGS,NULL,&g_piPassThroughEffect,&piBuffer)))
+    {
+        if( piBuffer) 
+        {
+            MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
+            piBuffer->Release();
+        }
+        return 0;
+    }
+    if( piBuffer) 
+    {
+        piBuffer->Release();
+        piBuffer = NULL;
+    }
+
+    // use Fixed Function effect when working with shaderless cards
+    if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
+        g_piPassThroughEffect->SetTechnique( "PassThrough_FF");
+
+    // create the shader used to visualize normal vectors
+    if(FAILED( D3DXCreateEffect(g_piDevice,
+        g_szNormalsShader.c_str(),(UINT)g_szNormalsShader.length(),
+        NULL,NULL,AI_SHADER_COMPILE_FLAGS,NULL,&g_piNormalsEffect, &piBuffer)))
+    {
+        if( piBuffer) 
+        {
+            MessageBox(g_hDlg,(LPCSTR)piBuffer->GetBufferPointer(),"HLSL",MB_OK);
+            piBuffer->Release();
+        }
+        return 0;
+    }
+    if( piBuffer) 
+    {
+        piBuffer->Release();
+        piBuffer = NULL;
+    }
+
+    //MessageBox( g_hDlg, "Failed to create vertex declaration", "Init", MB_OK);
+
+    // use Fixed Function effect when working with shaderless cards
+    if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
+        g_piNormalsEffect->SetTechnique( "RenderNormals_FF");
+
+    g_piDevice->SetRenderState(D3DRS_DITHERENABLE,TRUE);
+
+    // create the texture for the HUD
+    CreateHUDTexture();
+    CBackgroundPainter::Instance().RecreateNativeResource();
+    CLogDisplay::Instance().RecreateNativeResource();
+
+    g_piPassThroughEffect->SetTexture("TEXTURE_2D",g_pcTexture);
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+int CreateDevice (void)
+{
+    return CreateDevice(g_sOptions.bMultiSample,
+        g_sOptions.bSuperSample);
+}
+
+
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+int GetProjectionMatrix (aiMatrix4x4& p_mOut)
+{
+    const float fFarPlane = 100.0f;
+    const float fNearPlane = 0.1f;
+    const float fFOV = (float)(45.0 * 0.0174532925);
+
+    const float s = 1.0f / tanf(fFOV * 0.5f);
+    const float Q = fFarPlane / (fFarPlane - fNearPlane);
+
+    RECT sRect;
+    GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
+    sRect.right -= sRect.left;
+    sRect.bottom -= sRect.top;
+    const float fAspect = (float)sRect.right / (float)sRect.bottom;
+
+    p_mOut = aiMatrix4x4(
+        s / fAspect, 0.0f, 0.0f, 0.0f,
+        0.0f, s, 0.0f, 0.0f,
+        0.0f, 0.0f, Q, 1.0f,
+        0.0f, 0.0f, -Q * fNearPlane, 0.0f);
+    return 1;
+}
+
+
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+aiVector3D GetCameraMatrix (aiMatrix4x4& p_mOut)
+{
+    D3DXMATRIX view;
+    D3DXMatrixIdentity( &view );
+
+    D3DXVec3Normalize( (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vLookAt );
+    D3DXVec3Cross( (D3DXVECTOR3*)&g_sCamera.vRight, (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vLookAt );
+    D3DXVec3Normalize( (D3DXVECTOR3*)&g_sCamera.vRight, (D3DXVECTOR3*)&g_sCamera.vRight );
+    D3DXVec3Cross( (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vLookAt, (D3DXVECTOR3*)&g_sCamera.vRight );
+    D3DXVec3Normalize( (D3DXVECTOR3*)&g_sCamera.vUp, (D3DXVECTOR3*)&g_sCamera.vUp );
+
+    view._11 = g_sCamera.vRight.x;
+    view._12 = g_sCamera.vUp.x;
+    view._13 = g_sCamera.vLookAt.x;
+    view._14 = 0.0f;
+
+    view._21 = g_sCamera.vRight.y;
+    view._22 = g_sCamera.vUp.y;
+    view._23 = g_sCamera.vLookAt.y;
+    view._24 = 0.0f;
+
+    view._31 = g_sCamera.vRight.z;
+    view._32 = g_sCamera.vUp.z;
+    view._33 = g_sCamera.vLookAt.z;
+    view._34 = 0.0f;
+
+    view._41 = -D3DXVec3Dot( (D3DXVECTOR3*)&g_sCamera.vPos, (D3DXVECTOR3*)&g_sCamera.vRight );
+    view._42 = -D3DXVec3Dot( (D3DXVECTOR3*)&g_sCamera.vPos, (D3DXVECTOR3*)&g_sCamera.vUp );
+    view._43 = -D3DXVec3Dot( (D3DXVECTOR3*)&g_sCamera.vPos, (D3DXVECTOR3*)&g_sCamera.vLookAt );
+    view._44 =  1.0f;
+
+    memcpy(&p_mOut,&view,sizeof(aiMatrix4x4));
+
+    return g_sCamera.vPos;
+}
+
+}

+ 497 - 497
tools/assimp_view/assimp_view.rc

@@ -1,497 +1,497 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.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
-
-/////////////////////////////////////////////////////////////////////////////
-// German (Germany) 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"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_ABOUTBOX DIALOGEX 22, 17, 283, 149
-STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU
-CAPTION "About Open Asset Import Library"
-FONT 9, "Courier New", 400, 0, 0x0
-BEGIN
-    LTEXT           "Open Asset Import Library (Assimp)",IDC_STATIC,30,14,144,9
-    LTEXT           "A free C/C++ library to read various well-known 3D model formats into a straightforward in-memory format for easy processing by applications. Licensed under a 3-clause BSD license and totally awesome.",IDC_STATIC,31,34,204,24
-    LTEXT           "(c) 2008-2009. Assimp Development Team. See the CREDITS file for a list of all contributors.",IDC_STATIC,30,65,204,23
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,27,282,1
-    LTEXT           "http://assimp.sourceforge.net  http://www.zfx.info",IDC_STATIC,31,101,127,22
-    DEFPUSHBUTTON   "Love this library",IDOK,186,110,84,14
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,148,283,1
-    CONTROL         130,IDC_STATIC,"Static",SS_BITMAP,0,129,514,20
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,10,281,1
-END
-
-#define X_GROUP1 7
-#define W_GROUP1 6+160+6
-#define X_GROUP2 X_GROUP1+W_GROUP1+7
-#define W_GROUP2 6+150+8
-#define X_GROUP3 X_GROUP2+W_GROUP2+7
-#define W_GROUP3 6+60+35+8
-
-#define W X_GROUP3+W_GROUP3+47
-#define H 450
-
-#define Y_PANEL H-12-82-7-7-14-4
-#define Y_GROUPS Y_PANEL+14+7
-
-#define TREE_W 143
-#define COMBO_W 100
-
-IDD_DIALOGMAIN DIALOGEX 0, 0, W+TREE_W, H
-STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 
-EXSTYLE WS_EX_ACCEPTFILES | WS_EX_WINDOWEDGE
-CAPTION "Open Asset Import Library - Model Viewer "
-MENU IDR_MENU1
-FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
-BEGIN
-
-    CONTROL         "",IDC_RT,"Static",SS_OWNERDRAW,0,0,W,Y_PANEL
-    CONTROL         "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS|TVS_HASLINES|TVS_SHOWSELALWAYS|WS_BORDER|WS_HSCROLL|WS_TABSTOP, W,0,TREE_W,H
-
-#define Y Y_PANEL+4
-    CONTROL         "<<",IDC_BLUBB,"Button",BS_AUTOCHECKBOX|BS_PUSHLIKE|WS_TABSTOP, W-7-35,Y,35,14
-    COMBOBOX        IDC_COMBO1, W-7-35-4-100,Y,100,14, CBS_DROPDOWN|WS_VSCROLL|WS_TABSTOP
-    PUSHBUTTON      "Play",IDC_PLAY, W-7-35-4-100-35-4,Y,35,14
-    CONTROL         "",IDC_SLIDERANIM,"msctls_trackbar32",TBS_AUTOTICKS|TBS_BOTH|TBS_NOTICKS|WS_TABSTOP, 0,Y,W-7-35-4-100-35-4,15
-
-#undef Y
-#define Y Y_GROUPS+12
-#define X X_GROUP1+6
-
-    GROUPBOX        "Display",IDC_STATIC,	X_GROUP1,Y_GROUPS,W_GROUP1,12+82+7
-
-    CONTROL         "Multisampling [M]",IDC_TOGGLEMS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y,80,10
-    CONTROL         "Wireframe [W]",IDC_TOGGLEWIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+12,80,10
-    CONTROL         "No materials [D]",IDC_TOGGLEMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+24,80,10
-    CONTROL         "Display normals [N]",IDC_TOGGLENORMALS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,	X,Y+36,80,10
-    CONTROL         "Low quality [P]",IDC_LOWQUALITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+48,80,10
-    CONTROL         "No specular [S]",IDC_NOSPECULAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+60,80,10
-    CONTROL         "Show skeleton [K]",IDC_SHOWSKELETON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+72,80,10
-
-    CONTROL         "AutoRotate [A]",IDC_AUTOROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y,80,10
-    CONTROL         "Zoom/Rotate [Z]",IDC_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,			X+80,Y+12,80,10
-    CONTROL         "Rotate lights [R]",IDC_LIGHTROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y+24,80,10
-    CONTROL         "Two lights [L]",IDC_3LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,			X+80,Y+36,80,10
-    CONTROL         "Backface culling [C]",IDC_BFCULL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y+48,80,10
-    CONTROL         "No transparency [T]",IDC_NOAB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y+60,80,10
-
-#undef X
-#define X X_GROUP2+6
-
-    GROUPBOX        "Statistics",IDC_STATIC,	X_GROUP2,Y_GROUPS,W_GROUP2,12+36+8+7
-
-    LTEXT           "Vertices:",IDC_NUMVERTS,	X,Y,35,8
-    LTEXT           "Nodes:",IDC_NUMNODES,	X,Y+12,35,8
-    LTEXT           "Shaders:",IDC_NUMSHADERS,	X,Y+24,35,8
-    LTEXT           "Time:",IDC_LOADTIME,	X,Y+36,35,8
-
-    EDITTEXT        IDC_EVERT,			X+35,Y,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-    EDITTEXT        IDC_ENODEWND,		X+35,Y+12,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-    EDITTEXT        IDC_ESHADER,		X+35,Y+24,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-    EDITTEXT        IDC_ELOAD,			X+35,Y+36,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-
-    LTEXT           "Faces:",IDC_NUMFACES,	X+80,Y,35,8
-    LTEXT           "Materials:",IDC_NUMMATS,	X+80,Y+12,35,8
-    LTEXT           "Meshes:",IDC_NUMMESHES,	X+80,Y+24,35,8
-    LTEXT           "FPS:",IDC_FPS,		X+80,Y+36,35,8
-
-    EDITTEXT        IDC_EFACE,			X+115,Y,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-    EDITTEXT        IDC_EMAT,			X+115,Y+12,35,8,	ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-    EDITTEXT        IDC_EMESH,			X+115,Y+24,35,8,	ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-    EDITTEXT        IDC_EFPS,			X+115,Y+36,35,8,	ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
-
-    EDITTEXT        IDC_VIEWMATRIX,		X,Y+48+7,72,44,		ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_VISIBLE
-
-#undef X
-#define X X_GROUP3+6
-
-    GROUPBOX        "Colors",IDC_STATIC,	X_GROUP3,Y_GROUPS,W_GROUP3,12+54+14+7
-
-    LTEXT           "Primary:",IDC_STATIC,	X,Y+3,48,8
-    LTEXT           "Secondary:",IDC_STATIC,	X,Y+3+18,54,8
-    LTEXT           "Ambient:",IDC_STATIC,	X,Y+3+36,54,8
-
-    CONTROL         "Button1",IDC_LCOLOR1,"Button",BS_OWNERDRAW | WS_TABSTOP,	X+60,Y,35,14
-    CONTROL         "Button1",IDC_LCOLOR2,"Button",BS_OWNERDRAW | WS_TABSTOP,	X+60,Y+18,35,14
-    CONTROL         "Button1",IDC_LCOLOR3,"Button",BS_OWNERDRAW | WS_TABSTOP,	X+60,Y+36,35,14
-    PUSHBUTTON      "Reset",IDC_LRESET,						X+60,Y+54,35,14
-END
-
-IDD_LOADDIALOG DIALOGEX 0, 0, 143, 60
-STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_BORDER | WS_SYSMENU
-FONT 12, "Tahoma", 400, 0, 0x0
-BEGIN
-    DEFPUSHBUTTON   "Cancel",IDOK,104,41,33,13
-    CONTROL         "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,6,30,130,8
-    LTEXT           "Loading ...\nMay the force be with you ...",IDC_STATIC,8,9,123,16
-END
-
-IDD_AVHELP DIALOGEX 0, 0, 481, 346
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "ASSIMP Viewer: Help"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
-    DEFPUSHBUTTON   "OK",IDOK,420,324,50,14
-    CONTROL         "",IDC_RICHEDIT21,"RichEdit20A",ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_TABSTOP,19,18,462,294
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,312,490,1
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,16,490,1
-END
-
-IDD_LOGVIEW DIALOGEX 0, 0, 365, 182
-STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
-EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
-CAPTION "AssimpView Log Output"
-FONT 8, "Courier New", 400, 0, 0x0
-BEGIN
-    CONTROL         "",IDC_EDIT1,"RichEdit20A",ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_NUMBER | WS_VSCROLL | WS_TABSTOP,3,4,358,174,WS_EX_STATICEDGE
-END
-
-IDD_DIALOGSMOOTH DIALOGEX 0, 0, 278, 141
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Set smooth limit "
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
-    DEFPUSHBUTTON   "OK",IDOK,213,94,50,14
-    PUSHBUTTON      "Cancel",IDCANCEL,161,94,50,14
-    EDITTEXT        IDC_EDITSM,99,7,175,14,ES_AUTOHSCROLL | ES_NUMBER
-    LTEXT           "Angle limit (in degrees):",IDC_STATIC,13,10,76,8
-    LTEXT           "The angle limit defines the maximum angle that may be between two adjacent face normals that they're smoothed together.",IDC_STATIC,13,31,253,19
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,113,278,1
-    LTEXT           "This setting is also used during import, but it can be overriden by single model importers to match the original look of a model as closely as possible. Examples include 3DS, ASE and LWO, all of them relying on smoothing groups and their own angle limits. ",IDC_STATIC,13,51,254,33
-    LTEXT           "NOTE: New settings don't take effect immediately, use 'Smooth Normals' or 'Reload' to update the model.",IDC_STATIC,14,118,254,22
-    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,90,277,1
-END
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE 
-BEGIN
-    "resource.h\0"
-END
-
-2 TEXTINCLUDE 
-BEGIN
-    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
-    "#include ""windows.h""\r\n"
-    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
-    "\0"
-END
-
-3 TEXTINCLUDE 
-BEGIN
-    "\r\n"
-    "\0"
-END
-
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,1,700,0
- PRODUCTVERSION 1,1,700,1
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x0L
- FILESUBTYPE 0x0L
-BEGIN
-    BLOCK "StringFileInfo"
-    BEGIN
-        BLOCK "040704b0"
-        BEGIN
-            VALUE "CompanyName", "assimp team"
-            VALUE "FileDescription", "ASSIMP Viewer Application"
-            VALUE "FileVersion", "1, 1, SVNRevision, 0"
-            VALUE "InternalName", "assimp_view"
-            VALUE "LegalCopyright", "Licensed under the LGPL"
-            VALUE "OriginalFilename", "assimpview32.exe"
-            VALUE "ProductName", "ASSIMP Viewer Application"
-            VALUE "ProductVersion", "1, 1, SVNRevision, 0"
-        END
-    END
-    BLOCK "VarFileInfo"
-    BEGIN
-        VALUE "Translation", 0x407, 1200
-    END
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO 
-BEGIN
-    IDD_ABOUTBOX, DIALOG
-    BEGIN
-        TOPMARGIN, 1
-        BOTTOMMARGIN, 138
-    END
-
-    IDD_DIALOGMAIN, DIALOG
-    BEGIN
-        RIGHTMARGIN, 623
-        BOTTOMMARGIN, 484
-    END
-
-    IDD_LOADDIALOG, DIALOG
-    BEGIN
-        LEFTMARGIN, 7
-        TOPMARGIN, 7
-    END
-
-    IDD_AVHELP, DIALOG
-    BEGIN
-        LEFTMARGIN, 7
-        RIGHTMARGIN, 474
-        TOPMARGIN, 7
-        BOTTOMMARGIN, 339
-    END
-
-    IDD_LOGVIEW, DIALOG
-    BEGIN
-        LEFTMARGIN, 7
-        RIGHTMARGIN, 358
-        TOPMARGIN, 14
-        BOTTOMMARGIN, 175
-    END
-
-    IDD_DIALOGSMOOTH, DIALOG
-    BEGIN
-        LEFTMARGIN, 7
-        RIGHTMARGIN, 271
-        TOPMARGIN, 7
-        BOTTOMMARGIN, 134
-    END
-END
-#endif    // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Bitmap
-//
-
-IDB_BITMAP1             BITMAP                  "banner.bmp"
-IDB_BANIM               BITMAP                  "base_anim.bmp"
-IDB_BDISPLAY            BITMAP                  "base_display.bmp"
-IDB_BINTER              BITMAP                  "base_inter.bmp"
-IDB_BRENDERING          BITMAP                  "base_rendering.bmp"
-IDB_BSTATS              BITMAP                  "base_stats.bmp"
-IDB_BTX                 BITMAP                  "tx.bmp"
-IDB_BFX                 BITMAP                  "fx.bmp"
-IDB_BNODE               BITMAP                  "n.bmp"
-IDB_BROOT               BITMAP                  "root.bmp"
-IDB_BTXI                BITMAP                  "txi.bmp"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Menu
-//
-
-IDR_MENU1 MENU 
-BEGIN
-    POPUP "Viewer"
-    BEGIN
-        MENUITEM "Open Asset",                  ID_VIEWER_OPEN
-        MENUITEM "Close Asset",                 ID_VIEWER_CLOSEASSET
-        MENUITEM "Reload",                      ID_VIEWER_RELOAD
-        POPUP "Import settings"
-        BEGIN
-            MENUITEM "Calculate Tangent Space",     ID_VIEWER_PP_CTS
-            MENUITEM "Compute Indexed Meshes",      ID_VIEWER_PP_JIV
-            MENUITEM "Optimize Materials",          ID_VIEWER_PP_RRM2
-            MENUITEM "Optimize Meshes",             ID_VIEWER_PP_OM
-            MENUITEM "Optimize Scenegraph",         ID_VIEWER_PP_OG
-            MENUITEM "Find Instanced Meshes",       ID_VIEWER_PP_FIM
-            MENUITEM "Run Full Validation",         ID_VIEWER_PP_VDS
-            MENUITEM "Pretransform Vertices",       ID_VIEWER_PP_PTV
-            MENUITEM "VCache Optimization",         ID_VIEWER_PP_ICL
-            MENUITEM "Fix Infacing Normals",        ID_VIEWER_PP_FIN
-            MENUITEM "Find Degenerates",            ID_VIEWER_PP_FD
-            MENUITEM "Find Invalid Data",           ID_VIEWER_PP_FID
-            MENUITEM "Generate UV Coords",          ID_VIEWER_PP_GUV
-            MENUITEM "Transform UV Coords",         ID_VIEWER_PP_TUV
-            MENUITEM "Remove Lines and Points",     ID_VIEWER_PP_RLINE_PNT, GRAYED
-            MENUITEM "Remove dummy bones (De-bone)", ID_VIEWER_PP_DB
-            MENUITEM SEPARATOR
-            MENUITEM "(required) Triangulate",      ID_VIEWER_PP_JIV, GRAYED
-            MENUITEM "(required) Limit Bone Weights", ID_VIEWER_PP_JIV, GRAYED
-            MENUITEM "(required) Split Large Meshes", ID_VIEWER_PP_JIV, GRAYED
-            MENUITEM "(required) Sort by primitive type", ID_VIEWER_PP_JIV, GRAYED
-            MENUITEM "(required) Convert to Left-Handed", ID_VIEWER_PP_JIV, GRAYED
-            MENUITEM SEPARATOR
-            MENUITEM "Reset to default",            ID_IMPORTSETTINGS_RESETTODEFAULT
-            MENUITEM "Open Post-Process Short Reference", ID_IMPORTSETTINGS_OPENPOST
-        END
-        MENUITEM SEPARATOR
-        MENUITEM "Save Screenshot",             ID_VIEWER_SAVESCREENSHOTTOFILE
-        MENUITEM "Reset view",                  ID_VIEWER_RESETVIEW
-        MENUITEM "Memory consumption",          ID_VIEWER_MEMORYCONSUMATION
-        MENUITEM SEPARATOR
-        MENUITEM "Setup file associations",     ID_VIEWER_H
-        MENUITEM SEPARATOR
-        MENUITEM "Recent files ",               ID_VIEWER_RECENTFILES
-        MENUITEM "Clear history",               ID_VIEWER_CLEARHISTORY
-        MENUITEM SEPARATOR
-        MENUITEM "Quit",                        ID_VIEWER_QUIT
-    END
-    POPUP "Tools"
-    BEGIN
-        MENUITEM "Log window",                  ID_TOOLS_LOGWINDOW
-        MENUITEM "Save log to file",            ID_TOOLS_SAVELOGTOFILE
-        MENUITEM "Clear log",                   ID_TOOLS_CLEARLOG
-        MENUITEM SEPARATOR
-        MENUITEM "Original normals",            ID_TOOLS_ORIGINALNORMALS, CHECKED
-        MENUITEM "Hard normals",                ID_TOOLS_HARDNORMALS
-        MENUITEM "Smooth normals",              ID_TOOLS_SMOOTHNORMALS
-        MENUITEM SEPARATOR
-        MENUITEM "Set angle limit ...",         ID_TOOLS_SETANGLELIMIT
-        MENUITEM "Flip normals",                ID_TOOLS_FLIPNORMALS
-        MENUITEM SEPARATOR
-        MENUITEM "Stereo view",                 ID_TOOLS_STEREOVIEW
-    END
-    POPUP "Background"
-    BEGIN
-        MENUITEM "Set color",                   ID_BACKGROUND_SETCOLOR
-        MENUITEM "Load skybox",                 ID_BACKGROUND_LOADSKYBOX
-        MENUITEM "Load texture",                ID_BACKGROUND_LOADTEXTURE
-        MENUITEM SEPARATOR
-        MENUITEM "Clear",                       ID_BACKGROUND_CLEAR
-    END
-    MENUITEM "Export",                      32878
-    POPUP "?"
-    BEGIN
-        POPUP "Feedback"
-        BEGIN
-            MENUITEM "Report bug",                  ID_REPORTBUG
-            MENUITEM "Feature request/discuss",     ID_FR
-        END
-        MENUITEM "Help",                        ID__HELP
-        MENUITEM SEPARATOR
-        MENUITEM "About",                       ID__ABOUT
-        MENUITEM SEPARATOR
-        MENUITEM "Website",                     ID__WEBSITE
-        MENUITEM "SF.net Project Page",         ID__WEBSITESF
-    END
-END
-
-IDR_TXPOPUP MENU 
-BEGIN
-    POPUP "Hey"
-    BEGIN
-        MENUITEM "Replace texture",             ID_HEY_REPLACE
-        MENUITEM "Export texture",              ID_HEY_EXPORT
-        MENUITEM "Remove texture",              ID_HEY_REMOVE
-        MENUITEM SEPARATOR
-        MENUITEM "Reset texture",               ID_HEY_RESETTEXTURE
-    END
-    MENUITEM "This is not an easter egg",   0
-END
-
-IDR_MATPOPUP MENU 
-BEGIN
-    POPUP "So long"
-    BEGIN
-        MENUITEM "Add diffuse texture",         ID_SOLONG_ADDDIFFUSETEXTURE
-        MENUITEM "Add specular texture",        ID_SOLONG_ADDSPECULARTEXTURE
-        MENUITEM "Add ambient texture",         ID_SOLONG_ADDAMBIENTTEXTURE
-        MENUITEM "Add emissive texture",        ID_SOLONG_ADDEMISSIVETEXTURE
-        MENUITEM "Add opacity texture",         ID_SOLONG_ADDOPACITYTEXTURE
-        MENUITEM "Add normal/height texture",   ID_SOLONG_ADDNORMAL
-        MENUITEM "Add shininess texture",       ID_SOLONG_ADDSHININESSTEXTURE
-        MENUITEM SEPARATOR
-        MENUITEM "Set diffuse color",           ID_SOLONG_CLEARDIFFUSECOLOR
-        MENUITEM "Set specular color",          ID_SOLONG_CLEARSPECULARCOLOR
-        MENUITEM "Set ambient color",           ID_SOLONG_CLEARAMBIENTCOLOR
-        MENUITEM "Set emissive color",          ID_SOLONG_CLEAREMISSIVECOLOR
-        MENUITEM "Set transparency",            ID_SOLONG_CLEARTRANSPARENCY
-        MENUITEM SEPARATOR
-        MENUITEM "Make default material",       ID_SOLONG_MAKEDEFAULTMATERIAL
-        POPUP "Set shading mode"
-        BEGIN
-            MENUITEM "Gouraud",                     ID_SETSHADINGMODE_GOURAUD
-            MENUITEM "Phong (specular)",            ID_SETSHADINGMODE_PHONG
-        END
-    END
-    MENUITEM "and thanks for all the fish", 0
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXT
-//
-
-IDR_TEXT1               TEXT                    "text1.bin"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// RCDATA
-//
-
-IDR_HUD                 RCDATA                  "HUD.png"
-IDR_HUDMASK             RCDATA                  "HUDMask.png"
-#endif    // German (Germany) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif    // not APSTUDIO_INVOKED
-
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.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
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) 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"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 22, 17, 283, 149
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU
+CAPTION "About Open Asset Import Library"
+FONT 9, "Courier New", 400, 0, 0x0
+BEGIN
+    LTEXT           "Open Asset Import Library (Assimp)",IDC_STATIC,30,14,144,9
+    LTEXT           "A free C/C++ library to read various well-known 3D model formats into a straightforward in-memory format for easy processing by applications. Licensed under a 3-clause BSD license and totally awesome.",IDC_STATIC,31,34,204,24
+    LTEXT           "(c) 2008-2009. Assimp Development Team. See the CREDITS file for a list of all contributors.",IDC_STATIC,30,65,204,23
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,27,282,1
+    LTEXT           "http://assimp.sourceforge.net  http://www.zfx.info",IDC_STATIC,31,101,127,22
+    DEFPUSHBUTTON   "Love this library",IDOK,186,110,84,14
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,148,283,1
+    CONTROL         130,IDC_STATIC,"Static",SS_BITMAP,0,129,514,20
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,10,281,1
+END
+
+#define X_GROUP1 7
+#define W_GROUP1 6+160+6
+#define X_GROUP2 X_GROUP1+W_GROUP1+7
+#define W_GROUP2 6+150+8
+#define X_GROUP3 X_GROUP2+W_GROUP2+7
+#define W_GROUP3 6+60+35+8
+
+#define W X_GROUP3+W_GROUP3+47
+#define H 450
+
+#define Y_PANEL H-12-82-7-7-14-4
+#define Y_GROUPS Y_PANEL+14+7
+
+#define TREE_W 143
+#define COMBO_W 100
+
+IDD_DIALOGMAIN DIALOGEX 0, 0, W+TREE_W, H
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU 
+EXSTYLE WS_EX_ACCEPTFILES | WS_EX_WINDOWEDGE
+CAPTION "Open Asset Import Library - Model Viewer "
+MENU IDR_MENU1
+FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+
+    CONTROL         "",IDC_RT,"Static",SS_OWNERDRAW,0,0,W,Y_PANEL
+    CONTROL         "",IDC_TREE1,"SysTreeView32",TVS_HASBUTTONS|TVS_HASLINES|TVS_SHOWSELALWAYS|WS_BORDER|WS_HSCROLL|WS_TABSTOP, W,0,TREE_W,H
+
+#define Y Y_PANEL+4
+    CONTROL         "<<",IDC_BLUBB,"Button",BS_AUTOCHECKBOX|BS_PUSHLIKE|WS_TABSTOP, W-7-35,Y,35,14
+    COMBOBOX        IDC_COMBO1, W-7-35-4-100,Y,100,14, CBS_DROPDOWN|WS_VSCROLL|WS_TABSTOP
+    PUSHBUTTON      "Play",IDC_PLAY, W-7-35-4-100-35-4,Y,35,14
+    CONTROL         "",IDC_SLIDERANIM,"msctls_trackbar32",TBS_AUTOTICKS|TBS_BOTH|TBS_NOTICKS|WS_TABSTOP, 0,Y,W-7-35-4-100-35-4,15
+
+#undef Y
+#define Y Y_GROUPS+12
+#define X X_GROUP1+6
+
+    GROUPBOX        "Display",IDC_STATIC,	X_GROUP1,Y_GROUPS,W_GROUP1,12+82+7
+
+    CONTROL         "Multisampling [M]",IDC_TOGGLEMS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y,80,10
+    CONTROL         "Wireframe [W]",IDC_TOGGLEWIRE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+12,80,10
+    CONTROL         "No materials [D]",IDC_TOGGLEMAT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+24,80,10
+    CONTROL         "Display normals [N]",IDC_TOGGLENORMALS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,	X,Y+36,80,10
+    CONTROL         "Low quality [P]",IDC_LOWQUALITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+48,80,10
+    CONTROL         "No specular [S]",IDC_NOSPECULAR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+60,80,10
+    CONTROL         "Show skeleton [K]",IDC_SHOWSKELETON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X,Y+72,80,10
+
+    CONTROL         "AutoRotate [A]",IDC_AUTOROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y,80,10
+    CONTROL         "Zoom/Rotate [Z]",IDC_ZOOM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,			X+80,Y+12,80,10
+    CONTROL         "Rotate lights [R]",IDC_LIGHTROTATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y+24,80,10
+    CONTROL         "Two lights [L]",IDC_3LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,			X+80,Y+36,80,10
+    CONTROL         "Backface culling [C]",IDC_BFCULL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y+48,80,10
+    CONTROL         "No transparency [T]",IDC_NOAB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,		X+80,Y+60,80,10
+
+#undef X
+#define X X_GROUP2+6
+
+    GROUPBOX        "Statistics",IDC_STATIC,	X_GROUP2,Y_GROUPS,W_GROUP2,12+36+8+7
+
+    LTEXT           "Vertices:",IDC_NUMVERTS,	X,Y,35,8
+    LTEXT           "Nodes:",IDC_NUMNODES,	X,Y+12,35,8
+    LTEXT           "Shaders:",IDC_NUMSHADERS,	X,Y+24,35,8
+    LTEXT           "Time:",IDC_LOADTIME,	X,Y+36,35,8
+
+    EDITTEXT        IDC_EVERT,			X+35,Y,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+    EDITTEXT        IDC_ENODEWND,		X+35,Y+12,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+    EDITTEXT        IDC_ESHADER,		X+35,Y+24,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+    EDITTEXT        IDC_ELOAD,			X+35,Y+36,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+
+    LTEXT           "Faces:",IDC_NUMFACES,	X+80,Y,35,8
+    LTEXT           "Materials:",IDC_NUMMATS,	X+80,Y+12,35,8
+    LTEXT           "Meshes:",IDC_NUMMESHES,	X+80,Y+24,35,8
+    LTEXT           "FPS:",IDC_FPS,		X+80,Y+36,35,8
+
+    EDITTEXT        IDC_EFACE,			X+115,Y,35,8,		ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+    EDITTEXT        IDC_EMAT,			X+115,Y+12,35,8,	ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+    EDITTEXT        IDC_EMESH,			X+115,Y+24,35,8,	ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+    EDITTEXT        IDC_EFPS,			X+115,Y+36,35,8,	ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | ES_RIGHT
+
+    EDITTEXT        IDC_VIEWMATRIX,		X,Y+48+7,72,44,		ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_VISIBLE
+
+#undef X
+#define X X_GROUP3+6
+
+    GROUPBOX        "Colors",IDC_STATIC,	X_GROUP3,Y_GROUPS,W_GROUP3,12+54+14+7
+
+    LTEXT           "Primary:",IDC_STATIC,	X,Y+3,48,8
+    LTEXT           "Secondary:",IDC_STATIC,	X,Y+3+18,54,8
+    LTEXT           "Ambient:",IDC_STATIC,	X,Y+3+36,54,8
+
+    CONTROL         "Button1",IDC_LCOLOR1,"Button",BS_OWNERDRAW | WS_TABSTOP,	X+60,Y,35,14
+    CONTROL         "Button1",IDC_LCOLOR2,"Button",BS_OWNERDRAW | WS_TABSTOP,	X+60,Y+18,35,14
+    CONTROL         "Button1",IDC_LCOLOR3,"Button",BS_OWNERDRAW | WS_TABSTOP,	X+60,Y+36,35,14
+    PUSHBUTTON      "Reset",IDC_LRESET,						X+60,Y+54,35,14
+END
+
+IDD_LOADDIALOG DIALOGEX 0, 0, 143, 60
+STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_BORDER | WS_SYSMENU
+FONT 12, "Tahoma", 400, 0, 0x0
+BEGIN
+    DEFPUSHBUTTON   "Cancel",IDOK,104,41,33,13
+    CONTROL         "",IDC_PROGRESS,"msctls_progress32",WS_BORDER,6,30,130,8
+    LTEXT           "Loading ...\nMay the force be with you ...",IDC_STATIC,8,9,123,16
+END
+
+IDD_AVHELP DIALOGEX 0, 0, 481, 346
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "ASSIMP Viewer: Help"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,420,324,50,14
+    CONTROL         "",IDC_RICHEDIT21,"RichEdit20A",ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL | WS_TABSTOP,19,18,462,294
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,312,490,1
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,16,490,1
+END
+
+IDD_LOGVIEW DIALOGEX 0, 0, 365, 182
+STYLE DS_SETFONT | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_TOPMOST | WS_EX_WINDOWEDGE
+CAPTION "AssimpView Log Output"
+FONT 8, "Courier New", 400, 0, 0x0
+BEGIN
+    CONTROL         "",IDC_EDIT1,"RichEdit20A",ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_NUMBER | WS_VSCROLL | WS_TABSTOP,3,4,358,174,WS_EX_STATICEDGE
+END
+
+IDD_DIALOGSMOOTH DIALOGEX 0, 0, 278, 141
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Set smooth limit "
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,213,94,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,161,94,50,14
+    EDITTEXT        IDC_EDITSM,99,7,175,14,ES_AUTOHSCROLL | ES_NUMBER
+    LTEXT           "Angle limit (in degrees):",IDC_STATIC,13,10,76,8
+    LTEXT           "The angle limit defines the maximum angle that may be between two adjacent face normals that they're smoothed together.",IDC_STATIC,13,31,253,19
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,113,278,1
+    LTEXT           "This setting is also used during import, but it can be overriden by single model importers to match the original look of a model as closely as possible. Examples include 3DS, ASE and LWO, all of them relying on smoothing groups and their own angle limits. ",IDC_STATIC,13,51,254,33
+    LTEXT           "NOTE: New settings don't take effect immediately, use 'Smooth Normals' or 'Reload' to update the model.",IDC_STATIC,14,118,254,22
+    CONTROL         "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,90,277,1
+END
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "#include ""windows.h""\r\n"
+    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,1,700,0
+ PRODUCTVERSION 1,1,700,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x0L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040704b0"
+        BEGIN
+            VALUE "CompanyName", "assimp team"
+            VALUE "FileDescription", "ASSIMP Viewer Application"
+            VALUE "FileVersion", "1, 1, SVNRevision, 0"
+            VALUE "InternalName", "assimp_view"
+            VALUE "LegalCopyright", "Licensed under the LGPL"
+            VALUE "OriginalFilename", "assimpview32.exe"
+            VALUE "ProductName", "ASSIMP Viewer Application"
+            VALUE "ProductVersion", "1, 1, SVNRevision, 0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x407, 1200
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        TOPMARGIN, 1
+        BOTTOMMARGIN, 138
+    END
+
+    IDD_DIALOGMAIN, DIALOG
+    BEGIN
+        RIGHTMARGIN, 623
+        BOTTOMMARGIN, 484
+    END
+
+    IDD_LOADDIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        TOPMARGIN, 7
+    END
+
+    IDD_AVHELP, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 474
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 339
+    END
+
+    IDD_LOGVIEW, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 358
+        TOPMARGIN, 14
+        BOTTOMMARGIN, 175
+    END
+
+    IDD_DIALOGSMOOTH, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 271
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 134
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BITMAP1             BITMAP                  "banner.bmp"
+IDB_BANIM               BITMAP                  "base_anim.bmp"
+IDB_BDISPLAY            BITMAP                  "base_display.bmp"
+IDB_BINTER              BITMAP                  "base_inter.bmp"
+IDB_BRENDERING          BITMAP                  "base_rendering.bmp"
+IDB_BSTATS              BITMAP                  "base_stats.bmp"
+IDB_BTX                 BITMAP                  "tx.bmp"
+IDB_BFX                 BITMAP                  "fx.bmp"
+IDB_BNODE               BITMAP                  "n.bmp"
+IDB_BROOT               BITMAP                  "root.bmp"
+IDB_BTXI                BITMAP                  "txi.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU 
+BEGIN
+    POPUP "Viewer"
+    BEGIN
+        MENUITEM "Open Asset",                  ID_VIEWER_OPEN
+        MENUITEM "Close Asset",                 ID_VIEWER_CLOSEASSET
+        MENUITEM "Reload",                      ID_VIEWER_RELOAD
+        POPUP "Import settings"
+        BEGIN
+            MENUITEM "Calculate Tangent Space",     ID_VIEWER_PP_CTS
+            MENUITEM "Compute Indexed Meshes",      ID_VIEWER_PP_JIV
+            MENUITEM "Optimize Materials",          ID_VIEWER_PP_RRM2
+            MENUITEM "Optimize Meshes",             ID_VIEWER_PP_OM
+            MENUITEM "Optimize Scenegraph",         ID_VIEWER_PP_OG
+            MENUITEM "Find Instanced Meshes",       ID_VIEWER_PP_FIM
+            MENUITEM "Run Full Validation",         ID_VIEWER_PP_VDS
+            MENUITEM "Pretransform Vertices",       ID_VIEWER_PP_PTV
+            MENUITEM "VCache Optimization",         ID_VIEWER_PP_ICL
+            MENUITEM "Fix Infacing Normals",        ID_VIEWER_PP_FIN
+            MENUITEM "Find Degenerates",            ID_VIEWER_PP_FD
+            MENUITEM "Find Invalid Data",           ID_VIEWER_PP_FID
+            MENUITEM "Generate UV Coords",          ID_VIEWER_PP_GUV
+            MENUITEM "Transform UV Coords",         ID_VIEWER_PP_TUV
+            MENUITEM "Remove Lines and Points",     ID_VIEWER_PP_RLINE_PNT, GRAYED
+            MENUITEM "Remove dummy bones (De-bone)", ID_VIEWER_PP_DB
+            MENUITEM SEPARATOR
+            MENUITEM "(required) Triangulate",      ID_VIEWER_PP_JIV, GRAYED
+            MENUITEM "(required) Limit Bone Weights", ID_VIEWER_PP_JIV, GRAYED
+            MENUITEM "(required) Split Large Meshes", ID_VIEWER_PP_JIV, GRAYED
+            MENUITEM "(required) Sort by primitive type", ID_VIEWER_PP_JIV, GRAYED
+            MENUITEM "(required) Convert to Left-Handed", ID_VIEWER_PP_JIV, GRAYED
+            MENUITEM SEPARATOR
+            MENUITEM "Reset to default",            ID_IMPORTSETTINGS_RESETTODEFAULT
+            MENUITEM "Open Post-Process Short Reference", ID_IMPORTSETTINGS_OPENPOST
+        END
+        MENUITEM SEPARATOR
+        MENUITEM "Save Screenshot",             ID_VIEWER_SAVESCREENSHOTTOFILE
+        MENUITEM "Reset view",                  ID_VIEWER_RESETVIEW
+        MENUITEM "Memory consumption",          ID_VIEWER_MEMORYCONSUMATION
+        MENUITEM SEPARATOR
+        MENUITEM "Setup file associations",     ID_VIEWER_H
+        MENUITEM SEPARATOR
+        MENUITEM "Recent files ",               ID_VIEWER_RECENTFILES
+        MENUITEM "Clear history",               ID_VIEWER_CLEARHISTORY
+        MENUITEM SEPARATOR
+        MENUITEM "Quit",                        ID_VIEWER_QUIT
+    END
+    POPUP "Tools"
+    BEGIN
+        MENUITEM "Log window",                  ID_TOOLS_LOGWINDOW
+        MENUITEM "Save log to file",            ID_TOOLS_SAVELOGTOFILE
+        MENUITEM "Clear log",                   ID_TOOLS_CLEARLOG
+        MENUITEM SEPARATOR
+        MENUITEM "Original normals",            ID_TOOLS_ORIGINALNORMALS, CHECKED
+        MENUITEM "Hard normals",                ID_TOOLS_HARDNORMALS
+        MENUITEM "Smooth normals",              ID_TOOLS_SMOOTHNORMALS
+        MENUITEM SEPARATOR
+        MENUITEM "Set angle limit ...",         ID_TOOLS_SETANGLELIMIT
+        MENUITEM "Flip normals",                ID_TOOLS_FLIPNORMALS
+        MENUITEM SEPARATOR
+        MENUITEM "Stereo view",                 ID_TOOLS_STEREOVIEW
+    END
+    POPUP "Background"
+    BEGIN
+        MENUITEM "Set color",                   ID_BACKGROUND_SETCOLOR
+        MENUITEM "Load skybox",                 ID_BACKGROUND_LOADSKYBOX
+        MENUITEM "Load texture",                ID_BACKGROUND_LOADTEXTURE
+        MENUITEM SEPARATOR
+        MENUITEM "Clear",                       ID_BACKGROUND_CLEAR
+    END
+    MENUITEM "Export",                      32878
+    POPUP "?"
+    BEGIN
+        POPUP "Feedback"
+        BEGIN
+            MENUITEM "Report bug",                  ID_REPORTBUG
+            MENUITEM "Feature request/discuss",     ID_FR
+        END
+        MENUITEM "Help",                        ID__HELP
+        MENUITEM SEPARATOR
+        MENUITEM "About",                       ID__ABOUT
+        MENUITEM SEPARATOR
+        MENUITEM "Website",                     ID__WEBSITE
+        MENUITEM "SF.net Project Page",         ID__WEBSITESF
+    END
+END
+
+IDR_TXPOPUP MENU 
+BEGIN
+    POPUP "Hey"
+    BEGIN
+        MENUITEM "Replace texture",             ID_HEY_REPLACE
+        MENUITEM "Export texture",              ID_HEY_EXPORT
+        MENUITEM "Remove texture",              ID_HEY_REMOVE
+        MENUITEM SEPARATOR
+        MENUITEM "Reset texture",               ID_HEY_RESETTEXTURE
+    END
+    MENUITEM "This is not an easter egg",   0
+END
+
+IDR_MATPOPUP MENU 
+BEGIN
+    POPUP "So long"
+    BEGIN
+        MENUITEM "Add diffuse texture",         ID_SOLONG_ADDDIFFUSETEXTURE
+        MENUITEM "Add specular texture",        ID_SOLONG_ADDSPECULARTEXTURE
+        MENUITEM "Add ambient texture",         ID_SOLONG_ADDAMBIENTTEXTURE
+        MENUITEM "Add emissive texture",        ID_SOLONG_ADDEMISSIVETEXTURE
+        MENUITEM "Add opacity texture",         ID_SOLONG_ADDOPACITYTEXTURE
+        MENUITEM "Add normal/height texture",   ID_SOLONG_ADDNORMAL
+        MENUITEM "Add shininess texture",       ID_SOLONG_ADDSHININESSTEXTURE
+        MENUITEM SEPARATOR
+        MENUITEM "Set diffuse color",           ID_SOLONG_CLEARDIFFUSECOLOR
+        MENUITEM "Set specular color",          ID_SOLONG_CLEARSPECULARCOLOR
+        MENUITEM "Set ambient color",           ID_SOLONG_CLEARAMBIENTCOLOR
+        MENUITEM "Set emissive color",          ID_SOLONG_CLEAREMISSIVECOLOR
+        MENUITEM "Set transparency",            ID_SOLONG_CLEARTRANSPARENCY
+        MENUITEM SEPARATOR
+        MENUITEM "Make default material",       ID_SOLONG_MAKEDEFAULTMATERIAL
+        POPUP "Set shading mode"
+        BEGIN
+            MENUITEM "Gouraud",                     ID_SETSHADINGMODE_GOURAUD
+            MENUITEM "Phong (specular)",            ID_SETSHADINGMODE_PHONG
+        END
+    END
+    MENUITEM "and thanks for all the fish", 0
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXT
+//
+
+IDR_TEXT1               TEXT                    "text1.bin"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// RCDATA
+//
+
+IDR_HUD                 RCDATA                  "HUD.png"
+IDR_HUDMASK             RCDATA                  "HUDMask.png"
+#endif    // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 235 - 235
tools/assimp_view/resource.h

@@ -1,235 +1,235 @@
-//{{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
-#define IDI_SMALL                       108
-#define IDR_MAINFRAME                   128
-#define IDD_DIALOGMAIN                  129
-#define IDB_BITMAP1                     130
-#define IDR_MENU1                       131
-#define IDD_LOADDIALOG                  132
-#define IDB_BITMAP2                     134
-#define IDD_AVHELP                      135
-#define IDR_TEXT1                       138
-#define IDR_MAX                         140
-#define IDB_MAXCIRCLEMASK               141
-#define IDB_MAXCIRCLE                   142
-#define IDR_HUD                         143
-#define IDR_HUDMASK                     144
-#define IDB_BANIM                       145
-#define IDB_BITMAP4                     146
-#define IDB_BDISPLAY                    146
-#define IDB_BITMAP5                     147
-#define IDB_BINTER                      147
-#define IDB_BITMAP6                     148
-#define IDB_BRENDERING                  148
-#define IDB_BITMAP7                     149
-#define IDB_BSTATS                      149
-#define IDB_BTX                         150
-#define IDB_BITMAP8                     151
-#define IDB_BFX                         151
-#define IDB_BITMAP9                     152
-#define IDB_BNODE                       152
-#define IDB_BITMAP10                    153
-#define IDB_BROOT                       153
-#define IDD_LOGVIEW                     154
-#define IDB_BTXI                        155
-#define IDR_TXPOPUP                     156
-#define IDR_MATPOPUP                    157
-#define IDD_DIALOGSMOOTH                159
-#define SVNRevision                     700
-#define IDC_CHECK1                      1000
-#define IDC_TOGGLEMS                    1000
-#define IDC_CHECK2                      1001
-#define IDC_TOGGLEWIRE                  1001
-#define IDC_CHECK3                      1002
-#define IDC_TOGGLEMAT                   1002
-#define IDC_CHECK4                      1003
-#define IDC_TOGGLENORMALS               1003
-#define IDC_CHECK5                      1004
-#define IDC_AUTOROTATE                  1004
-#define IDC_RT                          1006
-#define IDC_NUMVERTS                    1007
-#define IDC_NUMFACES                    1008
-#define IDC_NUMMATS                     1009
-#define IDC_FPS                         1010
-#define IDC_EFPS                        1011
-#define IDC_EMAT                        1012
-#define IDC_EFACE                       1013
-#define IDC_EVERT                       1014
-#define IDC_CHECK6                      1015
-#define IDC_LIGHTROTATE                 1015
-#define IDC_3LIGHTS                     1016
-#define IDC_PROGRESS                    1016
-#define IDC_LOADTIME                    1017
-#define IDC_ELOAD                       1018
-#define IDC_CHECK7                      1019
-#define IDC_ZOOM                        1019
-#define IDC_CHECK8                      1020
-#define IDC_LOWQUALITY                  1020
-#define IDC_NUMMATS2                    1021
-#define IDC_NUMSHADERS                  1021
-#define IDC_ESHADER                     1022
-#define IDC_RICHEDIT21                  1023
-#define IDC_EMESH                       1023
-#define IDC_CHECK9                      1024
-#define IDC_NOSPECULAR                  1024
-#define IDC_PLAYANIM                    1025
-#define IDC_3LIGHTS2                    1025
-#define IDC_NOAB                        1025
-#define IDC_SPEED                       1026
-#define IDC_COMBO1                      1027
-#define IDC_PINORDER                    1028
-#define IDC_NOSPECULAR2                 1028
-#define IDC_SSPEED                      1029
-#define IDC_SANIM                       1030
-#define IDC_SANIMGB                     1031
-#define IDC_ENODE                       1031
-#define IDC_ESHADER2                    1032
-#define IDC_ETEX                        1032
-#define IDC_TREE1                       1033
-#define IDC_EDIT1                       1034
-#define IDC_BLUBB                       1037
-#define IDC_BLABLA                      1038
-#define IDC_NUMNODES                    1038
-#define IDC_LCOLOR1                     1041
-#define IDC_LCOLOR2                     1042
-#define IDC_ENODEWND                    1043
-#define IDC_LCOLOR3                     1044
-#define IDC_LRESET                      1046
-#define IDC_NUMMESHES                   1047
-#define IDC_VIEWMAT                     1048
-#define IDC_VIEWMATRIX                  1048
-#define IDC_SLIDERANIM                  1052
-#define IDC_PLAY                        1053
-#define IDC_SHOWSKELETON                1054
-#define IDC_BFCULL                      1055
-#define IDC_EDITSM                      1056
-#define ID_VIEWER_OPEN                  32771
-#define ID_VIEWER_CLOSETHIS             32772
-#define ID_VIEWER_CLOSEASSET            32773
-#define ID_VIEWER_QUIT                  32774
-#define ID__ABOUT                       32775
-#define ID__HELP                        32776
-#define ID_VIEWER_SAVESCREENSHOTTOFILE  32777
-#define ID_VIEWER_RESETVIEW             32778
-#define ID_BACKGROUND_LOADTEXTURE       32779
-#define ID_BACKGROUND_CLEAR             32780
-#define ID_BACKGROUND_SETCOLOR          32781
-#define ID_Menu                         32782
-#define ID_BACKGROUND_LOADSKYBOX        32783
-#define ID_VIEWER_H                     32784
-#define ID_TOOLS_LOGWINDOW              32785
-#define ID_TOOLS_SAVELOGTOFILE          32786
-#define ID_TOOLS_CLEARLOG               32787
-#define ID_VIEWER_RECENTFILES           32788
-#define ID_VIEWER_MEMORYCONSUMATION     32789
-#define ID_VIEWER_CLEARHISTORY          32790
-#define ID_TOOLS_ORIGINALNORMALS        32791
-#define ID_TOOLS_SMOOTHNORMALS          32792
-#define ID_TOOLS_HARDNORMALS            32793
-#define ID_TOOLS_FLIPNORMALS            32794
-#define ID__S                           32795
-#define ID__FEEDBACK                    32796
-#define ID_FEEDBACK_GH                  32797
-#define ID_FEEDBACK_FEATUREREQUEST      32798
-#define ID_FEEDBACK_DONATE              32799
-#define ID_ANIMATION_PLAYALLINORDER     32800
-#define ID_TOOLS_STEREOVIEW             32801
-#define ID_EGNEKLGEG_EGEG               32802
-#define ID_HEY_REPLACE                  32803
-#define ID_HEY_EXPORT                   32804
-#define ID_HEY_REMOVE                   32805
-#define ID_SOLONG_ADDDIFFUSETEXTURE     32806
-#define ID_SOLONG_ADDSPECULARTEXTURE    32807
-#define ID_SOLONG_ADDAMBIENTTEXTURE     32808
-#define ID_SOLONG_ADDEMISSIVETEXTURE    32809
-#define ID_SOLONG_ADDOPACITYTEXTURE     32810
-#define ID_SOLONG_ADDNORMAL             32811
-#define ID_SOLONG_ADDSHININESSTEXTURE   32812
-#define ID_SOLONG_CLEARDIFFUSECOLOR     32813
-#define ID_SOLONG_CLEARSPECULARCOLOR    32814
-#define ID_SOLONG_CLEARAMBIENTCOLOR     32815
-#define ID_SOLONG_CLEAREMISSIVECOLOR    32816
-#define ID_SOLONG_CLEARTRANSPARENCY     32817
-#define ID_SOLONG_MAKEDEFAULTMATERIAL   32818
-#define ID_HEY_RESETTEXTURE             32819
-#define ID_SOLONG_SETSHADINGMODE        32820
-#define ID_SETSHADINGMODE_GOURAUD       32821
-#define ID_SETSHADINGMODE_PHONG         32822
-#define ID_OPTIMIZE_OPTIMIZEACMR        32823
-#define ID_OPTIMIZE_OPTIMIZEOVERDRAW    32824
-#define ID_OPTIMIZE_OPTIMIZEBOTH        32825
-#define ID_VERTEXCACHELOCALITY_FINDCURRENT 32826
-#define ID_VERTEXCACHELOCALITY_OPTIMIZE 32827
-#define ID_VERTEXCACHELOCALITY_FINDBEST 32828
-#define ID_OPTIMIZE_SCENEGRAPH          32829
-#define ID_SCENEGRAPH_SMALLESTPOSSIBLEGRAPH 32830
-#define ID_SMOOTHNORMALS_5              32831
-#define ID_SMOOTHNORMALS_6              32832
-#define ID_SMOOTHNORMALS_MAXANGLE60     32833
-#define ID_SMOOTHNORMALS_MAXANGLE90     32834
-#define ID_SMOOTHNORMALS_MAXANGLE120    32835
-#define ID_SMOOTHNORMALS_NOLIMIT        32836
-#define ID_SMOOTHNORMALS_30             32837
-#define ID_SMOOTHNORMALS_40             32838
-#define ID_SMOOTHNORMALS_60             32839
-#define ID_SMOOTHNORMALS_90             32840
-#define ID_SMOOTHNORMALS_120            32841
-#define ID_Menu32842                    32842
-#define ID_SMOOTHANGLE_30               32843
-#define ID_SMOOTHANGLE_40               32844
-#define ID_SMOOTHANGLE_50               32845
-#define ID_SMOOTHANGLE_60               32846
-#define ID_SMOOTHANGLE_70               32847
-#define ID_SMOOTHANGLE_90               32848
-#define ID_SMOOTHANGLE_120              32849
-#define ID_SMOOTHANGLE_NONE             32850
-#define ID_TOOLS_SETANGLELIMIT          32851
-#define ID_VIEWER_PP_JIV                32852
-#define ID_VIEWER_PP_RRM                32852
-#define ID_VIEWER_PP_OM                 32853
-#define ID_VIEWER_PP_OG                 32854
-#define ID_VIEWER_PP_FIM                32855
-#define ID_VIEWER_PP_VDS                32856
-#define ID_VIEWER_PP_PTV                32857
-#define ID_VIEWER_PP_ICL                32858
-#define ID_VIEWER_PP_FIN                32859
-#define ID_VIEWER_PP_FD                 32860
-#define ID_VIEWER_PP_FID                32861
-#define ID_VIEWER_PP_GUV                32862
-#define ID_VIEWER_PP_TUV                32863
-#define ID_VIEWER_PP_RLINE_PNT          32864
-#define ID_REPORTBUG                    32865
-#define ID_FR                           32866
-#define ID__WEBSITE                     32867
-#define ID__SF                          32868
-#define ID__                            32869
-#define ID__WEBSITESF                   32870
-#define ID_IMPORTSETTINGS_CALCULATETANGENTSPACE 32871
-#define ID_VIEWER_CTS                   32872
-#define ID_VIEWER_PP_CTS                32873
-#define ID_VIEWER_RELOAD                32874
-#define ID_VIEWER_PP_RRM2               32875
-#define ID_IMPORTSETTINGS_RESETTODEFAULT 32876
-#define ID_IMPORTSETTINGS_OPENPOST      32877
-#define ID_EXPORT                       32878
-#define ID_IMPORTSETTINGS_REMOVEDUMMYBONES 32879
-#define ID_VIEWER_PP_DB                 32880
-#define IDC_STATIC                      -1
-
-// Next default values for new objects
-// 
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NO_MFC                     1
-#define _APS_NEXT_RESOURCE_VALUE        160
-#define _APS_NEXT_COMMAND_VALUE         32881
-#define _APS_NEXT_CONTROL_VALUE         1059
-#define _APS_NEXT_SYMED_VALUE           110
-#endif
-#endif
+//{{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
+#define IDI_SMALL                       108
+#define IDR_MAINFRAME                   128
+#define IDD_DIALOGMAIN                  129
+#define IDB_BITMAP1                     130
+#define IDR_MENU1                       131
+#define IDD_LOADDIALOG                  132
+#define IDB_BITMAP2                     134
+#define IDD_AVHELP                      135
+#define IDR_TEXT1                       138
+#define IDR_MAX                         140
+#define IDB_MAXCIRCLEMASK               141
+#define IDB_MAXCIRCLE                   142
+#define IDR_HUD                         143
+#define IDR_HUDMASK                     144
+#define IDB_BANIM                       145
+#define IDB_BITMAP4                     146
+#define IDB_BDISPLAY                    146
+#define IDB_BITMAP5                     147
+#define IDB_BINTER                      147
+#define IDB_BITMAP6                     148
+#define IDB_BRENDERING                  148
+#define IDB_BITMAP7                     149
+#define IDB_BSTATS                      149
+#define IDB_BTX                         150
+#define IDB_BITMAP8                     151
+#define IDB_BFX                         151
+#define IDB_BITMAP9                     152
+#define IDB_BNODE                       152
+#define IDB_BITMAP10                    153
+#define IDB_BROOT                       153
+#define IDD_LOGVIEW                     154
+#define IDB_BTXI                        155
+#define IDR_TXPOPUP                     156
+#define IDR_MATPOPUP                    157
+#define IDD_DIALOGSMOOTH                159
+#define SVNRevision                     700
+#define IDC_CHECK1                      1000
+#define IDC_TOGGLEMS                    1000
+#define IDC_CHECK2                      1001
+#define IDC_TOGGLEWIRE                  1001
+#define IDC_CHECK3                      1002
+#define IDC_TOGGLEMAT                   1002
+#define IDC_CHECK4                      1003
+#define IDC_TOGGLENORMALS               1003
+#define IDC_CHECK5                      1004
+#define IDC_AUTOROTATE                  1004
+#define IDC_RT                          1006
+#define IDC_NUMVERTS                    1007
+#define IDC_NUMFACES                    1008
+#define IDC_NUMMATS                     1009
+#define IDC_FPS                         1010
+#define IDC_EFPS                        1011
+#define IDC_EMAT                        1012
+#define IDC_EFACE                       1013
+#define IDC_EVERT                       1014
+#define IDC_CHECK6                      1015
+#define IDC_LIGHTROTATE                 1015
+#define IDC_3LIGHTS                     1016
+#define IDC_PROGRESS                    1016
+#define IDC_LOADTIME                    1017
+#define IDC_ELOAD                       1018
+#define IDC_CHECK7                      1019
+#define IDC_ZOOM                        1019
+#define IDC_CHECK8                      1020
+#define IDC_LOWQUALITY                  1020
+#define IDC_NUMMATS2                    1021
+#define IDC_NUMSHADERS                  1021
+#define IDC_ESHADER                     1022
+#define IDC_RICHEDIT21                  1023
+#define IDC_EMESH                       1023
+#define IDC_CHECK9                      1024
+#define IDC_NOSPECULAR                  1024
+#define IDC_PLAYANIM                    1025
+#define IDC_3LIGHTS2                    1025
+#define IDC_NOAB                        1025
+#define IDC_SPEED                       1026
+#define IDC_COMBO1                      1027
+#define IDC_PINORDER                    1028
+#define IDC_NOSPECULAR2                 1028
+#define IDC_SSPEED                      1029
+#define IDC_SANIM                       1030
+#define IDC_SANIMGB                     1031
+#define IDC_ENODE                       1031
+#define IDC_ESHADER2                    1032
+#define IDC_ETEX                        1032
+#define IDC_TREE1                       1033
+#define IDC_EDIT1                       1034
+#define IDC_BLUBB                       1037
+#define IDC_BLABLA                      1038
+#define IDC_NUMNODES                    1038
+#define IDC_LCOLOR1                     1041
+#define IDC_LCOLOR2                     1042
+#define IDC_ENODEWND                    1043
+#define IDC_LCOLOR3                     1044
+#define IDC_LRESET                      1046
+#define IDC_NUMMESHES                   1047
+#define IDC_VIEWMAT                     1048
+#define IDC_VIEWMATRIX                  1048
+#define IDC_SLIDERANIM                  1052
+#define IDC_PLAY                        1053
+#define IDC_SHOWSKELETON                1054
+#define IDC_BFCULL                      1055
+#define IDC_EDITSM                      1056
+#define ID_VIEWER_OPEN                  32771
+#define ID_VIEWER_CLOSETHIS             32772
+#define ID_VIEWER_CLOSEASSET            32773
+#define ID_VIEWER_QUIT                  32774
+#define ID__ABOUT                       32775
+#define ID__HELP                        32776
+#define ID_VIEWER_SAVESCREENSHOTTOFILE  32777
+#define ID_VIEWER_RESETVIEW             32778
+#define ID_BACKGROUND_LOADTEXTURE       32779
+#define ID_BACKGROUND_CLEAR             32780
+#define ID_BACKGROUND_SETCOLOR          32781
+#define ID_Menu                         32782
+#define ID_BACKGROUND_LOADSKYBOX        32783
+#define ID_VIEWER_H                     32784
+#define ID_TOOLS_LOGWINDOW              32785
+#define ID_TOOLS_SAVELOGTOFILE          32786
+#define ID_TOOLS_CLEARLOG               32787
+#define ID_VIEWER_RECENTFILES           32788
+#define ID_VIEWER_MEMORYCONSUMATION     32789
+#define ID_VIEWER_CLEARHISTORY          32790
+#define ID_TOOLS_ORIGINALNORMALS        32791
+#define ID_TOOLS_SMOOTHNORMALS          32792
+#define ID_TOOLS_HARDNORMALS            32793
+#define ID_TOOLS_FLIPNORMALS            32794
+#define ID__S                           32795
+#define ID__FEEDBACK                    32796
+#define ID_FEEDBACK_GH                  32797
+#define ID_FEEDBACK_FEATUREREQUEST      32798
+#define ID_FEEDBACK_DONATE              32799
+#define ID_ANIMATION_PLAYALLINORDER     32800
+#define ID_TOOLS_STEREOVIEW             32801
+#define ID_EGNEKLGEG_EGEG               32802
+#define ID_HEY_REPLACE                  32803
+#define ID_HEY_EXPORT                   32804
+#define ID_HEY_REMOVE                   32805
+#define ID_SOLONG_ADDDIFFUSETEXTURE     32806
+#define ID_SOLONG_ADDSPECULARTEXTURE    32807
+#define ID_SOLONG_ADDAMBIENTTEXTURE     32808
+#define ID_SOLONG_ADDEMISSIVETEXTURE    32809
+#define ID_SOLONG_ADDOPACITYTEXTURE     32810
+#define ID_SOLONG_ADDNORMAL             32811
+#define ID_SOLONG_ADDSHININESSTEXTURE   32812
+#define ID_SOLONG_CLEARDIFFUSECOLOR     32813
+#define ID_SOLONG_CLEARSPECULARCOLOR    32814
+#define ID_SOLONG_CLEARAMBIENTCOLOR     32815
+#define ID_SOLONG_CLEAREMISSIVECOLOR    32816
+#define ID_SOLONG_CLEARTRANSPARENCY     32817
+#define ID_SOLONG_MAKEDEFAULTMATERIAL   32818
+#define ID_HEY_RESETTEXTURE             32819
+#define ID_SOLONG_SETSHADINGMODE        32820
+#define ID_SETSHADINGMODE_GOURAUD       32821
+#define ID_SETSHADINGMODE_PHONG         32822
+#define ID_OPTIMIZE_OPTIMIZEACMR        32823
+#define ID_OPTIMIZE_OPTIMIZEOVERDRAW    32824
+#define ID_OPTIMIZE_OPTIMIZEBOTH        32825
+#define ID_VERTEXCACHELOCALITY_FINDCURRENT 32826
+#define ID_VERTEXCACHELOCALITY_OPTIMIZE 32827
+#define ID_VERTEXCACHELOCALITY_FINDBEST 32828
+#define ID_OPTIMIZE_SCENEGRAPH          32829
+#define ID_SCENEGRAPH_SMALLESTPOSSIBLEGRAPH 32830
+#define ID_SMOOTHNORMALS_5              32831
+#define ID_SMOOTHNORMALS_6              32832
+#define ID_SMOOTHNORMALS_MAXANGLE60     32833
+#define ID_SMOOTHNORMALS_MAXANGLE90     32834
+#define ID_SMOOTHNORMALS_MAXANGLE120    32835
+#define ID_SMOOTHNORMALS_NOLIMIT        32836
+#define ID_SMOOTHNORMALS_30             32837
+#define ID_SMOOTHNORMALS_40             32838
+#define ID_SMOOTHNORMALS_60             32839
+#define ID_SMOOTHNORMALS_90             32840
+#define ID_SMOOTHNORMALS_120            32841
+#define ID_Menu32842                    32842
+#define ID_SMOOTHANGLE_30               32843
+#define ID_SMOOTHANGLE_40               32844
+#define ID_SMOOTHANGLE_50               32845
+#define ID_SMOOTHANGLE_60               32846
+#define ID_SMOOTHANGLE_70               32847
+#define ID_SMOOTHANGLE_90               32848
+#define ID_SMOOTHANGLE_120              32849
+#define ID_SMOOTHANGLE_NONE             32850
+#define ID_TOOLS_SETANGLELIMIT          32851
+#define ID_VIEWER_PP_JIV                32852
+#define ID_VIEWER_PP_RRM                32852
+#define ID_VIEWER_PP_OM                 32853
+#define ID_VIEWER_PP_OG                 32854
+#define ID_VIEWER_PP_FIM                32855
+#define ID_VIEWER_PP_VDS                32856
+#define ID_VIEWER_PP_PTV                32857
+#define ID_VIEWER_PP_ICL                32858
+#define ID_VIEWER_PP_FIN                32859
+#define ID_VIEWER_PP_FD                 32860
+#define ID_VIEWER_PP_FID                32861
+#define ID_VIEWER_PP_GUV                32862
+#define ID_VIEWER_PP_TUV                32863
+#define ID_VIEWER_PP_RLINE_PNT          32864
+#define ID_REPORTBUG                    32865
+#define ID_FR                           32866
+#define ID__WEBSITE                     32867
+#define ID__SF                          32868
+#define ID__                            32869
+#define ID__WEBSITESF                   32870
+#define ID_IMPORTSETTINGS_CALCULATETANGENTSPACE 32871
+#define ID_VIEWER_CTS                   32872
+#define ID_VIEWER_PP_CTS                32873
+#define ID_VIEWER_RELOAD                32874
+#define ID_VIEWER_PP_RRM2               32875
+#define ID_IMPORTSETTINGS_RESETTODEFAULT 32876
+#define ID_IMPORTSETTINGS_OPENPOST      32877
+#define ID_EXPORT                       32878
+#define ID_IMPORTSETTINGS_REMOVEDUMMYBONES 32879
+#define ID_VIEWER_PP_DB                 32880
+#define IDC_STATIC                      -1
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC                     1
+#define _APS_NEXT_RESOURCE_VALUE        160
+#define _APS_NEXT_COMMAND_VALUE         32881
+#define _APS_NEXT_CONTROL_VALUE         1059
+#define _APS_NEXT_SYMED_VALUE           110
+#endif
+#endif

+ 8 - 8
tools/assimp_view/stdafx.cpp

@@ -1,8 +1,8 @@
-// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
-// assimp_view.pch ist der vorkompilierte Header.
-// stdafx.obj enthält die vorkompilierten Typinformationen.
-
-#include "stdafx.h"
-
-// TODO: Auf zusätzliche Header verweisen, die in STDAFX.H
-// und nicht in dieser Datei erforderlich sind.
+// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
+// assimp_view.pch ist der vorkompilierte Header.
+// stdafx.obj enthält die vorkompilierten Typinformationen.
+
+#include "stdafx.h"
+
+// TODO: Auf zusätzliche Header verweisen, die in STDAFX.H
+// und nicht in dieser Datei erforderlich sind.