Browse Source

Bug fixing in exporters

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
ecd70f961a
7 changed files with 150 additions and 147 deletions
  1. 55 94
      CMakeLists.txt
  2. 1 1
      shaders/Pps.glsl
  3. 2 0
      src/renderer/Drawer.cpp
  4. 13 3
      src/scene/ModelNode.cpp
  5. 1 1
      src/util/CMakeLists.txt
  6. 3 5
      testapp/Main.cpp
  7. 75 43
      tools/2anki/Main.cpp

+ 55 - 94
CMakeLists.txt

@@ -24,7 +24,7 @@ ENDIF()
 # Because we want different compiler flags for each platform
 # Because we want different compiler flags for each platform
 SET(ANKI_CPU "X86" CACHE STRING "The CPU arch (X86 or ARM)")
 SET(ANKI_CPU "X86" CACHE STRING "The CPU arch (X86 or ARM)")
 
 
-# Take a wild guess on CPU address space
+# Address space
 IF(${ANKI_CPU} STREQUAL "ARM")
 IF(${ANKI_CPU} STREQUAL "ARM")
 	SET(_ADDR_SPACE "32")
 	SET(_ADDR_SPACE "32")
 ELSE()
 ELSE()
@@ -32,7 +32,20 @@ ELSE()
 ENDIF()
 ENDIF()
 
 
 SET(ANKI_CPU_ADDR_SPACE "${_ADDR_SPACE}" CACHE STRING "The CPU architecture (0 or 32 or 64). If zero go native")
 SET(ANKI_CPU_ADDR_SPACE "${_ADDR_SPACE}" CACHE STRING "The CPU architecture (0 or 32 or 64). If zero go native")
+
+# SIMD
 OPTION(ANKI_ENABLE_MATH_SIMD "Enable or not math SIMD optimizations" ON)
 OPTION(ANKI_ENABLE_MATH_SIMD "Enable or not math SIMD optimizations" ON)
+IF(ANKI_ENABLE_MATH_SIMD)
+	IF(ANKI_CPU STREQUAL "X86")
+		SET(ANKI_MATH_SIMD "SSE")
+	ELSEIF(ANKI_CPU STREQUAL "ARM")
+		SET(ANKI_MATH_SIMD "NEON")
+	ELSE()
+		MESSAGE(FATAL "Wrong ANKI_CPU set")
+	ENDIF()
+ELSE()
+	SET(ANKI_MATH_SIMD "NONE")
+ENDIF()
 
 
 # libz and libpng
 # libz and libpng
 OPTION(ANKI_SYSTEM_LIBZ "Use the system's libz" OFF)
 OPTION(ANKI_SYSTEM_LIBZ "Use the system's libz" OFF)
@@ -53,120 +66,87 @@ SET(ANKI_GCC_TO_STRING_WORKAROUND "0" CACHE STRING "Enable workaround for C++11
 SET(ANKI_EXTRA_INCLUDE_DIRS CACHE STRING "Some extra include paths (Needed for some weird builds)")
 SET(ANKI_EXTRA_INCLUDE_DIRS CACHE STRING "Some extra include paths (Needed for some weird builds)")
 SET(ANKI_EXTRA_LIB_DIRS CACHE STRING "Some extra lib paths (Needed for some weird builds)")
 SET(ANKI_EXTRA_LIB_DIRS CACHE STRING "Some extra lib paths (Needed for some weird builds)")
 
 
+# Valgrind
+OPTION(ANKI_VALGRIND_HAPPY "Make valgrind happy" OFF)
+
 #
 #
 # Options that affect anki and extern
 # Options that affect anki and extern
 #
 #
 
 
-# CPU
-MESSAGE("++ Build for CPU: ${ANKI_CPU}")
+SET(CXX_FLAGS "")
+SET(C_FLAGS "")
+SET(COMMON_FLAGS "")
+SET(LINKER_FLAGS "")
 
 
-IF(ANKI_CPU STREQUAL "X86")
-	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4 ")
-	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4 ")
-ELSE()
+# address space
+IF(NOT ANKI_CPU_ADDR_SPACE STREQUAL "0")
+	SET(LINKER_FLAGS "${LINKER_FLAGS} -m${ANKI_CPU_ADDR_SPACE} ")
+	SET(COMMON_FLAGS "${COMMON_FLAGS} -m${ANKI_CPU_ADDR_SPACE} ")
 ENDIF()
 ENDIF()
 
 
-IF(ANKI_ENABLE_MATH_SIMD)
-	IF(ANKI_CPU STREQUAL "X86")
-		SET(ANKI_MATH_SIMD "SSE")
-	ELSEIF(ANKI_CPU STREQUAL "ARM")
-		SET(ANKI_MATH_SIMD "NEON")
-	ELSE()
-		MESSAGE(FATAL "Wrong ANKI_CPU set")
-	ENDIF()
+# static libstdc++
+SET(CXX_FLAGS "${CXX_FLAGS} -static-libstdc++ ")
 
 
-	MESSAGE("++ SIMD: true")
-ELSE()
-	SET(ANKI_MATH_SIMD "NONE")
-	MESSAGE("++ SIMD: false")
+# SSE
+IF(ANKI_CPU STREQUAL "X86")
+	SET(COMMON_FLAGS "${COMMON_FLAGS} -msse4 ")
 ENDIF()
 ENDIF()
 
 
-# CPU address space
-IF(ANKI_CPU_ADDR_SPACE STREQUAL "0")
-	MESSAGE("++ CPU address space: 0 (Native)")
+IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
+	# Debug
+
+	SET(COMMON_FLAGS "${COMMON_FLAGS} -g3 -O0 ")
 ELSE()
 ELSE()
-	MESSAGE("++ CPU address space: ${ANKI_CPU_ADDR_SPACE}")
-ENDIF()
+	# Release
 
 
-IF(NOT ANKI_CPU_ADDR_SPACE STREQUAL "0")
-	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${ANKI_CPU_ADDR_SPACE} ")
-	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m${ANKI_CPU_ADDR_SPACE} ")
-	SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m${ANKI_CPU_ADDR_SPACE} ")
+	SET(COMMON_FLAGS "${COMMON_FLAGS} -ffast-math -O4 ")
+
+	SET(CXX_FLAGS "${CXX_FLAGS} -fno-rtti ")
 ENDIF()
 ENDIF()
 
 
-# platform
-IF(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
-	SET(ANKI_PLATFORM "LINUX")
-ELSEIF(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
-	SET(ANKI_PLATFORM "WINDOWS")
+# Valgrind hacks
+IF(ANKI_VALGRIND_HAPPY)
+	ADD_DEFINITIONS("-DGLIBCXX_FORCE_NEW")
 ENDIF()
 ENDIF()
-MESSAGE("++ Platform: ${ANKI_PLATFORM}")
 
 
 # libz and libpng
 # libz and libpng
 IF(ANKI_SYSTEM_LIBZ)
 IF(ANKI_SYSTEM_LIBZ)
 	SET(_ANKI_LIBZ "z")
 	SET(_ANKI_LIBZ "z")
-	MESSAGE("++ Building with system libz")
 ELSE()
 ELSE()
 	SET(_ANKI_LIBZ "ankiz")
 	SET(_ANKI_LIBZ "ankiz")
-	MESSAGE("++ Building with AnKi provided libz")
 ENDIF()
 ENDIF()
 
 
 IF(ANKI_SYSTEM_LIBPNG)
 IF(ANKI_SYSTEM_LIBPNG)
 	SET(_ANKI_LIBPNG "png")
 	SET(_ANKI_LIBPNG "png")
-	MESSAGE("++ Building with system libpng")
 ELSE()
 ELSE()
 	SET(_ANKI_LIBPNG "ankipng")
 	SET(_ANKI_LIBPNG "ankipng")
-	MESSAGE("++ Building with AnKi provided libpng")
 ENDIF()
 ENDIF()
 
 
 # Disable GLU in GLEW
 # Disable GLU in GLEW
 ADD_DEFINITIONS(-DGLEW_NO_GLU)
 ADD_DEFINITIONS(-DGLEW_NO_GLU)
 
 
-# Window backend
-MESSAGE("++ Window backend: ${ANKI_WINDOW_BACKEND}")
-
-#
-# Common compiler flags
-#
-
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -static-libstdc++")
-
-# Build type
-IF(CMAKE_BUILD_TYPE STREQUAL Debug)
-	# Do nothing
-ELSE()
-	SET(FLAGS " -ffast-math")
-
-	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS} -fno-rtti ")
-	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
-	SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
-ENDIF()
-
 # Strip
 # Strip
 IF(ANKI_STRIP)
 IF(ANKI_STRIP)
-	MESSAGE("++ Stipping symbols: true")
-	SET(FLAGS " -s ")
-
-	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}")
-	SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}")
-	SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
-ELSE()
-	MESSAGE("++ Stipping symbols: false")
+	SET(LINKER_FLAGS "${LINKER_FLAGS} -s ")
+	SET(COMMON_FLAGS "${COMMON_FLAGS} -s ")
 ENDIF()
 ENDIF()
 
 
 # gperftools
 # gperftools
 IF(ANKI_WITH_GPERFTOOLS_PROF)
 IF(ANKI_WITH_GPERFTOOLS_PROF)
 	LINK_DIRECTORIES("/home/godlike/src/more/gperftools/install/lib")
 	LINK_DIRECTORIES("/home/godlike/src/more/gperftools/install/lib")
 	SET(ANKI_GPERFTOOLS_LIBS "profiler")
 	SET(ANKI_GPERFTOOLS_LIBS "profiler")
-	MESSAGE("++ With gperftools profiler: true")
 ELSE()
 ELSE()
 	SET(ANKI_GPERFTOOLS_LIBS "")
 	SET(ANKI_GPERFTOOLS_LIBS "")
-	MESSAGE("++ With gperftools profiler: false")
 ENDIF()
 ENDIF()
 
 
 INCLUDE_DIRECTORIES(${ANKI_EXTRA_INCLUDE_DIRS})
 INCLUDE_DIRECTORIES(${ANKI_EXTRA_INCLUDE_DIRS})
 LINK_DIRECTORIES(${ANKI_EXTRA_LIB_DIRS})
 LINK_DIRECTORIES(${ANKI_EXTRA_LIB_DIRS})
 
 
+# Set the flags to cmake now
+SET(CMAKE_CXX_FLAGS "${COMMON_FLAGS} ${CXX_FLAGS}")
+SET(CMAKE_C_FLAGS "${COMMON_FLAGS} ${C_FLAGS}")
+SET(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}")
+
 #
 #
 # Install
 # Install
 #
 #
@@ -212,26 +192,14 @@ SET(ANKI_VERSION_MINOR 1)
 MESSAGE("++ AnKi version: ${ANKI_VERSION_MAJOR}.${ANKI_VERSION_MINOR}")
 MESSAGE("++ AnKi version: ${ANKI_VERSION_MAJOR}.${ANKI_VERSION_MINOR}")
 
 
 IF(CMAKE_BUILD_TYPE STREQUAL Debug)
 IF(CMAKE_BUILD_TYPE STREQUAL Debug)
-	MESSAGE("++ Debug build: true")
 	SET(ANKI_DEBUG 1)
 	SET(ANKI_DEBUG 1)
 ELSE()
 ELSE()
-	MESSAGE("++ Debug build: false")
 	SET(ANKI_DEBUG 0)
 	SET(ANKI_DEBUG 0)
 ENDIF()
 ENDIF()
 
 
 CONFIGURE_FILE("include/anki/Config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h")
 CONFIGURE_FILE("include/anki/Config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h")
 INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h" DESTINATION "${INCLUDE_INSTALL_DIR}/anki")
 INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/anki/Config.h" DESTINATION "${INCLUDE_INSTALL_DIR}/anki")
 
 
-#
-# Defines
-#
-ADD_DEFINITIONS("-Dthread_local=__thread")
-
-#
-# AnKi compiler flags (Mainly warnings)
-#
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors -pedantic -ansi -Wall -W -Wextra -Wwrite-strings -Wno-unused -Wno-unused-parameter -Wundef -Werror -std=c++11")
-
 #
 #
 # Include & lib directories
 # Include & lib directories
 #
 #
@@ -244,23 +212,15 @@ ELSE()
 	INCLUDE_DIRECTORIES("extern/GLES3/include")
 	INCLUDE_DIRECTORIES("extern/GLES3/include")
 ENDIF()
 ENDIF()
 
 
-# Add a few compiler specific stuff 
-IF(${CMAKE_CXX_COMPILER} MATCHES ".*clang\\+\\+$")	
-	INCLUDE_DIRECTORIES("/opt/libcxx/include/c++/v1")
-	LINK_DIRECTORIES("/opt/libcxx/lib")
-ELSE()
-	# Dont use it. It produces warnings with -std=c++0x
-	#ADD_DEFINITIONS("-fsingle-precision-constant")
-ENDIF()
-
 #
 #
-# Valgrind hacks
+# AnKi specific compiler flags
 #
 #
-OPTION(ANKI_VALGRIND_HAPPY "Make valgrind happy" OFF)
 
 
-IF(ANKI_VALGRIND_HAPPY)
-	ADD_DEFINITIONS("-DGLIBCXX_FORCE_NEW")
-ENDIF()
+# thread local
+ADD_DEFINITIONS("-Dthread_local=__thread")
+
+# AnKi compiler flags (Mainly warnings)
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -W -Wextra -Wwrite-strings -Wunused -Wunused-variable -Wno-unused-parameter -Wundef -std=c++11 ")
 
 
 #
 #
 # Add anki related dirs
 # Add anki related dirs
@@ -279,3 +239,4 @@ ENDIF()
 IF(ANKI_BUILD_TESTAPP)
 IF(ANKI_BUILD_TESTAPP)
 	ADD_SUBDIRECTORY(testapp)
 	ADD_SUBDIRECTORY(testapp)
 ENDIF()
 ENDIF()
+

+ 1 - 1
shaders/Pps.glsl

@@ -90,7 +90,7 @@ vec3 erosion(in sampler2D tex, in vec2 texCoords)
 //==============================================================================
 //==============================================================================
 void main(void)
 void main(void)
 {
 {
-#if SHARPEN_ENABLED
+#if defined(SHARPEN_ENABLED)
 	fColor = sharpen(isFai, vTexCoords);
 	fColor = sharpen(isFai, vTexCoords);
 #else
 #else
 	fColor = textureLod(isFai, vTexCoords, 0.0).rgb;
 	fColor = textureLod(isFai, vTexCoords, 0.0).rgb;

+ 2 - 0
src/renderer/Drawer.cpp

@@ -12,6 +12,7 @@
 namespace anki {
 namespace anki {
 
 
 //==============================================================================
 //==============================================================================
+#if ANKI_ENABLE_COUNTERS
 static U64 countVerts(U32* indicesCount, I primCount)
 static U64 countVerts(U32* indicesCount, I primCount)
 {
 {
 	U64 sum = 0;
 	U64 sum = 0;
@@ -21,6 +22,7 @@ static U64 countVerts(U32* indicesCount, I primCount)
 	}
 	}
 	return sum;
 	return sum;
 }
 }
+#endif
 
 
 //==============================================================================
 //==============================================================================
 /// Visitor that sets a uniform
 /// Visitor that sets a uniform

+ 13 - 3
src/scene/ModelNode.cpp

@@ -222,11 +222,21 @@ ModelNode::~ModelNode()
 void ModelNode::setInstanceLocalTransform(U instanceIndex, const Transform& trf)
 void ModelNode::setInstanceLocalTransform(U instanceIndex, const Transform& trf)
 {
 {
 	ANKI_ASSERT(patches.size() > 0);
 	ANKI_ASSERT(patches.size() > 0);
-	ANKI_ASSERT(instanceIndex < patches[0]->instances.size());
 
 
-	for(ModelPatchNode* patch : patches)
+	if(patches[0]->instances.size() > 0)
+	{
+		ANKI_ASSERT(instanceIndex < patches[0]->instances.size());
+
+		for(ModelPatchNode* patch : patches)
+		{
+			patch->instances[instanceIndex]->setLocalTransform(trf);
+		}
+	}
+	else
 	{
 	{
-		patch->instances[instanceIndex]->setLocalTransform(trf);
+		ANKI_ASSERT(instanceIndex == 0);
+
+		setLocalTransform(trf);
 	}
 	}
 }
 }
 
 

+ 1 - 1
src/util/CMakeLists.txt

@@ -1,6 +1,6 @@
 SET(ANKI_UTIL_SOURCES Assert.cpp BinaryStream.cpp Exception.cpp Functions.cpp StringList.cpp Filesystem.cpp Allocator.cpp Memory.cpp System.cpp)
 SET(ANKI_UTIL_SOURCES Assert.cpp BinaryStream.cpp Exception.cpp Functions.cpp StringList.cpp Filesystem.cpp Allocator.cpp Memory.cpp System.cpp)
 
 
-IF(ANKI_PLATFORM STREQUAL "LINUX")
+IF(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
 	SET(ANKI_UTIL_SOURCES ${ANKI_UTIL_SOURCES} HighRezTimerPosix.cpp FilesystemPosix.cpp)
 	SET(ANKI_UTIL_SOURCES ${ANKI_UTIL_SOURCES} HighRezTimerPosix.cpp FilesystemPosix.cpp)
 ELSE()
 ELSE()
 	MESSAGE(FATAL "See file")
 	MESSAGE(FATAL "See file")

+ 3 - 5
testapp/Main.cpp

@@ -243,12 +243,9 @@ void init()
 	// barrel
 	// barrel
 	ModelNode* redBarrel = new ModelNode(
 	ModelNode* redBarrel = new ModelNode(
 		"red_barrel", &scene, nullptr, Movable::MF_NONE, 
 		"red_barrel", &scene, nullptr, Movable::MF_NONE, 
-		"data/models/red_barrel/red_barrel.mdl", 2);
+		"data/models/red_barrel/red_barrel.mdl");
 	redBarrel->setLocalTransform(Transform(Vec3(+2, 0, 0), Mat3::getIdentity(),
 	redBarrel->setLocalTransform(Transform(Vec3(+2, 0, 0), Mat3::getIdentity(),
 		0.7));
 		0.7));
-
-	redBarrel->setInstanceLocalTransform(1, 
-		Transform(Vec3(1.0), Mat3(Euler(getPi<F32>() / 2, 0.0, 0.0)), 2.0));
 #endif
 #endif
 
 
 #if 0
 #if 0
@@ -472,7 +469,7 @@ void mainLoop()
 
 
 		// Sleep
 		// Sleep
 		//
 		//
-#if 1
+#if 0
 		timer.stop();
 		timer.stop();
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		{
 		{
@@ -554,6 +551,7 @@ void initSubsystems(int argc, char* argv[])
 	initializer.pps.bl.enabled = true;
 	initializer.pps.bl.enabled = true;
 	initializer.pps.bl.blurringIterationsNum = 2;
 	initializer.pps.bl.blurringIterationsNum = 2;
 	initializer.pps.bl.sideBlurFactor = 1.0;
 	initializer.pps.bl.sideBlurFactor = 1.0;
+	initializer.pps.sharpen = true;
 	initializer.renderingQuality = 1.0;
 	initializer.renderingQuality = 1.0;
 	initializer.width = win->getWidth();
 	initializer.width = win->getWidth();
 	initializer.height = win->getHeight();
 	initializer.height = win->getHeight();

+ 75 - 43
tools/2anki/Main.cpp

@@ -36,6 +36,8 @@ struct Config
 	std::vector<Material> materials;
 	std::vector<Material> materials;
 };
 };
 
 
+Config config;
+
 //==============================================================================
 //==============================================================================
 // Log and errors
 // Log and errors
 
 
@@ -90,7 +92,32 @@ static std::string getFilename(const std::string& path)
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-static void parseConfig(int argc, char** argv, Config& config)
+static aiMatrix4x4 toAnkiMatrix(const aiMatrix4x4& in)
+{
+	static const aiMatrix4x4 toLeftHanded(
+		1, 0, 0, 0, 
+		0, 0, 1, 0, 
+		0, -1, 0, 0, 
+		0, 0, 0, 1);
+
+	static const aiMatrix4x4 toLeftHandedInv(
+		1, 0, 0, 0, 
+		0, 0, -1, 0, 
+		0, 1, 0, 0, 
+		0, 0, 0, 1);
+
+	if(config.flipyz)
+	{
+		return toLeftHanded * in * toLeftHandedInv;
+	}
+	else
+	{
+		return in;
+	}
+}
+
+//==============================================================================
+static void parseConfig(int argc, char** argv)
 {
 {
 	static const char* usage = R"(Usage: 2anki in_file out_dir [options]
 	static const char* usage = R"(Usage: 2anki in_file out_dir [options]
 Options:
 Options:
@@ -168,6 +195,7 @@ static const aiScene& load(
 		//| aiProcess_SortByPType
 		//| aiProcess_SortByPType
 		| aiProcess_ImproveCacheLocality
 		| aiProcess_ImproveCacheLocality
 		| aiProcess_OptimizeMeshes
 		| aiProcess_OptimizeMeshes
+		| aiProcess_RemoveRedundantMaterials
 		);
 		);
 
 
 	if(!scene)
 	if(!scene)
@@ -194,8 +222,7 @@ struct Vw
 static void exportMesh(
 static void exportMesh(
 	const aiMesh& mesh, 
 	const aiMesh& mesh, 
 	const std::string* name_,
 	const std::string* name_,
-	const aiMatrix4x4* transform,
-	const Config& config)
+	const aiMatrix4x4* transform)
 {
 {
 	std::string name = (name_) ? *name_ : mesh.mName.C_Str();
 	std::string name = (name_) ? *name_ : mesh.mName.C_Str();
 	std::fstream file;
 	std::fstream file;
@@ -230,9 +257,13 @@ static void exportMesh(
 		// flip
 		// flip
 		if(config.flipyz)
 		if(config.flipyz)
 		{
 		{
-			float tmp = pos[1];
-			pos[1] = pos[2];
-			pos[2] = -tmp;
+			static const aiMatrix4x4 toLefthanded(
+				1, 0, 0, 0, 
+				0, 0, 1, 0, 
+				0, -1, 0, 0, 
+				0, 0, 0, 1);
+
+			pos = toLefthanded * pos;
 		}
 		}
 
 
 		for(uint32_t j = 0; j < 3; j++)
 		for(uint32_t j = 0; j < 3; j++)
@@ -337,7 +368,7 @@ static void exportMesh(
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-static void exportSkeleton(const aiMesh& mesh, const Config& config)
+static void exportSkeleton(const aiMesh& mesh)
 {
 {
 	assert(mesh.HasBones());
 	assert(mesh.HasBones());
 	std::string name = mesh.mName.C_Str();
 	std::string name = mesh.mName.C_Str();
@@ -409,8 +440,7 @@ static void exportMaterial(
 	const aiScene& scene, 
 	const aiScene& scene, 
 	const aiMaterial& mtl, 
 	const aiMaterial& mtl, 
 	bool instanced,
 	bool instanced,
-	const std::string* name_,
-	const Config& config)
+	const std::string* name_)
 {
 {
 	std::string diffTex;
 	std::string diffTex;
 	std::string normTex;
 	std::string normTex;
@@ -489,7 +519,6 @@ static void exportMaterial(
 //==============================================================================
 //==============================================================================
 static void exportLight(
 static void exportLight(
 	const aiLight& light, 
 	const aiLight& light, 
-	const Config& config, 
 	std::fstream& file)
 	std::fstream& file)
 {
 {
 	if(light.mType != aiLightSource_POINT || light.mType != aiLightSource_SPOT)
 	if(light.mType != aiLightSource_POINT || light.mType != aiLightSource_SPOT)
@@ -555,8 +584,7 @@ static void exportLight(
 //==============================================================================
 //==============================================================================
 static void exportModel(
 static void exportModel(
 	const aiScene& scene, 
 	const aiScene& scene, 
-	const aiNode& node, 
-	const Config& config)
+	const aiNode& node)
 {
 {
 	if(node.mNumMeshes == 0)
 	if(node.mNumMeshes == 0)
 	{
 	{
@@ -606,8 +634,7 @@ static void exportModel(
 static void exportAnimation(
 static void exportAnimation(
 	const aiAnimation& anim, 
 	const aiAnimation& anim, 
 	uint32_t index, 
 	uint32_t index, 
-	const aiScene& scene, 
-	const Config& config)
+	const aiScene& scene)
 {
 {
 	// Get name
 	// Get name
 	std::string name = anim.mName.C_Str();
 	std::string name = anim.mName.C_Str();
@@ -694,7 +721,7 @@ static void exportAnimation(
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-static void visitNode(const aiNode* node, const aiScene& scene, Config& config)
+static void visitNode(const aiNode* node, const aiScene& scene)
 {
 {
 	if(node == nullptr)
 	if(node == nullptr)
 	{
 	{
@@ -728,23 +755,28 @@ static void visitNode(const aiNode* node, const aiScene& scene, Config& config)
 	// Go to children
 	// Go to children
 	for(uint32_t i = 0; i < node->mNumChildren; i++)
 	for(uint32_t i = 0; i < node->mNumChildren; i++)
 	{
 	{
-		visitNode(node->mChildren[i], scene, config);
+		visitNode(node->mChildren[i], scene);
 	}
 	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-static void exportScene(const aiScene& scene, Config& config)
+static void exportScene(const aiScene& scene)
 {
 {
 	LOGI("Exporting scene to %s\n", config.outDir.c_str());
 	LOGI("Exporting scene to %s\n", config.outDir.c_str());
 
 
+	//
 	// Open scene file
 	// Open scene file
+	//
 	std::ofstream file;
 	std::ofstream file;
 	file.open(config.outDir + "master.scene");
 	file.open(config.outDir + "master.scene");
 
 
 	file << xmlHeader << "\n"
 	file << xmlHeader << "\n"
 		<< "<scene>\n";
 		<< "<scene>\n";
 
 
+	//
 	// Get all the data
 	// Get all the data
+	//
+
 	config.meshes.resize(scene.mNumMeshes);
 	config.meshes.resize(scene.mNumMeshes);
 	config.materials.resize(scene.mNumMaterials);
 	config.materials.resize(scene.mNumMaterials);
 
 
@@ -761,19 +793,29 @@ static void exportScene(const aiScene& scene, Config& config)
 
 
 	const aiNode* node = scene.mRootNode;
 	const aiNode* node = scene.mRootNode;
 
 
-	visitNode(node, scene, config);
+	visitNode(node, scene);
 
 
 #if 0
 #if 0
-	// Export all meshes that are used
+	//
+	// Export non instanced static meshes
+	//
 	for(uint32_t i = 0; i < config.meshes.size(); i++)
 	for(uint32_t i = 0; i < config.meshes.size(); i++)
 	{
 	{
-		// Check if used
-		if(config.meshes[i].transforms.size() < 1)
+		// Check if instance is one
+		if(config.meshes[i].transforms.size() == 1)
 		{
 		{
 			continue;
 			continue;
 		}
 		}
 
 
-		std::string name = "mesh_" + std::to_string(i);
+		// Export the material
+		aiMaterial& aimtl = *scene.mMaterials[mesh.mtlIndex];
+		std::string mtlName = getMaterialName(aimtl);
+		exportMaterial(scene, aimtl, false, &mtlName);
+
+		// Export mesh
+		std::string meshName = std::string(scene.mMeshes[i]->mName.C_Str())
+			+ "_static_" + std::to_string(i);
+		exportMesh(*scene.mMeshes[i], &meshName, nullptr);
 
 
 		for(uint32_t t = 0; t < config.meshes[i].transforms.size(); t++)
 		for(uint32_t t = 0; t < config.meshes[i].transforms.size(); t++)
 		{
 		{
@@ -783,39 +825,30 @@ static void exportScene(const aiScene& scene, Config& config)
 				&config.meshes[i].transforms[t], config);
 				&config.meshes[i].transforms[t], config);
 		}
 		}
 	}
 	}
-
-	// Export materials
-	for(uint32_t i = 0; i < config.materials.size(); i++)
-	{
-		// Check if used
-		if(config.materials[i].meshIndices.size() < 1)
-		{
-			continue;
-		}
-
-		exportMaterial(scene, *scene.mMaterials[i], config);
-	}
 #endif
 #endif
 
 
+	//
 	// Write the instanced meshes
 	// Write the instanced meshes
+	//
 	for(uint32_t i = 0; i < config.meshes.size(); i++)
 	for(uint32_t i = 0; i < config.meshes.size(); i++)
 	{
 	{
 		const Mesh& mesh = config.meshes[i];
 		const Mesh& mesh = config.meshes[i];
 
 
 		// Skip meshes that are not instance candidates
 		// Skip meshes that are not instance candidates
-		if(mesh.transforms.size() < 2)
+		if(mesh.transforms.size() == 0)
 		{
 		{
 			continue;
 			continue;
 		}
 		}
 
 
 		// Export the material
 		// Export the material
 		aiMaterial& aimtl = *scene.mMaterials[mesh.mtlIndex];
 		aiMaterial& aimtl = *scene.mMaterials[mesh.mtlIndex];
-		std::string mtlName = getMaterialName(aimtl) + "_instance";
-		exportMaterial(scene, aimtl, true, &mtlName, config);
+		std::string mtlName = getMaterialName(aimtl) + "_instanced";
+		exportMaterial(scene, aimtl, true, &mtlName);
 
 
 		// Export mesh
 		// Export mesh
-		std::string meshName = mtlName + "_" + std::to_string(i);
-		exportMesh(*scene.mMeshes[i], &meshName, nullptr, config);
+		std::string meshName = std::string(scene.mMeshes[i]->mName.C_Str())
+			+ "_instanced_" + std::to_string(i);
+		exportMesh(*scene.mMeshes[i], &meshName, nullptr);
 
 
 		// Write model file
 		// Write model file
 		std::string modelName = mtlName + "_" + std::to_string(i);
 		std::string modelName = mtlName + "_" + std::to_string(i);
@@ -853,7 +886,7 @@ static void exportScene(const aiScene& scene, Config& config)
 		{
 		{
 			file << "\t\t<transform>";
 			file << "\t\t<transform>";
 
 
-			aiMatrix4x4 trf = mesh.transforms[j];
+			aiMatrix4x4 trf = toAnkiMatrix(mesh.transforms[j]);
 
 
 			for(uint32_t a = 0; a < 4; a++)
 			for(uint32_t a = 0; a < 4; a++)
 			{
 			{
@@ -946,15 +979,14 @@ int main(int argc, char** argv)
 {
 {
 	try
 	try
 	{
 	{
-		Config config;
-		parseConfig(argc, argv, config);
+		parseConfig(argc, argv);
 
 
 		// Load
 		// Load
 		Assimp::Importer importer;
 		Assimp::Importer importer;
 		const aiScene& scene = load(config.inputFname, importer);
 		const aiScene& scene = load(config.inputFname, importer);
 
 
 		// Export
 		// Export
-		exportScene(scene, config);
+		exportScene(scene);
 	}
 	}
 	catch(std::exception& e)
 	catch(std::exception& e)
 	{
 	{