Bladeren bron

Some work on the GLTF importer

Panagiotis Christopoulos Charitos 6 jaren geleden
bovenliggende
commit
88d80a7a7a

+ 58 - 1
tools/gltf_importer/Importer.cpp

@@ -24,10 +24,12 @@ Importer::~Importer()
 	m_alloc.deleteInstance(m_hive);
 }
 
-Error Importer::load(CString inputFname, CString outDir)
+Error Importer::load(CString inputFname, CString outDir, CString rpath, CString texrpath)
 {
 	m_inputFname.create(inputFname);
 	m_outDir.create(outDir);
+	m_rpath.create(rpath);
+	m_texrpath.create(texrpath);
 
 	cgltf_options options = {};
 	cgltf_result res = cgltf_parse_file(&options, inputFname.cstr(), &m_gltf);
@@ -61,6 +63,61 @@ Error Importer::writeAll()
 		ANKI_CHECK(writeMaterial(m_gltf->materials[i]));
 	}
 
+	StringAuto sceneFname(m_alloc);
+	sceneFname.sprintf("%sscene.lua", m_outDir.cstr());
+	ANKI_CHECK(m_sceneFile.open(sceneFname.toCString(), FileOpenFlag::WRITE));
+
+	// Nodes
+	for(const cgltf_scene* scene = m_gltf->scenes; scene < m_gltf->scenes + m_gltf->scenes_count; ++scene)
+	{
+		for(cgltf_node* const* node = scene->nodes; node < scene->nodes + scene->nodes_count; ++node)
+		{
+			ANKI_CHECK(visitNode(*(*node)));
+		}
+	}
+
+	return Error::NONE;
+}
+
+Error Importer::visitNode(const cgltf_node& node)
+{
+	if(node.light)
+	{
+		ANKI_CHECK(writeLight(node));
+	}
+	else
+	{
+		ANKI_ASSERT(!"TODO");
+	}
+
+	return Error::NONE;
+}
+
+Error Importer::writeLight(const cgltf_node& node)
+{
+	const cgltf_light& light = *node.light;
+	ANKI_GLTF_LOGI("Exporting light %s", light.name);
+
+	CString lightTypeStr;
+	switch(light.type)
+	{
+	case cgltf_light_type_point:
+		lightTypeStr = "Point";
+		break;
+	case cgltf_light_type_spot:
+		lightTypeStr = "Spot";
+		break;
+	case cgltf_light_type_directional:
+		lightTypeStr = "Directional";
+		break;
+	default:
+		ANKI_GLTF_LOGE("Unsupporter light type %d", light.type);
+		return Error::USER_DATA;
+	}
+
+	ANKI_CHECK(m_sceneFile.writeText("\nnode = scene:new%sLightNode(\"%s\")\n", lightTypeStr.cstr(), light.name));
+	ANKI_CHECK(m_sceneFile.writeText("lcomp = node:getSceneNodeBase():getLightComponent()\n"));
+
 	return Error::NONE;
 }
 

+ 8 - 1
tools/gltf_importer/Importer.h

@@ -19,7 +19,7 @@ public:
 
 	~Importer();
 
-	Error load(CString inputFname, CString outDir);
+	Error load(CString inputFname, CString outDir, CString rpath, CString texrpath);
 
 	Error writeAll();
 
@@ -28,6 +28,8 @@ private:
 
 	StringAuto m_inputFname = {m_alloc};
 	StringAuto m_outDir = {m_alloc};
+	StringAuto m_rpath = {m_alloc};
+	StringAuto m_texrpath = {m_alloc};
 
 	cgltf_data* m_gltf = nullptr;
 
@@ -35,8 +37,13 @@ private:
 
 	ThreadHive* m_hive = nullptr;
 
+	File m_sceneFile;
+
 	ANKI_USE_RESULT Error writeMesh(const cgltf_mesh& mesh);
 	ANKI_USE_RESULT Error writeMaterial(const cgltf_material& mtl);
+
+	ANKI_USE_RESULT Error visitNode(const cgltf_node& node);
+	ANKI_USE_RESULT Error writeLight(const cgltf_node& node);
 };
 
 #define ANKI_GLTF_LOGI(...) ANKI_LOG("GLTF", NORMAL, __VA_ARGS__)

+ 116 - 5
tools/gltf_importer/ImporterMaterial.cpp

@@ -14,8 +14,7 @@ const char* MATERIAL_TEMPLATE = R"(<?xml version="1.0" encoding="UTF-8" ?>
 	<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="METALLIC_ROUGHNESS_TEX" value="%metallicRoughnessTexMutator%"/>
 		<mutator name="NORMAL_TEX" value="%normalTexMutator%"/>
 		<mutator name="PARALLAX" value="%parallaxMutator%"/>
 		<mutator name="EMISSIVE_TEX" value="%emissiveTexMutator%"/>
@@ -30,8 +29,7 @@ const char* MATERIAL_TEMPLATE = R"(<?xml version="1.0" encoding="UTF-8" ?>
 
 		%diff%
 		%spec%
-		%roughness%
-		%metallic%
+		%metallicRoughness%
 		%normal%
 		%emission%
 		%subsurface%
@@ -84,7 +82,7 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
 	if(mtl.pbr_metallic_roughness.base_color_texture.texture)
 	{
 		StringAuto uri(m_alloc);
-		uri.sprintf("%s%s", "TODO", getTextureUri(mtl.pbr_metallic_roughness.base_color_texture).cstr());
+		uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.base_color_texture).cstr());
 
 		xml = replaceAllString(
 			xml, "%diff%", "<input shaderInput=\"diffTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
@@ -102,6 +100,119 @@ Error Importer::writeMaterial(const cgltf_material& mtl)
 		xml = replaceAllString(xml, "%diffTexMutator%", "0");
 	}
 
+	// Specular color (freshnel)
+	// TODO
+	{
+		xml = replaceAllString(xml, "%spec%", "<input shaderInput=\"specColor\" value=\"0.04 0.04 0.04\"/>");
+		xml = replaceAllString(xml, "%specTexMutator%", "0");
+	}
+
+	// Roughness & metallic
+	if(mtl.pbr_metallic_roughness.metallic_roughness_texture.texture)
+	{
+		StringAuto uri(m_alloc);
+		uri.sprintf(
+			"%s%s", m_texrpath.cstr(), getTextureUri(mtl.pbr_metallic_roughness.metallic_roughness_texture).cstr());
+
+		xml = replaceAllString(xml,
+			"%metallicRoughness%",
+			"<input shaderInput=\"metallicRoughnessTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
+
+		xml = replaceAllString(xml, "%metallicRoughnessTexMutator%", "1");
+	}
+	else
+	{
+		const F32 roughness = mtl.pbr_metallic_roughness.roughness_factor;
+		const F32 metallic = mtl.pbr_metallic_roughness.metallic_factor;
+
+		xml = replaceAllString(xml,
+			"%metallicRoughness%",
+			"<input shaderInput=\"metallic\" value=\"" + std::to_string(metallic) + "\"/>\n"
+				+ "<input shaderInput=\"roughness\" value=\"" + std::to_string(roughness) + "\"/>");
+
+		xml = replaceAllString(xml, "%metallicRoughnessTexMutator%", "0");
+	}
+
+	// Normal texture
+	if(mtl.normal_texture.texture)
+	{
+		StringAuto uri(m_alloc);
+		uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.normal_texture).cstr());
+
+		xml = replaceAllString(
+			xml, "%normal%", "<input shaderInput=\"normalTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
+
+		xml = replaceAllString(xml, "%normalTexMutator%", "1");
+	}
+	else
+	{
+		xml = replaceAllString(xml, "%normal%", "");
+		xml = replaceAllString(xml, "%normalTexMutator%", "0");
+	}
+
+	// Emissive texture
+	if(mtl.emissive_texture.texture)
+	{
+		StringAuto uri(m_alloc);
+		uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.emissive_texture).cstr());
+
+		xml = replaceAllString(
+			xml, "%emission%", "<input shaderInput=\"emissiveTex\" value=\"" + std::string(uri.cstr()) + "\"/>");
+
+		xml = replaceAllString(xml, "%emissiveTexMutator%", "1");
+	}
+	else
+	{
+		const F32* emissionCol = &mtl.emissive_factor[0];
+
+		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
+	// TODO
+	{
+		F32 subsurface = 0.0f;
+
+		xml = replaceAllString(
+			xml, "%subsurface%", "<input shaderInput=\"subsurface\" value=\"" + std::to_string(subsurface) + "\"/>");
+	}
+
+	// Height texture
+	// TODO Add native support and not use occlusion map
+	if(mtl.occlusion_texture.texture)
+	{
+		StringAuto uri(m_alloc);
+		uri.sprintf("%s%s", m_texrpath.cstr(), getTextureUri(mtl.occlusion_texture).cstr());
+
+		xml = replaceAllString(xml,
+			"%height%",
+			"<input shaderInput=\"heightTex\" value=\"" + std::string(uri.cstr())
+				+ "\"/>\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
+	{
+		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");
+
 	// Write file
 	File file;
 	ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::WRITE));

+ 4 - 1
tools/gltf_importer/Main.cpp

@@ -102,7 +102,10 @@ int main(int argc, char** argv)
 	}
 
 	Importer importer;
-	if(importer.load(info.m_inputFname.toCString(), info.m_outDir.toCString()))
+	if(importer.load(info.m_inputFname.toCString(),
+		   info.m_outDir.toCString(),
+		   info.m_rpath.toCString(),
+		   info.m_texRpath.toCString()))
 	{
 		return 1;
 	}