소스 검색

Remove the unused assimp importer

Panagiotis Christopoulos Charitos 5 년 전
부모
커밋
e0004c7707

+ 0 - 8
tools/scene/CMakeLists.txt

@@ -1,8 +0,0 @@
-include_directories("../../thirdparty/assimp/include")
-include_directories("../../src")
-
-add_definitions("-fexceptions")
-
-add_executable(sceneimp Main.cpp Common.cpp Exporter.cpp ExporterMesh.cpp ExporterMaterial.cpp)
-target_link_libraries(sceneimp ankiassimp anki)
-installExecutable(sceneimp)

+ 0 - 70
tools/scene/Common.cpp

@@ -1,70 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "Common.h"
-#include <cstdarg>
-
-#define TERMINAL_COL_INFO "\033[0;32m"
-#define TERMINAL_COL_ERROR "\033[1;31m"
-#define TERMINAL_COL_WARNING "\033[0;33m"
-#define TERMINAL_COL_RESET "\033[0m"
-
-void log(const char* file, int line, unsigned type, const char* fmt, ...)
-{
-	char buffer[1024];
-	va_list args;
-
-	va_start(args, fmt);
-	vsnprintf(buffer, sizeof(buffer), fmt, args);
-	va_end(args);
-
-	switch(type)
-	{
-	case 1:
-		fprintf(stdout, TERMINAL_COL_INFO "[I] %s (%s:%d)\n" TERMINAL_COL_RESET, buffer, file, line);
-		break;
-	case 2:
-		fprintf(stderr, TERMINAL_COL_ERROR "[E] %s (%s:%d)\n" TERMINAL_COL_RESET, buffer, file, line);
-		break;
-	case 3:
-		fprintf(stderr, TERMINAL_COL_WARNING "[W] %s (%s:%d)\n" TERMINAL_COL_RESET, buffer, file, line);
-		break;
-	};
-}
-
-std::string replaceAllString(const std::string& str, const std::string& from, const std::string& to)
-{
-	if(from.empty())
-	{
-		return str;
-	}
-
-	std::string out = str;
-	size_t start_pos = 0;
-	while((start_pos = out.find(from, start_pos)) != std::string::npos)
-	{
-		out.replace(start_pos, from.length(), to);
-		start_pos += to.length();
-	}
-
-	return out;
-}
-
-std::string getFilename(const std::string& path)
-{
-	std::string out;
-
-	const size_t last = path.find_last_of("/");
-	if(std::string::npos != last)
-	{
-		out.insert(out.end(), path.begin() + last + 1, path.end());
-	}
-	else
-	{
-		out = path;
-	}
-
-	return out;
-}

+ 0 - 29
tools/scene/Common.h

@@ -1,29 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma once
-
-#include <string>
-
-/// Write to log. Don't use it directly.
-void log(const char* file, int line, unsigned type, const char* fmt, ...);
-
-// Log and errors
-#define LOGI(...) log(__FILE__, __LINE__, 1, __VA_ARGS__)
-
-#define ERROR(...) \
-	do \
-	{ \
-		log(__FILE__, __LINE__, 2, __VA_ARGS__); \
-		exit(0); \
-	} while(0)
-
-#define LOGW(...) log(__FILE__, __LINE__, 3, __VA_ARGS__)
-
-/// Replace all @a from substrings in @a str to @a to
-std::string replaceAllString(const std::string& str, const std::string& from, const std::string& to);
-
-/// From a path return only the filename
-std::string getFilename(const std::string& path);

+ 0 - 1248
tools/scene/Exporter.cpp

@@ -1,1248 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "Exporter.h"
-#include <iostream>
-
-static const char* XML_HEADER = R"(<?xml version="1.0" encoding="UTF-8" ?>)";
-
-#if 0
-static aiColor3D srgbToLinear(aiColor3D in)
-{
-	const float p = 1.0f / 2.4f;
-	aiColor3D out;
-	out[0] = pow(in[0], p);
-	out[1] = pow(in[1], p);
-	out[2] = pow(in[2], p);
-	out[3] = in[3];
-	return out;
-}
-
-/// Convert from sRGB to linear and preserve energy
-static aiColor3D computeLightColor(aiColor3D in)
-{
-	float energy = std::max(std::max(in[0], in[1]), in[2]);
-
-	if(energy > 1.0)
-	{
-		in[0] /= energy;
-		in[1] /= energy;
-		in[2] /= energy;
-	}
-	else
-	{
-		energy = 1.0;
-	}
-
-	in = srgbToLinear(in);
-
-	in[0] *= energy;
-	in[1] *= energy;
-	in[2] *= energy;
-
-	return in;
-}
-#endif
-
-static std::string getMeshName(const aiMesh& mesh)
-{
-	return std::string(mesh.mName.C_Str());
-}
-
-/// Walk the node hierarchy and find the node.
-static const aiNode* findNodeWithName(const std::string& name, const aiNode* node, unsigned* depth = nullptr)
-{
-	if(node == nullptr || node->mName.C_Str() == name)
-	{
-		return node;
-	}
-
-	if(depth)
-	{
-		++(*depth);
-	}
-
-	const aiNode* out = nullptr;
-
-	// Go to children
-	for(unsigned i = 0; i < node->mNumChildren; i++)
-	{
-		out = findNodeWithName(name, node->mChildren[i]);
-		if(out)
-		{
-			break;
-		}
-	}
-
-	return out;
-}
-
-static std::vector<std::string> tokenize(const std::string& source)
-{
-	const char* delimiter = " ";
-	bool keepEmpty = false;
-	std::vector<std::string> results;
-
-	size_t prev = 0;
-	size_t next = 0;
-
-	while((next = source.find_first_of(delimiter, prev)) != std::string::npos)
-	{
-		if(keepEmpty || (next - prev != 0))
-		{
-			results.push_back(source.substr(prev, next - prev));
-		}
-
-		prev = next + 1;
-	}
-
-	if(prev < source.size())
-	{
-		results.push_back(source.substr(prev));
-	}
-
-	return results;
-}
-
-template<int N, typename Arr>
-static void stringToFloatArray(const std::string& in, Arr& out)
-{
-	std::vector<std::string> tokens = tokenize(in);
-	if(tokens.size() != N)
-	{
-		ERROR("Failed to parse %s", in.c_str());
-	}
-
-	int count = 0;
-	for(const std::string& s : tokens)
-	{
-		out[count] = std::stof(s);
-		++count;
-	}
-}
-
-static void removeScale(aiMatrix4x4& m)
-{
-	aiVector3D xAxis(m.a1, m.b1, m.c1);
-	aiVector3D yAxis(m.a2, m.b2, m.c2);
-	aiVector3D zAxis(m.a3, m.b3, m.c3);
-
-	float scale = xAxis.Length();
-	m.a1 /= scale;
-	m.b1 /= scale;
-	m.c1 /= scale;
-
-	scale = yAxis.Length();
-	m.a2 /= scale;
-	m.b2 /= scale;
-	m.c2 /= scale;
-
-	scale = zAxis.Length();
-	m.a3 /= scale;
-	m.b3 /= scale;
-	m.c3 /= scale;
-}
-
-static float getUniformScale(const aiMatrix4x4& m)
-{
-	const float SCALE_THRESHOLD = 0.01f; // 1 cm
-
-	aiVector3D xAxis(m.a1, m.b1, m.c1);
-	aiVector3D yAxis(m.a2, m.b2, m.c2);
-	aiVector3D zAxis(m.a3, m.b3, m.c3);
-
-	float scale = xAxis.Length();
-	if(std::abs(scale - yAxis.Length()) > SCALE_THRESHOLD || std::abs(scale - zAxis.Length()) > SCALE_THRESHOLD)
-	{
-		ERROR("No uniform scale in the matrix");
-	}
-
-	return scale;
-}
-
-static aiVector3D getNonUniformScale(const aiMatrix4x4& m)
-{
-	aiVector3D xAxis(m.a1, m.b1, m.c1);
-	aiVector3D yAxis(m.a2, m.b2, m.c2);
-	aiVector3D zAxis(m.a3, m.b3, m.c3);
-
-	aiVector3D scale;
-	scale[0] = xAxis.Length();
-	scale[1] = yAxis.Length();
-	scale[2] = zAxis.Length();
-
-	return scale;
-}
-
-std::string Exporter::getMaterialName(const aiMaterial& mtl)
-{
-	aiString ainame;
-	std::string name;
-	if(mtl.Get(AI_MATKEY_NAME, ainame) == AI_SUCCESS)
-	{
-		name = ainame.C_Str();
-	}
-	else
-	{
-		ERROR("Material's name is missing");
-	}
-
-	return name;
-}
-
-aiMatrix4x4 Exporter::toAnkiMatrix(const aiMatrix4x4& in) const
-{
-	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(m_flipyz)
-	{
-		return toLeftHanded * in * toLeftHandedInv;
-	}
-	else
-	{
-		return in;
-	}
-}
-
-aiMatrix3x3 Exporter::toAnkiMatrix(const aiMatrix3x3& in) const
-{
-	static const aiMatrix3x3 toLeftHanded(1, 0, 0, 0, 0, 1, 0, -1, 0);
-
-	static const aiMatrix3x3 toLeftHandedInv(1, 0, 0, 0, 0, -1, 0, 1, 0);
-
-	if(m_flipyz)
-	{
-		return toLeftHanded * in;
-	}
-	else
-	{
-		return in;
-	}
-}
-
-void Exporter::writeTransform(const aiMatrix4x4& inmat)
-{
-	aiMatrix4x4 mat = inmat;
-	std::ofstream& file = m_sceneFile;
-
-	float pos[3];
-	pos[0] = mat[0][3];
-	pos[1] = mat[1][3];
-	pos[2] = mat[2][3];
-
-	file << "trf = Transform.new()\n";
-
-	file << "trf:setOrigin(Vec4.new(" << pos[0] << ", " << pos[1] << ", " << pos[2] << ", 0))\n";
-
-	float scale = getUniformScale(mat);
-	removeScale(mat);
-
-	file << "rot = Mat3x4.new()\n";
-	file << "rot:setAll(";
-	for(unsigned j = 0; j < 3; j++)
-	{
-		for(unsigned i = 0; i < 4; i++)
-		{
-			if(i == 3)
-			{
-				file << "0";
-			}
-			else
-			{
-				file << mat[j][i];
-			}
-
-			if(!(i == 3 && j == 2))
-			{
-				file << ", ";
-			}
-		}
-	}
-	file << ")\n";
-
-	file << "trf:setRotation(rot)\n";
-	file << "trf:setScale(" << scale << ")\n";
-}
-
-void Exporter::writeNodeTransform(const std::string& node, const aiMatrix4x4& mat)
-{
-	std::ofstream& file = m_sceneFile;
-
-	writeTransform(mat);
-
-	file << node << ":getSceneNodeBase():getMoveComponent():setLocalTransform(trf)\n";
-}
-
-const aiMesh& Exporter::getMeshAt(unsigned index) const
-{
-	assert(index < m_scene->mNumMeshes);
-	return *m_scene->mMeshes[index];
-}
-
-const aiMaterial& Exporter::getMaterialAt(unsigned index) const
-{
-	assert(index < m_scene->mNumMaterials);
-	return *m_scene->mMaterials[index];
-}
-
-std::string Exporter::getModelName(const Model& model) const
-{
-	std::string name = getMeshName(getMeshAt(model.m_meshIndex));
-
-	name += getMaterialName(getMaterialAt(model.m_materialIndex));
-
-	return name;
-}
-
-void Exporter::exportSkeleton(const aiMesh& mesh) const
-{
-	assert(mesh.HasBones());
-	std::string name = mesh.mName.C_Str();
-	std::fstream file;
-	LOGI("Exporting skeleton %s", name.c_str());
-
-	// Find the root bone
-	unsigned minDepth = 0xFFFFFFFF;
-	std::string rootBoneName;
-	for(uint32_t i = 0; i < mesh.mNumBones; i++)
-	{
-		const aiBone& bone = *mesh.mBones[i];
-		unsigned depth = 0;
-		const aiNode* node = findNodeWithName(bone.mName.C_Str(), m_scene->mRootNode, &depth);
-		if(!node)
-		{
-			ERROR("Bone \"%s\" was not found in the scene hierarchy", bone.mName.C_Str());
-		}
-
-		if(depth < minDepth)
-		{
-			minDepth = depth;
-			rootBoneName = bone.mName.C_Str();
-		}
-	}
-	assert(!rootBoneName.empty());
-
-	// Open file
-	file.open(m_outputDirectory + name + ".ankiskel", std::ios::out);
-
-	file << XML_HEADER << "\n";
-	file << "<skeleton>\n";
-	file << "\t<bones>\n";
-
-	for(uint32_t i = 0; i < mesh.mNumBones; i++)
-	{
-		const aiBone& bone = *mesh.mBones[i];
-
-		file << "\t\t<bone>\n";
-
-		// <name>
-		file << "\t\t\t<name>" << bone.mName.C_Str() << "</name>\n";
-
-		// <boneTransform>
-		aiMatrix4x4 akMat = toAnkiMatrix(bone.mOffsetMatrix);
-		file << "\t\t\t<boneTransform>";
-		for(unsigned j = 0; j < 4; j++)
-		{
-			for(unsigned i = 0; i < 4; i++)
-			{
-				file << akMat[j][i] << " ";
-			}
-		}
-		file << "</boneTransform>\n";
-
-		// <transform>
-		const aiNode* node = findNodeWithName(bone.mName.C_Str(), m_scene->mRootNode);
-		assert(node);
-
-		akMat = toAnkiMatrix(node->mTransformation);
-		file << "\t\t\t<transform>";
-		for(unsigned j = 0; j < 4; j++)
-		{
-			for(unsigned i = 0; i < 4; i++)
-			{
-				file << akMat[j][i] << " ";
-			}
-		}
-		file << "</transform>\n";
-
-		// <parent>
-		if(bone.mName.C_Str() != rootBoneName)
-		{
-			file << "\t\t\t<parent>" << node->mParent->mName.C_Str() << "</parent>\n";
-		}
-
-		file << "\t\t</bone>\n";
-	}
-
-	file << "\t</bones>\n";
-	file << "</skeleton>\n";
-}
-
-void Exporter::exportModel(const Model& model) const
-{
-	std::string name = getModelName(model);
-	LOGI("Exporting model %s", name.c_str());
-
-	std::fstream file;
-	file.open(m_outputDirectory + name + ".ankimdl", std::ios::out);
-
-	file << XML_HEADER << '\n';
-	file << "<model>\n";
-	file << "\t<modelPatches>\n";
-
-	// Start patches
-	file << "\t\t<modelPatch>\n";
-
-	// Write mesh
-	file << "\t\t\t<mesh>" << m_rpath << getMeshName(getMeshAt(model.m_meshIndex)) << ".ankimesh</mesh>\n";
-
-	// Write mesh1
-	if(!model.m_lod1MeshName.empty())
-	{
-		bool found = false;
-		for(unsigned i = 0; i < m_scene->mNumMeshes; i++)
-		{
-			if(m_scene->mMeshes[i]->mName.C_Str() == model.m_lod1MeshName)
-			{
-				file << "\t\t\t<mesh1>" << m_rpath << getMeshName(getMeshAt(i)) << ".ankimesh</mesh1>\n";
-				found = true;
-				break;
-			}
-		}
-
-		if(!found)
-		{
-			ERROR("Couldn't find the LOD1 %s", model.m_lod1MeshName.c_str());
-		}
-	}
-
-	// Write material
-	const aiMaterial& mtl = *m_scene->mMaterials[model.m_materialIndex];
-	if(mtl.mAnKiProperties.find("material_override") == mtl.mAnKiProperties.end())
-	{
-		file << "\t\t\t<material>" << m_rpath << getMaterialName(getMaterialAt(model.m_materialIndex))
-			 << ".ankimtl</material>\n";
-	}
-	else
-	{
-		file << "\t\t\t<material>" << mtl.mAnKiProperties.at("material_override") << "</material>\n";
-	}
-
-	// End patches
-	file << "\t\t</modelPatch>\n";
-	file << "\t</modelPatches>\n";
-
-	// Skeleton
-	const aiMesh& aimesh = *m_scene->mMeshes[model.m_meshIndex];
-	if(aimesh.HasBones())
-	{
-		exportSkeleton(aimesh);
-		file << "\t<skeleton>" << m_rpath << aimesh.mName.C_Str() << ".ankiskel</skeleton>\n";
-	}
-
-	file << "</model>\n";
-}
-
-void Exporter::exportLight(const aiLight& light)
-{
-	std::ofstream& file = m_sceneFile;
-
-	LOGI("Exporting light %s", light.mName.C_Str());
-
-	if(light.mType != aiLightSource_POINT && light.mType != aiLightSource_SPOT
-		&& light.mType != aiLightSource_DIRECTIONAL)
-	{
-		LOGW("Skipping light %s. Unsupported type (0x%x)", light.mName.C_Str(), light.mType);
-		return;
-	}
-
-	if(light.mAttenuationLinear != 0.0)
-	{
-		LOGW("Skipping light %s. Linear attenuation is not 0.0", light.mName.C_Str());
-		return;
-	}
-
-	const char* lightType;
-	switch(light.mType)
-	{
-	case aiLightSource_POINT:
-		lightType = "Point";
-		break;
-	case aiLightSource_SPOT:
-		lightType = "Spot";
-		break;
-	case aiLightSource_DIRECTIONAL:
-		lightType = "Directional";
-		break;
-	default:
-		lightType = nullptr;
-		assert(0);
-	}
-
-	file << "\nnode = scene:new" << lightType << "LightNode(\"" << light.mName.C_Str() << "\")\n";
-
-	file << "lcomp = node:getSceneNodeBase():getLightComponent()\n";
-
-	// Colors
-	// aiColor3D linear = computeLightColor(light.mColorDiffuse);
-	aiVector3D linear(light.mColorDiffuse[0], light.mColorDiffuse[1], light.mColorDiffuse[2]);
-	file << "lcomp:setDiffuseColor(Vec4.new(" << linear[0] << ", " << linear[1] << ", " << linear[2] << ", 1))\n";
-
-	// Geometry
-	switch(light.mType)
-	{
-	case aiLightSource_POINT:
-	{
-		// At this point I want the radius and have the attenuation factors
-		// att = Ac + Al*d + Aq*d^2. When d = r then att = 0.0. Also if we assume that Al is 0 then:
-		// 0 = Ac + Aq*r^2. Solving by r is easy
-		float r = sqrt(light.mAttenuationConstant / light.mAttenuationQuadratic);
-		file << "lcomp:setRadius(" << r << ")\n";
-	}
-	break;
-	case aiLightSource_SPOT:
-	{
-		float dist = sqrt(light.mAttenuationConstant / light.mAttenuationQuadratic);
-
-		float outer = light.mAngleOuterCone;
-		float inner = light.mAngleInnerCone;
-		if(outer == inner)
-		{
-			inner = outer / 2.0f;
-		}
-
-		file << "lcomp:setInnerAngle(" << inner << ")\n"
-			 << "lcomp:setOuterAngle(" << outer << ")\n"
-			 << "lcomp:setDistance(" << dist << ")\n";
-		break;
-	}
-	case aiLightSource_DIRECTIONAL:
-	{
-
-		break;
-	}
-	default:
-		assert(0);
-		break;
-	}
-
-	// Transform
-	const aiNode* node = findNodeWithName(light.mName.C_Str(), m_scene->mRootNode);
-
-	if(node == nullptr)
-	{
-		ERROR("Couldn't find node for light %s", light.mName.C_Str());
-	}
-
-	aiMatrix4x4 rot;
-	aiMatrix4x4::RotationX(-3.1415f / 2.0f, rot);
-	writeNodeTransform("node", toAnkiMatrix(node->mTransformation * rot));
-
-	// Extra
-	if(light.mProperties.find("shadow") != light.mProperties.end())
-	{
-		if(light.mProperties.at("shadow") == "true")
-		{
-			file << "lcomp:setShadowEnabled(1)\n";
-		}
-		else
-		{
-			file << "lcomp:setShadowEnabled(0)\n";
-		}
-	}
-
-	if(light.mProperties.find("lens_flare") != light.mProperties.end())
-	{
-		file << "node:loadLensFlare(\"" << light.mProperties.at("lens_flare") << "\")\n";
-	}
-
-	bool lfCompRetrieved = false;
-
-	if(light.mProperties.find("lens_flare_first_sprite_size") != light.mProperties.end())
-	{
-		if(!lfCompRetrieved)
-		{
-			file << "lfcomp = node:getSceneNodeBase():getLensFlareComponent()\n";
-			lfCompRetrieved = true;
-		}
-
-		aiVector3D vec;
-		stringToFloatArray<2>(light.mProperties.at("lens_flare_first_sprite_size"), vec);
-		file << "lfcomp:setFirstFlareSize(Vec2.new(" << vec[0] << ", " << vec[1] << "))\n";
-	}
-
-	if(light.mProperties.find("lens_flare_color") != light.mProperties.end())
-	{
-		if(!lfCompRetrieved)
-		{
-			file << "lfcomp = node:getSceneNodeBase():getLensFlareComponent()\n";
-			lfCompRetrieved = true;
-		}
-
-		aiVector3D vec;
-		stringToFloatArray<4>(light.mProperties.at("lens_flare_color"), vec);
-		file << "lfcomp:setColorMultiplier(Vec4.new(" << vec[0] << ", " << vec[1] << ", " << vec[2] << ", " << vec[3]
-			 << "))\n";
-	}
-
-	bool eventCreated = false;
-	if(light.mProperties.find("light_event_intensity") != light.mProperties.end())
-	{
-		if(!eventCreated)
-		{
-			file << "event = events:newLightEvent(0.0, -1.0, node:getSceneNodeBase())\n";
-			eventCreated = true;
-		}
-
-		aiVector3D vec;
-		stringToFloatArray<4>(light.mProperties.at("light_event_intensity"), vec);
-
-		file << "event:setIntensityMultiplier(Vec4.new(" << vec[0] << ", " << vec[1] << ", " << vec[2] << ", " << vec[3]
-			 << "))\n";
-	}
-
-	if(light.mProperties.find("light_event_frequency") != light.mProperties.end())
-	{
-		if(!eventCreated)
-		{
-			file << "event = events:newLightEvent(0.0, -1.0, node:getSceneNodeBase())\n";
-			eventCreated = true;
-		}
-
-		float vec[2];
-		stringToFloatArray<2>(light.mProperties.at("light_event_frequency"), vec);
-
-		file << "event:setFrequency(" << vec[0] << ", " << vec[1] << ")\n";
-	}
-}
-
-void Exporter::exportAnimation(const aiAnimation& anim, unsigned index)
-{
-	// Get name
-	std::string name = anim.mName.C_Str();
-	if(name.size() == 0)
-	{
-		name = std::string("unnamed_") + std::to_string(index);
-	}
-
-	// Find if it's skeleton animation
-	/*bool isSkeletalAnimation = false;
-	for(uint32_t i = 0; i < scene.mNumMeshes; i++)
-	{
-		const aiMesh& mesh = *scene.mMeshes[i];
-		if(mesh.HasBones())
-		{
-
-		}
-	}*/
-
-	std::fstream file;
-	LOGI("Exporting animation %s", name.c_str());
-
-	file.open(m_outputDirectory + name + ".ankianim", std::ios::out);
-
-	file << XML_HEADER << "\n";
-	file << "<animation>\n";
-
-	file << "\t<channels>\n";
-
-	for(uint32_t i = 0; i < anim.mNumChannels; i++)
-	{
-		const aiNodeAnim& nAnim = *anim.mChannels[i];
-
-		file << "\t\t<channel>\n";
-
-		// Name
-		file << "\t\t\t<name>" << nAnim.mNodeName.C_Str() << "</name>\n";
-
-		// Positions
-		file << "\t\t\t<positionKeys>\n";
-		for(uint32_t j = 0; j < nAnim.mNumPositionKeys; j++)
-		{
-			const aiVectorKey& key = nAnim.mPositionKeys[j];
-
-			if(m_flipyz)
-			{
-				file << "\t\t\t\t<key><time>" << key.mTime << "</time><value>" << key.mValue[0] << " " << key.mValue[2]
-					 << " " << -key.mValue[1] << "</value></key>\n";
-			}
-			else
-			{
-				file << "\t\t\t\t<key><time>" << key.mTime << "</time><value>" << key.mValue[0] << " " << key.mValue[1]
-					 << " " << key.mValue[2] << "</value></key>\n";
-			}
-		}
-		file << "\t\t\t</positionKeys>\n";
-
-		// Rotations
-		file << "\t\t\t<rotationKeys>\n";
-		for(uint32_t j = 0; j < nAnim.mNumRotationKeys; j++)
-		{
-			const aiQuatKey& key = nAnim.mRotationKeys[j];
-
-			aiMatrix3x3 mat = toAnkiMatrix(key.mValue.GetMatrix());
-			aiQuaternion quat(mat);
-			// aiQuaternion quat(key.mValue);
-
-			file << "\t\t\t\t<key><time>" << key.mTime << "</time>"
-				 << "<value>" << quat.x << " " << quat.y << " " << quat.z << " " << quat.w << "</value></key>\n";
-		}
-		file << "\t\t\t</rotationKeys>\n";
-
-		// Scale
-		file << "\t\t\t<scalingKeys>\n";
-		for(uint32_t j = 0; j < nAnim.mNumScalingKeys; j++)
-		{
-			const aiVectorKey& key = nAnim.mScalingKeys[j];
-
-			// Note: only uniform scale
-			file << "\t\t\t\t<key><time>" << key.mTime << "</time>"
-				 << "<value>" << ((key.mValue[0] + key.mValue[1] + key.mValue[2]) / 3.0) << "</value></key>\n";
-		}
-		file << "\t\t\t</scalingKeys>\n";
-
-		file << "\t\t</channel>\n";
-	}
-
-	file << "\t</channels>\n";
-	file << "</animation>\n";
-}
-
-void Exporter::exportCamera(const aiCamera& cam)
-{
-	std::ofstream& file = m_sceneFile;
-
-	LOGI("Exporting camera %s", cam.mName.C_Str());
-
-	// Write the main node
-	file << "\nnode = scene:newPerspectiveCameraNode(\"" << cam.mName.C_Str() << "\")\n";
-
-	file << "scene:setActiveCameraNode(node:getSceneNodeBase())\n";
-
-	file << "frustumc = node:getSceneNodeBase():getFrustumComponent()\n";
-
-	file << "frustumc:setPerspective(" << cam.mClipPlaneNear << ", " << cam.mClipPlaneFar << ", " << cam.mHorizontalFOV
-		 << ", "
-		 << "1.0 / getMainRenderer():getAspectRatio() * " << cam.mHorizontalFOV << ")\n";
-
-	// Find the node
-	const aiNode* node = findNodeWithName(cam.mName.C_Str(), m_scene->mRootNode);
-	if(node == nullptr)
-	{
-		ERROR("Couldn't find node for camera %s", cam.mName.C_Str());
-	}
-
-	aiMatrix4x4 rot;
-	aiMatrix4x4::RotationX(-3.1415f / 2.0f, rot);
-	writeNodeTransform("node", toAnkiMatrix(node->mTransformation * rot));
-}
-
-void Exporter::load()
-{
-	LOGI("Loading file %s", &m_inputFilename[0]);
-
-	const int smoothAngle = 170;
-
-	m_importer.SetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, smoothAngle);
-
-	unsigned flags = 0
-					 //| aiProcess_FindInstances
-					 | aiProcess_JoinIdenticalVertices
-					 //| aiProcess_SortByPType
-					 | aiProcess_ImproveCacheLocality | aiProcess_OptimizeMeshes | aiProcess_RemoveRedundantMaterials
-					 | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals;
-
-	const aiScene* scene = m_importer.ReadFile(m_inputFilename, flags | aiProcess_Triangulate);
-
-	if(!scene)
-	{
-		ERROR("%s", m_importer.GetErrorString());
-	}
-
-	m_scene = scene;
-
-	// Load without triangulation
-	m_importerNoTriangles.SetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE, smoothAngle);
-
-	scene = m_importerNoTriangles.ReadFile(m_inputFilename, flags);
-
-	if(!scene)
-	{
-		ERROR("%s", m_importerNoTriangles.GetErrorString());
-	}
-
-	m_sceneNoTriangles = scene;
-}
-
-void Exporter::visitNode(const aiNode* ainode)
-{
-	if(ainode == nullptr)
-	{
-		return;
-	}
-
-	// For every mesh of this node
-	for(unsigned i = 0; i < ainode->mNumMeshes; i++)
-	{
-		unsigned meshIndex = ainode->mMeshes[i];
-		unsigned mtlIndex = m_scene->mMeshes[meshIndex]->mMaterialIndex;
-
-		// Check properties
-		std::string lod1MeshName;
-		std::string collisionMesh;
-		bool special = false;
-		GiProbe giProbe;
-		bool isGiProbe = false;
-		ParticleEmitter particleEmitter;
-		bool isParticleEmitter = false;
-		for(const auto& prop : m_scene->mMeshes[meshIndex]->mProperties)
-		{
-			if(prop.first == "particles")
-			{
-				particleEmitter.m_filename = prop.second;
-				particleEmitter.m_transform = toAnkiMatrix(ainode->mTransformation);
-				special = true;
-				isParticleEmitter = true;
-			}
-			else if(prop.first == "gpu_particles" && prop.second == "true")
-			{
-				particleEmitter.m_gpu = true;
-			}
-			else if(prop.first == "collision" && prop.second == "true")
-			{
-				StaticCollisionNode n;
-				n.m_meshIndex = meshIndex;
-				n.m_transform = toAnkiMatrix(ainode->mTransformation);
-				m_staticCollisionNodes.push_back(n);
-				special = true;
-			}
-			else if(prop.first == "lod1")
-			{
-				lod1MeshName = prop.second;
-				special = false;
-			}
-			else if(prop.first == "reflection_probe" && prop.second == "true")
-			{
-				ReflectionProbe probe;
-				aiMatrix4x4 trf = toAnkiMatrix(ainode->mTransformation);
-				probe.m_position = aiVector3D(trf.a4, trf.b4, trf.c4);
-
-				aiVector3D scale(trf.a1, trf.b2, trf.c3);
-				assert(scale.x > 0.0f && scale.y > 0.0f && scale.z > 0.0f);
-
-				aiVector3D half = scale;
-				probe.m_aabbMin = probe.m_position - half - probe.m_position;
-				probe.m_aabbMax = probe.m_position + half - probe.m_position;
-
-				m_reflectionProbes.push_back(probe);
-
-				special = true;
-			}
-			else if(prop.first == "gi_probe" && prop.second == "true")
-			{
-				GiProbe& probe = giProbe;
-				aiMatrix4x4 trf = toAnkiMatrix(ainode->mTransformation);
-				probe.m_position = aiVector3D(trf.a4, trf.b4, trf.c4);
-
-				aiVector3D scale(trf.a1, trf.b2, trf.c3);
-				assert(scale.x > 0.0f && scale.y > 0.0f && scale.z > 0.0f);
-
-				aiVector3D half = scale;
-				probe.m_aabbMin = probe.m_position - half - probe.m_position;
-				probe.m_aabbMax = probe.m_position + half - probe.m_position;
-
-				isGiProbe = true;
-				special = true;
-			}
-			else if(prop.first == "gi_probe_fade_distance")
-			{
-				giProbe.m_fadeDistance = std::strtof(prop.second.c_str(), nullptr);
-			}
-			else if(prop.first == "gi_probe_cell_size")
-			{
-				giProbe.m_cellSize = std::strtof(prop.second.c_str(), nullptr);
-			}
-			else if(prop.first == "reflection_proxy" && prop.second == "true")
-			{
-				ReflectionProxy proxy;
-
-				// Find proxy in the other scene
-				proxy.m_meshIndex = 0xFFFFFFFF;
-				for(unsigned i = 0; i < m_sceneNoTriangles->mNumMeshes; ++i)
-				{
-					if(m_sceneNoTriangles->mMeshes[i]->mName == m_scene->mMeshes[meshIndex]->mName)
-					{
-						// Found
-						proxy.m_meshIndex = i;
-						break;
-					}
-				}
-
-				if(proxy.m_meshIndex == 0xFFFFFFFF)
-				{
-					ERROR("Reflection proxy mesh not found");
-				}
-
-				proxy.m_transform = toAnkiMatrix(ainode->mTransformation);
-				m_reflectionProxies.push_back(proxy);
-
-				special = true;
-			}
-			else if(prop.first == "occluder" && prop.second == "true")
-			{
-				OccluderNode occluder;
-
-				occluder.m_meshIndex = meshIndex;
-				occluder.m_transform = toAnkiMatrix(ainode->mTransformation);
-				m_occluders.push_back(occluder);
-
-				special = true;
-			}
-			else if(prop.first == "collision_mesh")
-			{
-				collisionMesh = prop.second;
-				special = false;
-			}
-			else if(prop.first.find("decal_") == 0)
-			{
-				DecalNode decal;
-				for(const auto& pr : m_scene->mMeshes[meshIndex]->mProperties)
-				{
-					if(pr.first == "decal_diffuse_atlas")
-					{
-						decal.m_diffuseTextureAtlasFilename = pr.second;
-					}
-					else if(pr.first == "decal_diffuse_sub_texture")
-					{
-						decal.m_diffuseSubTextureName = pr.second;
-					}
-					else if(pr.first == "decal_diffuse_factor")
-					{
-						decal.m_factors[0] = std::stof(pr.second);
-					}
-					else if(pr.first == "decal_normal_roughness_atlas")
-					{
-						decal.m_specularRoughnessAtlasFilename = pr.second;
-					}
-					else if(pr.first == "decal_normal_roughness_sub_texture")
-					{
-						decal.m_specularRoughnessSubTextureName = pr.second;
-					}
-					else if(pr.first == "decal_normal_roughness_factor")
-					{
-						decal.m_factors[1] = std::stof(pr.second);
-					}
-				}
-
-				if(decal.m_diffuseTextureAtlasFilename.empty() || decal.m_diffuseSubTextureName.empty())
-				{
-					ERROR("Missing decal information");
-				}
-
-				aiMatrix4x4 trf = toAnkiMatrix(ainode->mTransformation);
-				decal.m_size = getNonUniformScale(trf);
-				removeScale(trf);
-				decal.m_transform = trf;
-
-				m_decals.push_back(decal);
-				special = true;
-				break;
-			}
-		}
-
-		if(isGiProbe)
-		{
-			m_giProbes.push_back(giProbe);
-		}
-
-		if(isParticleEmitter)
-		{
-			m_particleEmitters.push_back(particleEmitter);
-		}
-
-		if(special)
-		{
-			continue;
-		}
-
-		// Create new model
-		Model mdl;
-		mdl.m_meshIndex = meshIndex;
-		mdl.m_materialIndex = mtlIndex;
-		mdl.m_lod1MeshName = lod1MeshName;
-		m_models.push_back(mdl);
-
-		// Create new node
-		Node node;
-		node.m_modelIndex = uint32_t(m_models.size() - 1);
-		node.m_transform = toAnkiMatrix(ainode->mTransformation);
-		node.m_group = ainode->mGroup.C_Str();
-		node.m_collisionMesh = collisionMesh;
-		m_nodes.push_back(node);
-	}
-
-	// Go to children
-	for(uint32_t i = 0; i < ainode->mNumChildren; i++)
-	{
-		visitNode(ainode->mChildren[i]);
-	}
-}
-
-void Exporter::exportCollisionMesh(uint32_t meshIdx)
-{
-	std::string name = getMeshName(getMeshAt(meshIdx));
-
-	std::fstream file;
-	file.open(m_outputDirectory + name + ".ankicl", std::ios::out);
-
-	file << XML_HEADER << '\n';
-
-	// Write collision mesh
-	file << "<collisionShape>\n\t<type>staticMesh</type>\n\t<value>" << m_rpath << name
-		 << ".ankimesh</value>\n</collisionShape>\n";
-}
-
-void Exporter::exportAll()
-{
-	LOGI("Exporting scene to %s", &m_outputDirectory[0]);
-
-	//
-	// Open scene file
-	//
-	m_sceneFile.open(m_outputDirectory + "scene.lua");
-	std::ofstream& file = m_sceneFile;
-
-	file << "local scene = getSceneGraph()\n"
-		 << "local events = getEventManager()\n"
-		 << "local rot\n"
-		 << "local node\n"
-		 << "local inst\n"
-		 << "local lcomp\n";
-
-	//
-	// Get all node/model data
-	//
-	visitNode(m_scene->mRootNode);
-
-	//
-	// Export collision meshes
-	//
-	for(auto n : m_staticCollisionNodes)
-	{
-		exportMesh(*m_scene->mMeshes[n.m_meshIndex], nullptr, 3);
-		exportCollisionMesh(n.m_meshIndex);
-
-		file << "\n";
-		writeTransform(n.m_transform);
-
-		std::string name = getMeshName(getMeshAt(n.m_meshIndex));
-		std::string fname = m_rpath + name + ".ankicl";
-		file << "node = scene:newStaticCollisionNode(\"" << name << "\", \"" << fname << "\", trf)\n";
-	}
-
-	//
-	// Export particle emitters
-	//
-	int i = 0;
-	for(const ParticleEmitter& p : m_particleEmitters)
-	{
-		std::string name = "particles" + std::to_string(i);
-		file << "\nnode = scene:new" << (p.m_gpu ? "Gpu" : "") << "ParticleEmitterNode(\"" << name << "\", \""
-			 << p.m_filename << "\")\n";
-
-		writeNodeTransform("node", p.m_transform);
-		++i;
-	}
-
-	//
-	// Export refl probes
-	//
-	i = 0;
-	for(const ReflectionProbe& probe : m_reflectionProbes)
-	{
-		std::string name = "reflprobe" + std::to_string(i);
-		file << "\nnode = scene:newReflectionProbeNode(\"" << name << "\", Vec4.new(" << probe.m_aabbMin.x << ", "
-			 << probe.m_aabbMin.y << ", " << probe.m_aabbMin.z << ", 0), Vec4.new(" << probe.m_aabbMax.x << ", "
-			 << probe.m_aabbMax.y << ", " << probe.m_aabbMax.z << ", 0))\n";
-
-		aiMatrix4x4 trf;
-		aiMatrix4x4::Translation(probe.m_position, trf);
-
-		writeNodeTransform("node", trf);
-		++i;
-	}
-
-	//
-	// Export GI probes
-	//
-	i = 0;
-	for(const GiProbe& probe : m_giProbes)
-	{
-		std::string name = "giprobe" + std::to_string(i);
-		file << "\nnode = scene:newGlobalIlluminationProbeNode(\"" << name << "\")\n";
-
-		file << "comp = node:getSceneNodeBase():getGlobalIlluminationProbeComponent()\n";
-		file << "comp:setBoundingBox(Vec4.new(" << probe.m_aabbMin.x << ", " << probe.m_aabbMin.y << ", "
-			 << probe.m_aabbMin.z << ", 0), Vec4.new(" << probe.m_aabbMax.x << ", " << probe.m_aabbMax.y << ", "
-			 << probe.m_aabbMax.z << ", 0))\n";
-
-		if(probe.m_fadeDistance >= 0.0f)
-		{
-			file << "comp:setFadeDistance(" << probe.m_fadeDistance << ")\n";
-		}
-
-		if(probe.m_cellSize > 0.0f)
-		{
-			file << "comp:setCellSize(" << probe.m_cellSize << ")\n";
-		}
-
-		aiMatrix4x4 trf;
-		aiMatrix4x4::Translation(probe.m_position, trf);
-		writeNodeTransform("node", trf);
-		++i;
-	}
-
-	//
-	// Export proxies
-	//
-	i = 0;
-	for(const ReflectionProxy& proxy : m_reflectionProxies)
-	{
-		const aiMesh& mesh = *m_sceneNoTriangles->mMeshes[proxy.m_meshIndex];
-		exportMesh(mesh, nullptr, 4);
-
-		std::string name = "reflproxy" + std::to_string(i);
-		file << "\nnode = scene:newReflectionProxyNode(\"" << name << "\", \"" << m_rpath << mesh.mName.C_Str()
-			 << ".ankimesh\")\n";
-
-		writeNodeTransform("node", proxy.m_transform);
-		++i;
-	}
-
-	//
-	// Export occluders
-	//
-	i = 0;
-	for(const OccluderNode& occluder : m_occluders)
-	{
-		const aiMesh& mesh = *m_scene->mMeshes[occluder.m_meshIndex];
-		exportMesh(mesh, nullptr, 3);
-
-		std::string name = "occluder" + std::to_string(i);
-		file << "\nnode = scene:newOccluderNode(\"" << name << "\", \"" << m_rpath << mesh.mName.C_Str()
-			 << ".ankimesh\")\n";
-
-		writeNodeTransform("node", occluder.m_transform);
-		++i;
-	}
-
-	//
-	// Export decals
-	//
-	i = 0;
-	for(const DecalNode& decal : m_decals)
-	{
-		std::string name = "decal" + std::to_string(i);
-		file << "\nnode = scene:newDecalNode(\"" << name << "\")\n";
-
-		writeNodeTransform("node", decal.m_transform);
-
-		file << "decalc = node:getSceneNodeBase():getDecalComponent()\n";
-		file << "decalc:setDiffuseDecal(\"" << decal.m_diffuseTextureAtlasFilename << "\", \""
-			 << decal.m_diffuseSubTextureName << "\", " << decal.m_factors[0] << ")\n";
-		file << "decalc:updateShape(" << decal.m_size.x << ", " << decal.m_size.y << ", " << decal.m_size.z << ")\n";
-
-		if(!decal.m_specularRoughnessAtlasFilename.empty())
-		{
-			file << "decalc:setSpecularRoughnessDecal(\"" << decal.m_specularRoughnessAtlasFilename << "\", \""
-				 << decal.m_specularRoughnessSubTextureName << "\", " << decal.m_factors[1] << ")\n";
-		}
-
-		++i;
-	}
-
-	//
-	// Export nodes and models.
-	//
-	for(uint32_t i = 0; i < m_nodes.size(); i++)
-	{
-		Node& node = m_nodes[i];
-		Model& model = m_models[node.m_modelIndex];
-
-		// TODO If static bake transform
-		exportMesh(*m_scene->mMeshes[model.m_meshIndex], nullptr, 3);
-
-		exportMaterial(*m_scene->mMaterials[model.m_materialIndex]);
-
-		exportModel(model);
-		std::string modelName = getModelName(model);
-		std::string nodeName = modelName + node.m_group + std::to_string(i);
-
-		// Write the main node
-		file << "\nnode = scene:newModelNode(\"" << nodeName << "\", \"" << m_rpath << modelName << ".ankimdl\")\n";
-		writeNodeTransform("node", node.m_transform);
-
-		// Write the collision node
-		if(!node.m_collisionMesh.empty())
-		{
-			unsigned i = 0;
-			if(node.m_collisionMesh == "self")
-			{
-				i = model.m_meshIndex;
-			}
-			else
-			{
-				for(; i < m_scene->mNumMeshes; i++)
-				{
-					if(m_scene->mMeshes[i]->mName.C_Str() == node.m_collisionMesh)
-					{
-						break;
-					}
-				}
-			}
-
-			const bool found = i < m_scene->mNumMeshes;
-			if(found)
-			{
-				exportCollisionMesh(i);
-
-				std::string fname = m_rpath + getMeshName(getMeshAt(i)) + ".ankicl";
-				file << "node = scene:newStaticCollisionNode(\"" << nodeName << "_cl\", \"" << fname << "\", trf)\n";
-			}
-			else
-			{
-				ERROR("Couldn't find the collision_mesh %s", node.m_collisionMesh.c_str());
-			}
-		}
-	}
-
-	//
-	// Lights
-	//
-	for(unsigned i = 0; i < m_scene->mNumLights; i++)
-	{
-		exportLight(*m_scene->mLights[i]);
-	}
-
-	//
-	// Animations
-	//
-	for(unsigned i = 0; i < m_scene->mNumAnimations; i++)
-	{
-		exportAnimation(*m_scene->mAnimations[i], i);
-	}
-
-	//
-	// Cameras
-	//
-	for(unsigned i = 0; i < m_scene->mNumCameras; i++)
-	{
-		exportCamera(*m_scene->mCameras[i]);
-	}
-
-	LOGI("Done exporting scene!");
-}

+ 0 - 199
tools/scene/Exporter.h

@@ -1,199 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#ifndef ANKI_TOOLS_SCENE_EXPORTER_H
-#define ANKI_TOOLS_SCENE_EXPORTER_H
-
-#include <string>
-#include <array>
-#include <cstdint>
-#include <fstream>
-#include <vector>
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
-#include <assimp/postprocess.h>
-#pragma GCC diagnostic pop
-
-#include "Common.h"
-
-const uint32_t INVALID_INDEX = 0xFFFFFFFF;
-
-/// Thin mesh wrapper
-struct Model
-{
-	uint32_t m_meshIndex = INVALID_INDEX; ///< Mesh index in the scene
-	uint32_t m_materialIndex = INVALID_INDEX;
-	std::string m_lod1MeshName;
-};
-
-/// Scene node.
-struct Node
-{
-	uint32_t m_modelIndex; ///< Index inside Exporter::m_models
-	aiMatrix4x4 m_transform;
-	std::string m_group;
-	std::string m_collisionMesh;
-};
-
-const uint32_t MAX_BONES_PER_VERTEX = 4;
-
-/// Bone/weight info for a single vertex
-struct VertexWeight
-{
-	std::array<uint32_t, MAX_BONES_PER_VERTEX> m_boneIndices;
-	std::array<float, MAX_BONES_PER_VERTEX> m_weigths;
-	uint32_t m_bonesCount;
-};
-
-class ParticleEmitter
-{
-public:
-	std::string m_filename;
-	aiMatrix4x4 m_transform;
-	bool m_gpu = false;
-};
-
-class StaticCollisionNode
-{
-public:
-	uint32_t m_meshIndex;
-	aiMatrix4x4 m_transform;
-};
-
-class ReflectionProbe
-{
-public:
-	aiVector3D m_position;
-	aiVector3D m_aabbMin;
-	aiVector3D m_aabbMax;
-};
-
-class GiProbe
-{
-public:
-	aiVector3D m_position;
-	aiVector3D m_aabbMin;
-	aiVector3D m_aabbMax;
-	float m_fadeDistance = -1.0f;
-	float m_cellSize = -1.0f;
-};
-
-class ReflectionProxy
-{
-public:
-	aiMatrix4x4 m_transform;
-	uint32_t m_meshIndex; ///< Points to the scene that is not triangulated.
-};
-
-class OccluderNode
-{
-public:
-	aiMatrix4x4 m_transform;
-	uint32_t m_meshIndex; ///< Points to the scene that is not triangulated.
-};
-
-class DecalNode
-{
-public:
-	aiMatrix4x4 m_transform;
-	std::string m_diffuseTextureAtlasFilename;
-	std::string m_diffuseSubTextureName;
-	std::string m_specularRoughnessAtlasFilename;
-	std::string m_specularRoughnessSubTextureName;
-	aiVector3D m_size;
-	std::array<float, 2> m_factors = {{1.0, 1.0}};
-};
-
-/// AnKi exporter.
-class Exporter
-{
-public:
-	std::string m_inputFilename;
-	std::string m_outputDirectory;
-	std::string m_rpath;
-	std::string m_texrpath;
-
-	bool m_flipyz = false;
-
-	const aiScene* m_scene = nullptr;
-	const aiScene* m_sceneNoTriangles = nullptr;
-	Assimp::Importer m_importer;
-	Assimp::Importer m_importerNoTriangles;
-
-	std::vector<Model> m_models;
-	std::vector<Node> m_nodes;
-
-	std::ofstream m_sceneFile;
-
-	std::vector<StaticCollisionNode> m_staticCollisionNodes;
-	std::vector<ParticleEmitter> m_particleEmitters;
-	std::vector<ReflectionProbe> m_reflectionProbes;
-	std::vector<GiProbe> m_giProbes;
-	std::vector<ReflectionProxy> m_reflectionProxies;
-	std::vector<OccluderNode> m_occluders;
-	std::vector<DecalNode> m_decals;
-
-	/// Load the scene.
-	void load();
-
-	/// Export.
-	void exportAll();
-
-private:
-	/// @name Helpers
-	/// @{
-
-	/// Convert one 4x4 matrix to AnKi friendly matrix.
-	aiMatrix4x4 toAnkiMatrix(const aiMatrix4x4& in) const;
-
-	/// Convert one 3x3 matrix to AnKi friendly matrix.
-	aiMatrix3x3 toAnkiMatrix(const aiMatrix3x3& in) const;
-
-	void writeTransform(const aiMatrix4x4& mat);
-
-	/// Write transformation of a node
-	void writeNodeTransform(const std::string& node, const aiMatrix4x4& mat);
-
-	const aiMesh& getMeshAt(unsigned index) const;
-	const aiMaterial& getMaterialAt(unsigned index) const;
-	std::string getModelName(const Model& model) const;
-
-	/// Visits the node hierarchy and gathers models and nodes.
-	void visitNode(const aiNode* ainode);
-	/// @}
-
-	/// Export a mesh.
-	/// @param transform If not nullptr then transform the vertices using that.
-	void exportMesh(const aiMesh& mesh, const aiMatrix4x4* transform, unsigned vertCountPerFace) const;
-
-	/// Export a skeleton.
-	void exportSkeleton(const aiMesh& mesh) const;
-
-	/// Export a material.
-	void exportMaterial(const aiMaterial& mtl) const;
-
-	/// Export a model.
-	void exportModel(const Model& model) const;
-
-	/// Export a light.
-	void exportLight(const aiLight& light);
-
-	/// Export a camera.
-	void exportCamera(const aiCamera& cam);
-
-	/// Export an animation.
-	void exportAnimation(const aiAnimation& anim, unsigned index);
-
-	/// Export a static collision mesh.
-	void exportCollisionMesh(uint32_t meshIdx);
-
-	/// Helper.
-	static std::string getMaterialName(const aiMaterial& mtl);
-};
-
-#endif

+ 0 - 278
tools/scene/ExporterMaterial.cpp

@@ -1,278 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "Exporter.h"
-#include <iostream>
-
-const char* MATERIAL_TEMPLATE = R"(<?xml version="1.0" encoding="UTF-8" ?>
-<!-- This file is auto generated by ExporterMaterial.cpp -->
-<material shaderProgram="shaders/GBufferGeneric.glslp">
-
-	<mutators>
-		<mutator name="DIFFUSE_TEX" value="%diffTexMutator%"/>
-		<mutator name="SPECULAR_TEX" value="%specTexMutator%"/>
-		<mutator name="ROUGHNESS_TEX" value="%roughnessTexMutator%"/>
-		<mutator name="METAL_TEX" value="%metalTexMutator%"/>
-		<mutator name="NORMAL_TEX" value="%normalTexMutator%"/>
-		<mutator name="PARALLAX" value="%parallaxMutator%"/>
-		<mutator name="EMISSIVE_TEX" value="%emissiveTexMutator%"/>
-	</mutators>
-
-	<inputs>
-		<input shaderInput="mvp" builtin="MODEL_VIEW_PROJECTION_MATRIX"/>
-		<input shaderInput="prevMvp" builtin="PREVIOUS_MODEL_VIEW_PROJECTION_MATRIX"/>
-		<input shaderInput="rotationMat" builtin="ROTATION_MATRIX"/>
-		<input shaderInput="globalSampler" builtin="GLOBAL_SAMPLER"/>
-		%parallaxInput%
-
-		%diff%
-		%spec%
-		%roughness%
-		%metallic%
-		%normal%
-		%emission%
-		%subsurface%
-		%height%
-	</inputs>
-</material>
-)";
-
-void Exporter::exportMaterial(const aiMaterial& mtl) const
-{
-	aiString path;
-
-	std::string name = getMaterialName(mtl);
-	LOGI("Exporting material %s", name.c_str());
-
-	std::string xml = MATERIAL_TEMPLATE;
-
-	// Diffuse texture
-	if(mtl.GetTextureCount(aiTextureType_DIFFUSE) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS)
-		{
-			std::string diffTex = m_texrpath + getFilename(path.C_Str());
-			xml = replaceAllString(xml, "%diff%", "<input shaderInput=\"diffTex\" value=\"" + diffTex + "\"/>");
-			xml = replaceAllString(xml, "%diffTexMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		aiColor3D diffCol = {0.0, 0.0, 0.0};
-		mtl.Get(AI_MATKEY_COLOR_DIFFUSE, diffCol);
-
-		xml = replaceAllString(xml,
-			"%diff%",
-			"<input shaderInput=\"diffColor\" value=\"" + std::to_string(diffCol[0]) + " " + std::to_string(diffCol[1])
-				+ " " + std::to_string(diffCol[2]) + "\"/>");
-
-		xml = replaceAllString(xml, "%diffTexMutator%", "0");
-	}
-
-	// Specular color
-	if(mtl.GetTextureCount(aiTextureType_SPECULAR) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_SPECULAR, 0, &path) == AI_SUCCESS)
-		{
-			std::string specTex = m_texrpath + getFilename(path.C_Str());
-			xml = replaceAllString(xml, "%spec%", "<input shaderInput=\"specTex\" value=\"" + specTex + "\"/>");
-			xml = replaceAllString(xml, "%specTexMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		aiColor3D specCol = {0.0, 0.0, 0.0};
-		mtl.Get(AI_MATKEY_COLOR_SPECULAR, specCol);
-
-		xml = replaceAllString(xml,
-			"%spec%",
-			"<input shaderInput=\"specColor\" value=\"" + std::to_string(specCol[0]) + " " + std::to_string(specCol[1])
-				+ " " + std::to_string(specCol[2]) + "\"/>");
-
-		xml = replaceAllString(xml, "%specTexMutator%", "0");
-	}
-
-	// Roughness
-	if(mtl.GetTextureCount(aiTextureType_SHININESS) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_SHININESS, 0, &path) == AI_SUCCESS)
-		{
-			std::string shininessTex = m_texrpath + getFilename(path.C_Str());
-			xml = replaceAllString(
-				xml, "%roughness%", "<input shaderInput=\"roughnessTex\" value=\"" + shininessTex + "\"/>");
-
-			xml = replaceAllString(xml, "%roughnessTexMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		float roughness = 0.0;
-		if(mtl.mAnKiProperties.find("roughness") != mtl.mAnKiProperties.end())
-		{
-			roughness = std::stof(mtl.mAnKiProperties.at("roughness"));
-		}
-		else
-		{
-			mtl.Get(AI_MATKEY_SHININESS, roughness);
-			const float MAX_SHININESS = 511.0;
-			roughness = std::min(MAX_SHININESS, roughness);
-			if(roughness > MAX_SHININESS)
-			{
-				LOGW("Shininness exceeds %f", MAX_SHININESS);
-			}
-
-			roughness = roughness / MAX_SHININESS;
-		}
-
-		xml = replaceAllString(
-			xml, "%roughness%", "<input shaderInput=\"roughness\" value=\"" + std::to_string(roughness) + "\" />");
-
-		xml = replaceAllString(xml, "%roughnessTexMutator%", "0");
-	}
-
-	// Metallic texture
-	if(mtl.GetTextureCount(aiTextureType_REFLECTION) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_REFLECTION, 0, &path) == AI_SUCCESS)
-		{
-			std::string metallicTex = m_texrpath + getFilename(path.C_Str());
-			xml =
-				replaceAllString(xml, "%metallic%", "<input shaderInput=\"metalTex\" value=\"" + metallicTex + "\"/>");
-
-			xml = replaceAllString(xml, "%metalTexMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		float metallic = 0.0;
-		if(mtl.mAnKiProperties.find("metallic") != mtl.mAnKiProperties.end())
-		{
-			metallic = std::stof(mtl.mAnKiProperties.at("metallic"));
-		}
-
-		xml = replaceAllString(
-			xml, "%metallic%", "<input shaderInput=\"metallic\" value=\"" + std::to_string(metallic) + "\"/>");
-
-		xml = replaceAllString(xml, "%metalTexMutator%", "0");
-	}
-
-	// Normal texture
-	if(mtl.GetTextureCount(aiTextureType_NORMALS) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_NORMALS, 0, &path) == AI_SUCCESS)
-		{
-			std::string normTex = m_texrpath + getFilename(path.C_Str());
-			xml = replaceAllString(xml, "%normal%", "<input shaderInput=\"normalTex\" value=\"" + normTex + "\"/>");
-
-			xml = replaceAllString(xml, "%normalTexMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		xml = replaceAllString(xml, "%normal%", "");
-		xml = replaceAllString(xml, "%normalTexMutator%", "0");
-	}
-
-	// Emissive texture
-	if(mtl.GetTextureCount(aiTextureType_EMISSIVE) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_EMISSIVE, 0, &path) == AI_SUCCESS)
-		{
-			std::string emissiveTex = m_texrpath + getFilename(path.C_Str());
-			xml = replaceAllString(
-				xml, "%emission%", "<input shaderInput=\"emissiveTex\" value=\"" + emissiveTex + "\"/>");
-
-			xml = replaceAllString(xml, "%emissiveTexMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		aiColor3D emissionCol = {0.0, 0.0, 0.0};
-		mtl.Get(AI_MATKEY_COLOR_EMISSIVE, emissionCol);
-
-		xml = replaceAllString(xml,
-			"%emission%",
-			"<input shaderInput=\"emission\" value=\"" + std::to_string(emissionCol[0]) + " "
-				+ std::to_string(emissionCol[1]) + " " + std::to_string(emissionCol[2]) + "\"/>");
-
-		xml = replaceAllString(xml, "%emissiveTexMutator%", "0");
-	}
-
-	// Subsurface
-	{
-		float subsurface = 0.0;
-		if(mtl.mAnKiProperties.find("subsurface") != mtl.mAnKiProperties.end())
-		{
-			subsurface = std::stof(mtl.mAnKiProperties.at("subsurface"));
-		}
-
-		xml = replaceAllString(
-			xml, "%subsurface%", "<input shaderInput=\"subsurface\" value=\"" + std::to_string(subsurface) + "\"/>");
-	}
-
-	// Height texture
-	if(mtl.GetTextureCount(aiTextureType_DISPLACEMENT) > 0)
-	{
-		if(mtl.GetTexture(aiTextureType_DISPLACEMENT, 0, &path) == AI_SUCCESS)
-		{
-			std::string dispTex = m_texrpath + getFilename(path.C_Str());
-			xml = replaceAllString(xml,
-				"%height%",
-				"<input shaderInput=\"heightTex\" value=\"" + dispTex
-					+ "\"/>\n"
-					  "\t\t<input shaderInput=\"heightMapScale\" value=\"0.05\"/>");
-
-			xml = replaceAllString(
-				xml, "%parallaxInput%", "<input shaderInput=\"modelViewMat\" builtin=\"MODEL_VIEW_MATRIX\"/>");
-
-			xml = replaceAllString(xml, "%parallaxMutator%", "1");
-		}
-		else
-		{
-			ERROR("Failed to retrieve texture");
-		}
-	}
-	else
-	{
-		xml = replaceAllString(xml, "%height%", "");
-		xml = replaceAllString(xml, "%parallaxInput%", "");
-		xml = replaceAllString(xml, "%parallaxMutator%", "0");
-	}
-
-	// Replace texture extensions with .anki
-	xml = replaceAllString(xml, ".tga", ".ankitex");
-	xml = replaceAllString(xml, ".png", ".ankitex");
-	xml = replaceAllString(xml, ".jpg", ".ankitex");
-	xml = replaceAllString(xml, ".jpeg", ".ankitex");
-
-	// Open and write file
-	std::fstream file;
-	file.open(m_outputDirectory + name + ".ankimtl", std::ios::out);
-	file << xml;
-}

+ 0 - 449
tools/scene/ExporterMesh.cpp

@@ -1,449 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "Exporter.h"
-#include <anki/resource/MeshLoader.h>
-#include <anki/Collision.h>
-#include <anki/Math.h>
-#include <cmath>
-#include <cfloat>
-
-using namespace anki;
-
-void Exporter::exportMesh(const aiMesh& mesh, const aiMatrix4x4* transform, unsigned vertCountPerFace) const
-{
-	std::string name = mesh.mName.C_Str();
-	LOGI("Exporting mesh %s", name.c_str());
-
-	const bool hasBoneWeights = mesh.mNumBones > 0;
-
-	MeshBinaryFile::Header header;
-	memset(&header, 0, sizeof(header));
-
-	// Checks
-	if(mesh.mNumFaces == 0)
-	{
-		ERROR("Incorrect face number");
-	}
-
-	if(mesh.mVertices == 0)
-	{
-		ERROR("Incorrect vertex count number");
-	}
-
-	if(!mesh.HasPositions())
-	{
-		ERROR("Missing positions");
-	}
-
-	if(!mesh.HasNormals())
-	{
-		ERROR("Missing normals");
-	}
-
-	if(!mesh.HasTangentsAndBitangents())
-	{
-		ERROR("Missing tangents");
-	}
-
-	if(!mesh.HasTextureCoords(0))
-	{
-		ERROR("Missing UVs");
-	}
-
-	//
-	// Gather the attributes
-	//
-	struct WeightVertex
-	{
-		uint16_t m_boneIndices[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-		uint8_t m_weights[4] = {0, 0, 0, 0};
-	};
-	std::vector<WeightVertex> bweights;
-
-	std::vector<float> positions;
-
-	struct NTVertex
-	{
-		float m_n[3];
-		float m_t[4];
-		float m_uv[2];
-	};
-
-	std::vector<NTVertex> ntVerts;
-
-	float maxPositionDistance = 0.0; // Distance of positions from zero
-	float maxUvDistance = -FLT_MAX, minUvDistance = FLT_MAX;
-	Vec3 aabbMin(MAX_F32), aabbMax(MIN_F32);
-
-	{
-		const aiMatrix3x3 normalMat = (transform) ? aiMatrix3x3(*transform) : aiMatrix3x3();
-
-		const unsigned vertCount = mesh.mNumVertices;
-
-		positions.resize(vertCount * 3);
-		ntVerts.resize(vertCount);
-
-		for(unsigned i = 0; i < vertCount; i++)
-		{
-			aiVector3D pos = mesh.mVertices[i];
-			aiVector3D n = mesh.mNormals[i];
-			aiVector3D t = mesh.mTangents[i];
-			aiVector3D b = mesh.mBitangents[i];
-			const aiVector3D& uv = mesh.mTextureCoords[0][i];
-
-			if(transform)
-			{
-				pos = (*transform) * pos;
-				n = normalMat * n;
-				t = normalMat * t;
-				b = normalMat * b;
-			}
-
-			if(m_flipyz)
-			{
-				static const aiMatrix4x4 toLefthanded(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);
-
-				pos = toLefthanded * pos;
-				n = toLefthanded * n;
-				t = toLefthanded * t;
-				b = toLefthanded * b;
-			}
-
-			positions[i * 3 + 0] = pos.x;
-			positions[i * 3 + 1] = pos.y;
-			positions[i * 3 + 2] = pos.z;
-			for(int d = 0; d < 3; ++d)
-			{
-				maxPositionDistance = std::max<float>(maxPositionDistance, fabs(pos[d]));
-				aabbMin[d] = std::min(aabbMin[d], pos[d]);
-				aabbMax[d] = std::max(aabbMax[d], pos[d]);
-			}
-
-			ntVerts[i].m_n[0] = n.x;
-			ntVerts[i].m_n[1] = n.y;
-			ntVerts[i].m_n[2] = n.z;
-
-			ntVerts[i].m_t[0] = t.x;
-			ntVerts[i].m_t[1] = t.y;
-			ntVerts[i].m_t[2] = t.z;
-			ntVerts[i].m_t[3] = ((n ^ t) * b < 0.0) ? 1.0 : -1.0;
-
-			ntVerts[i].m_uv[0] = uv.x;
-			ntVerts[i].m_uv[1] = uv.y;
-			maxUvDistance = std::max(maxUvDistance, std::max(uv.x, uv.y));
-			minUvDistance = std::min(minUvDistance, std::min(uv.x, uv.y));
-		}
-
-		if(hasBoneWeights)
-		{
-			bweights.resize(vertCount);
-
-			for(unsigned i = 0; i < mesh.mNumBones; ++i)
-			{
-				const aiBone& bone = *mesh.mBones[i];
-				for(unsigned j = 0; j < bone.mNumWeights; ++j)
-				{
-					const aiVertexWeight& aiWeight = bone.mWeights[j];
-					assert(aiWeight.mVertexId < bweights.size());
-
-					WeightVertex& vert = bweights[aiWeight.mVertexId];
-
-					unsigned idx;
-					if(vert.m_boneIndices[0] == 0xFFFF)
-					{
-						idx = 0;
-					}
-					else if(vert.m_boneIndices[1] == 0xFFFF)
-					{
-						idx = 1;
-					}
-					else if(vert.m_boneIndices[2] == 0xFFFF)
-					{
-						idx = 2;
-					}
-					else if(vert.m_boneIndices[3] == 0xFFFF)
-					{
-						idx = 3;
-					}
-					else
-					{
-						ERROR("Vertex has more than 4 bone weights");
-					}
-
-					vert.m_boneIndices[idx] = uint16_t(i);
-					vert.m_weights[idx] = uint8_t(aiWeight.mWeight * 0xFF);
-				}
-			}
-		}
-
-		// Bump aabbMax a bit
-		aabbMax += EPSILON * 10.0f;
-	}
-
-	// Chose the formats of the attributes
-	{
-		// Positions
-		auto& posa = header.m_vertexAttributes[VertexAttributeLocation::POSITION];
-		posa.m_bufferBinding = 0;
-		posa.m_format = (maxPositionDistance < 2.0) ? Format::R16G16B16A16_SFLOAT : Format::R32G32B32_SFLOAT;
-		posa.m_relativeOffset = 0;
-		posa.m_scale = 1.0;
-
-		// Normals
-		auto& na = header.m_vertexAttributes[VertexAttributeLocation::NORMAL];
-		na.m_bufferBinding = 1;
-		na.m_format = Format::A2B10G10R10_SNORM_PACK32;
-		na.m_relativeOffset = 0;
-		na.m_scale = 1.0;
-
-		// Tangents
-		auto& ta = header.m_vertexAttributes[VertexAttributeLocation::TANGENT];
-		ta.m_bufferBinding = 1;
-		ta.m_format = Format::A2B10G10R10_SNORM_PACK32;
-		ta.m_relativeOffset = sizeof(uint32_t);
-		ta.m_scale = 1.0;
-
-		// UVs
-		auto& uva = header.m_vertexAttributes[VertexAttributeLocation::UV];
-		uva.m_bufferBinding = 1;
-		if(minUvDistance >= 0.0 && maxUvDistance <= 1.0)
-		{
-			uva.m_format = Format::R16G16_UNORM;
-		}
-		else
-		{
-			uva.m_format = Format::R16G16_SFLOAT;
-		}
-		uva.m_relativeOffset = sizeof(uint32_t) * 2;
-		uva.m_scale = 1.0;
-
-		// Bone weight
-		if(hasBoneWeights)
-		{
-			auto& bidxa = header.m_vertexAttributes[VertexAttributeLocation::BONE_INDICES];
-			bidxa.m_bufferBinding = 2;
-			bidxa.m_format = Format::R16G16B16A16_UINT;
-			bidxa.m_relativeOffset = 0;
-			bidxa.m_scale = 1.0;
-
-			auto& wa = header.m_vertexAttributes[VertexAttributeLocation::BONE_WEIGHTS];
-			wa.m_bufferBinding = 2;
-			wa.m_format = Format::R8G8B8A8_UNORM;
-			wa.m_relativeOffset = sizeof(uint16_t) * 4;
-			wa.m_scale = 1.0;
-		}
-	}
-
-	// Arange the attributes into vert buffers
-	{
-		header.m_vertexBufferCount = 2;
-
-		// First buff has positions
-		const auto& posa = header.m_vertexAttributes[VertexAttributeLocation::POSITION];
-		if(posa.m_format == Format::R32G32B32_SFLOAT)
-		{
-			header.m_vertexBuffers[0].m_vertexStride = sizeof(float) * 3;
-		}
-		else if(posa.m_format == Format::R16G16B16A16_SFLOAT)
-		{
-			header.m_vertexBuffers[0].m_vertexStride = sizeof(uint16_t) * 4;
-		}
-		else
-		{
-			assert(0);
-		}
-
-		// 2nd buff has normal + tangent + texcoords
-		header.m_vertexBuffers[1].m_vertexStride = sizeof(uint32_t) * 2 + sizeof(uint16_t) * 2;
-
-		// 3rd has bone weights
-		if(hasBoneWeights)
-		{
-			header.m_vertexBuffers[2].m_vertexStride = sizeof(WeightVertex);
-			++header.m_vertexBufferCount;
-		}
-	}
-
-	// Find if it's a convex shape
-	Bool convex = true;
-	for(unsigned i = 0; i < mesh.mNumFaces && vertCountPerFace == 3; i++)
-	{
-		const aiFace& face = mesh.mFaces[i];
-
-		Vec3 triangle[3];
-
-		for(unsigned j = 0; j < 3; j++)
-		{
-			unsigned idx = face.mIndices[j];
-			triangle[j].x() = positions[idx * 3 + 0];
-			triangle[j].y() = positions[idx * 3 + 1];
-			triangle[j].z() = positions[idx * 3 + 2];
-		}
-
-		// Check that all positions are behind the plane
-		Plane plane(triangle[0].xyz0(), triangle[1].xyz0(), triangle[2].xyz0());
-
-		for(unsigned j = 0; j < positions.size(); j += 3)
-		{
-			Vec3 pos;
-			pos.x() = positions[j + 0];
-			pos.y() = positions[j + 1];
-			pos.z() = positions[j + 2];
-
-			F32 test = testPlane(plane, pos.xyz0());
-			if(test > EPSILON)
-			{
-				convex = false;
-				break;
-			}
-		}
-
-		if(convex == false)
-		{
-			break;
-		}
-	}
-
-	// Write some other header stuff
-	{
-		memcpy(&header.m_magic[0], MeshBinaryFile::MAGIC, 8);
-		header.m_flags = (vertCountPerFace == 4) ? MeshBinaryFile::Flag::QUAD : MeshBinaryFile::Flag::NONE;
-		if(convex)
-		{
-			header.m_flags |= MeshBinaryFile::Flag::CONVEX;
-		}
-		header.m_indexType = IndexType::U16;
-		header.m_totalIndexCount = mesh.mNumFaces * vertCountPerFace;
-		header.m_totalVertexCount = mesh.mNumVertices;
-		header.m_subMeshCount = 1;
-		header.m_aabbMin = aabbMin;
-		header.m_aabbMax = aabbMax;
-	}
-
-	// Open file
-	std::fstream file;
-	file.open(m_outputDirectory + name + ".ankimesh", std::ios::out | std::ios::binary);
-
-	// Write header
-	file.write(reinterpret_cast<char*>(&header), sizeof(header));
-
-	// Write sub meshes
-	{
-		MeshBinaryFile::SubMesh smesh;
-		smesh.m_firstIndex = 0;
-		smesh.m_indexCount = header.m_totalIndexCount;
-		smesh.m_aabbMin = aabbMin;
-		smesh.m_aabbMax = aabbMax;
-
-		file.write(reinterpret_cast<char*>(&smesh), sizeof(smesh));
-	}
-
-	// Write indices
-	for(unsigned i = 0; i < mesh.mNumFaces; i++)
-	{
-		const aiFace& face = mesh.mFaces[i];
-
-		if(face.mNumIndices != vertCountPerFace)
-		{
-			ERROR("For some reason assimp returned wrong number of verts for a face (face.mNumIndices=%d). Probably"
-				  "degenerates in input file",
-				face.mNumIndices);
-		}
-
-		for(unsigned j = 0; j < vertCountPerFace; j++)
-		{
-			uint32_t index32 = face.mIndices[j];
-			if(index32 > 0xFFFF)
-			{
-				ERROR("Index too big");
-			}
-
-			uint16_t index = uint16_t(index32);
-			file.write(reinterpret_cast<char*>(&index), sizeof(index));
-		}
-	}
-
-	// Write first vert buffer
-	{
-		const auto& posa = header.m_vertexAttributes[VertexAttributeLocation::POSITION];
-		if(posa.m_format == Format::R32G32B32_SFLOAT)
-		{
-			file.write(reinterpret_cast<char*>(&positions[0]), positions.size() * sizeof(positions[0]));
-		}
-		else if(posa.m_format == Format::R16G16B16A16_SFLOAT)
-		{
-			std::vector<uint16_t> pos16;
-			pos16.resize(mesh.mNumVertices * 4);
-
-			const float* p32 = &positions[0];
-			const float* p32end = p32 + positions.size();
-			uint16_t* p16 = &pos16[0];
-			while(p32 != p32end)
-			{
-				p16[0] = F16(p32[0]).toU16();
-				p16[1] = F16(p32[1]).toU16();
-				p16[2] = F16(p32[2]).toU16();
-				p16[3] = F16(0.0f).toU16();
-
-				p32 += 3;
-				p16 += 4;
-			}
-
-			file.write(reinterpret_cast<char*>(&pos16[0]), pos16.size() * sizeof(pos16[0]));
-		}
-		else
-		{
-			assert(0);
-		}
-	}
-
-	// Write 2nd vert buffer
-	{
-		struct Vert
-		{
-			uint32_t m_n;
-			uint32_t m_t;
-			uint16_t m_uv[2];
-		};
-
-		std::vector<Vert> verts;
-		verts.resize(mesh.mNumVertices);
-
-		for(unsigned i = 0; i < mesh.mNumVertices; ++i)
-		{
-			const auto& inVert = ntVerts[i];
-
-			verts[i].m_n = packColorToR10G10B10A2SNorm(inVert.m_n[0], inVert.m_n[1], inVert.m_n[2], 0.0);
-			verts[i].m_t = packColorToR10G10B10A2SNorm(inVert.m_t[0], inVert.m_t[1], inVert.m_t[2], inVert.m_t[3]);
-
-			const float uv[2] = {inVert.m_uv[0], inVert.m_uv[1]};
-			const Format uvfmt = header.m_vertexAttributes[VertexAttributeLocation::UV].m_format;
-			if(uvfmt == Format::R16G16_UNORM)
-			{
-				assert(uv[0] <= 1.0 && uv[0] >= 0.0 && uv[1] <= 1.0 && uv[1] >= 0.0);
-				verts[i].m_uv[0] = uint16_t(uv[0] * 0xFFFF);
-				verts[i].m_uv[1] = uint16_t(uv[1] * 0xFFFF);
-			}
-			else if(uvfmt == Format::R16G16_SFLOAT)
-			{
-				verts[i].m_uv[0] = F16(uv[0]).toU16();
-				verts[i].m_uv[1] = F16(uv[1]).toU16();
-			}
-			else
-			{
-				assert(0);
-			}
-		}
-
-		file.write(reinterpret_cast<char*>(&verts[0]), verts.size() * sizeof(verts[0]));
-	}
-
-	// Write 3rd vert buffer
-	if(hasBoneWeights)
-	{
-		file.write(reinterpret_cast<char*>(&bweights[0]), bweights.size() * sizeof(bweights[0]));
-	}
-}

+ 0 - 110
tools/scene/Main.cpp

@@ -1,110 +0,0 @@
-// Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#include "Exporter.h"
-
-static void parseCommandLineArgs(int argc, char** argv, Exporter& exporter)
-{
-	static const char* usage = R"(Usage: %s in_file out_dir [options]
-Options:
--rpath <string>     : Replace all absolute paths of assets with that path
--texrpath <string>  : Same as rpath but for textures
--flipyz             : Flip y with z (For blender exports)
-)";
-
-	bool rpathFound = false;
-	bool texrpathFound = false;
-
-	// Parse config
-	if(argc < 3)
-	{
-		goto error;
-	}
-
-	exporter.m_inputFilename = argv[1];
-	exporter.m_outputDirectory = argv[2] + std::string("/");
-
-	for(int i = 3; i < argc; i++)
-	{
-		if(strcmp(argv[i], "-texrpath") == 0)
-		{
-			texrpathFound = true;
-			++i;
-
-			if(i < argc)
-			{
-				if(std::strlen(argv[i]) > 0)
-				{
-					exporter.m_texrpath = argv[i] + std::string("/");
-				}
-			}
-			else
-			{
-				goto error;
-			}
-		}
-		else if(strcmp(argv[i], "-rpath") == 0)
-		{
-			rpathFound = true;
-			++i;
-
-			if(i < argc)
-			{
-				if(std::strlen(argv[i]) > 0)
-				{
-					exporter.m_rpath = argv[i] + std::string("/");
-				}
-			}
-			else
-			{
-				goto error;
-			}
-		}
-		else if(strcmp(argv[i], "-flipyz") == 0)
-		{
-			exporter.m_flipyz = true;
-		}
-		else
-		{
-			goto error;
-		}
-	}
-
-	if(!rpathFound)
-	{
-		exporter.m_rpath = exporter.m_outputDirectory;
-	}
-
-	if(!texrpathFound)
-	{
-		exporter.m_texrpath = exporter.m_outputDirectory;
-	}
-
-	return;
-
-error:
-	printf(usage, argv[0]);
-	exit(1);
-}
-
-int main(int argc, char** argv)
-{
-	try
-	{
-		Exporter exporter;
-
-		parseCommandLineArgs(argc, argv, exporter);
-
-		// Load file
-		exporter.load();
-
-		// Export
-		exporter.exportAll();
-	}
-	catch(std::exception& e)
-	{
-		ERROR("Exception: %s", &e.what()[0]);
-	}
-}

+ 0 - 57
tools/scene/templates/diffNormSpecFrag.h

@@ -1,57 +0,0 @@
-R"(		<program>
-			<type>frag</type>
-
-			<includes>
-				<include>shaders/MsCommonFrag.glsl</include>
-			</includes>
-
-			<inputs>
-				%specularColorInput%
-				%specularPowerInput%
-				%diffuseColorInput%
-				%normalInput%
-				%subsurfaceInput%
-				%emissionInput%
-				%metallicInput%
-				%heightInput%
-			</inputs>
-
-			<operations>
-				<operation>
-					<id>0</id>
-					<returnType>vec3</returnType>
-					<function>getNormal</function>
-				</operation>
-				<operation>
-					<id>1</id>
-					<returnType>vec4</returnType>
-					<function>getTangent</function>
-				</operation>
-				<operation>
-					<id>2</id>
-					<returnType>vec2</returnType>
-					<function>getTextureCoord</function>
-				</operation>
-				%heightFunc%
-				%diffuseColorFunc%
-				%normalFunc%
-				%specularColorFunc%
-				%specularPowerFunc%
-				%emissionFunc%
-				%metallicFunc%
-				<operation>
-					<id>100</id>
-					<returnType>void</returnType>
-					<function>writeRts</function>
-					<arguments>
-						<argument>%diffuseColorArg%</argument>
-						<argument>%normalArg%</argument>
-						<argument>%specularColorArg%</argument>
-						<argument>%specularPowerArg%</argument>
-						<argument>%subsurfaceArg%</argument>
-						<argument>%emissionArg%</argument>
-						<argument>%metallicArg%</argument>
-					</arguments>
-				</operation>
-			</operations>
-		</program>)"

+ 0 - 28
tools/scene/templates/simpleVert.h

@@ -1,28 +0,0 @@
-R"(		<program>
-			<type>vert</type>
-			<includes>
-				<include>shaders/MsCommonVert.glsl</include>
-			</includes>
-
-			<inputs>
-				<input><type>mat4</type><name>anki_mvp</name></input>
-				<input><type>mat3</type><name>anki_n</name><inShadow>0</inShadow></input>
-				%heightVertInput%
-			</inputs>
-
-			<operations>
-				<operation>
-					<id>0</id>
-					<returnType>void</returnType>
-					<function>writePositionAndUv</function>
-					<arguments><argument>anki_mvp</argument></arguments>
-				</operation>
-				<operation>
-					<id>1</id>
-					<returnType>void</returnType>
-					<function>writeNormalAndTangent</function>
-					<arguments><argument>anki_n</argument></arguments>
-				</operation>
-				%heightVertFunc%
-			</operations>
-		</program>)"

+ 0 - 68
tools/scene/templates/tessVert.h

@@ -1,68 +0,0 @@
-R"(		<program>
-			<type>vert</type>
-			<includes>
-				<include>shaders/MsCommonVert.glsl</include>
-			</includes>
-
-			<inputs>
-				<input><type>mat4</type><name>uMvp</name><value></value><instanced>%instanced%</instanced><arraySize>%arraySize%</arraySize></input>
-				<input><type>mat3</type><name>uN</name><value></value><instanced>%instanced%</instanced><arraySize>%arraySize%</arraySize></input>
-			</inputs>
-
-			<operations>
-				<operation>
-					<id>1</id>
-					<returnType>void</returnType>
-					<function>writePositionNormalTangentTexCoord</function>
-					<arguments><argument>uMvp</argument><argument>uN</argument></arguments>
-				</operation>
-			</operations>
-		</program>
-
-		<program>
-			<type>tesc</type>
-			<includes><include>shaders/MsCommonTessc.glsl</include></includes>
-
-			<inputs>
-				<input><type>float</type><name>uMaxTessLevel</name><value>12.0</value></input>
-				<input><type>mat4</type><name>uMvp</name><value></value></input>
-				<input><type>mat3</type><name>uN</name><value></value></input>
-			</inputs>
-
-			<operations>
-				<operation>
-					<id>0</id>
-					<returnType>void</returnType>
-					<function>tessellateDispMapPositionNormalTangentTexCoord</function>
-					<arguments>
-						<argument>uMaxTessLevel</argument>
-						<argument>uMvp</argument>
-						<argument>uN</argument>
-					</arguments>
-				</operation>
-			</operations>
-		</program>
-
-		<program>
-			<type>tese</type>
-			<includes><include>shaders/MsCommonTesse.glsl</include></includes>
-
-			<inputs>
-				<input><type>mat4</type><name>uMvp</name><value></value></input>
-				<input><type>mat3</type><name>uN</name><value></value></input>
-				<input><type>sampler2D</type><name>dispMap</name><value>%dispMap%</value></input>
-			</inputs>
-
-			<operations>
-				<operation>
-					<id>0</id>
-					<returnType>void</returnType>
-					<function>tessellateDispMapPositionNormalTangentTexCoord</function>
-					<arguments>
-						<argument>uMvp</argument>
-						<argument>uN</argument>
-						<argument>dispMap</argument>
-					</arguments>
-				</operation>
-			</operations>
-		</program>)"