Browse Source

Some work on the GLTF importer

Panagiotis Christopoulos Charitos 6 years ago
parent
commit
e21e25da97
1 changed files with 217 additions and 20 deletions
  1. 217 20
      tools/gltf_importer/Importer.cpp

+ 217 - 20
tools/gltf_importer/Importer.cpp

@@ -45,40 +45,62 @@ static void removeScale(Mat4& m)
 	m.setRotationPart(rot);
 }
 
-static ANKI_USE_RESULT Error getNodeTransform(const cgltf_node& node, Transform& trf)
+static void getNodeTransform(const cgltf_node& node, Vec3& tsl, Mat3& rot, Vec3& scale)
 {
-	trf = Transform::getIdentity();
 	if(node.has_matrix)
 	{
-		Mat4 mat = Mat4(node.matrix).getTransposed();
-		F32 scale;
-		ANKI_CHECK(getUniformScale(mat, scale));
-		removeScale(mat);
-		trf = Transform(mat);
+		ANKI_ASSERT(!"TODO");
 	}
 	else
 	{
 		if(node.has_translation)
 		{
-			trf.setOrigin(Vec4(node.translation[0], node.translation[1], node.translation[2], 0.0f));
+			tsl = Vec3(node.translation[0], node.translation[1], node.translation[2]);
+		}
+		else
+		{
+			tsl = Vec3(0.0f);
 		}
 
 		if(node.has_rotation)
 		{
-			trf.setRotation(Mat3x4(Quat(node.rotation[0], node.rotation[1], node.rotation[2], node.rotation[3])));
+			rot = Mat3(Quat(node.rotation[0], node.rotation[1], node.rotation[2], node.rotation[3]));
+		}
+		else
+		{
+			rot = Mat3::getIdentity();
 		}
 
 		if(node.has_scale)
 		{
-			if(node.scale[0] != node.scale[1] || node.scale[0] != node.scale[2])
-			{
-				ANKI_GLTF_LOGE("Expecting uniform scale");
-				return Error::USER_DATA;
-			}
-
-			trf.setScale(node.scale[0]);
+			ANKI_ASSERT(node.scale[0] > 0.0f);
+			ANKI_ASSERT(node.scale[1] > 0.0f);
+			ANKI_ASSERT(node.scale[2] > 0.0f);
+			scale = Vec3(node.scale[0], node.scale[1], node.scale[2]);
+		}
+		else
+		{
+			scale = Vec3(1.0f);
 		}
 	}
+}
+
+static ANKI_USE_RESULT Error getNodeTransform(const cgltf_node& node, Transform& trf)
+{
+	Vec3 tsl;
+	Mat3 rot;
+	Vec3 scale;
+	getNodeTransform(node, tsl, rot, scale);
+
+	if(scale[0] != scale[1] || scale[0] != scale[2])
+	{
+		ANKI_GLTF_LOGE("Expecting uniform scale");
+		return Error::USER_DATA;
+	}
+
+	trf.setOrigin(tsl.xyz0());
+	trf.setRotation(Mat3x4(rot));
+	trf.setScale(scale[0]);
 
 	return Error::NONE;
 }
@@ -261,6 +283,9 @@ Error Importer::parseArrayOfNumbers(CString str, DynamicArrayAuto<F64>& out, con
 Error Importer::visitNode(
 	const cgltf_node& node, const Transform& parentTrf, const HashMapAuto<CString, StringAuto>& parentExtras)
 {
+	Transform localTrf;
+	ANKI_CHECK(getNodeTransform(node, localTrf));
+
 	HashMapAuto<CString, StringAuto> outExtras(m_alloc);
 	Bool dummyNode = false;
 	if(node.light)
@@ -273,8 +298,182 @@ Error Importer::visitNode(
 	}
 	else if(node.mesh)
 	{
-		ANKI_CHECK(writeModel(*node.mesh));
-		ANKI_CHECK(writeModelNode(node, parentExtras));
+		// Handle special nodes
+		HashMapAuto<CString, StringAuto> extras(parentExtras);
+		ANKI_CHECK(getExtras(node.extras, extras));
+
+		HashMapAuto<CString, StringAuto>::Iterator it;
+		if((it = extras.find("particles")) != extras.getEnd())
+		{
+			const StringAuto& fname = *it;
+
+			Bool gpuParticles = false;
+			if((it = extras.find("gpu_particles")) != extras.getEnd() && *it == "true")
+			{
+				gpuParticles = true;
+			}
+
+			ANKI_CHECK(m_sceneFile.writeText("\nnode = scene:new%sModelNode(\"%s\", \"%s%s\")\n",
+				(gpuParticles) ? "Gpu" : "",
+				node.name,
+				m_rpath.cstr(),
+				fname.cstr()));
+		}
+		else if((it = extras.find("collision")) != extras.getEnd() && *it == "true")
+		{
+			// Write colission mesh
+			{
+				StringAuto fname(m_alloc);
+				fname.sprintf("%s%s.ankicl", m_outDir.cstr(), node.mesh->name);
+				File file;
+				ANKI_CHECK(file.open(fname.toCString(), FileOpenFlag::WRITE));
+
+				ANKI_CHECK(file.writeText("<collisionShape>\n\t<type>staticMesh</type>\n\t<value>%s%s.ankimesh"
+										  "</value>\n</collisionShape>\n",
+					m_rpath.cstr(),
+					node.mesh->name));
+			}
+
+			ANKI_CHECK(m_sceneFile.writeText("\nnode = scene:newStaticCollisionNode(\"%s\", \"%s%s.ankicl\")\n",
+				node.name,
+				m_rpath.cstr(),
+				node.mesh->name));
+		}
+		else if((it = extras.find("reflection_probe")) != extras.getEnd() && *it == "true")
+		{
+			Vec3 tsl;
+			Mat3 rot;
+			Vec3 scale;
+			getNodeTransform(node, tsl, rot, scale);
+
+			const Vec3 half = scale;
+			const Vec3 aabbMin = tsl - half - tsl;
+			const Vec3 aabbMax = tsl + half - tsl;
+
+			localTrf = Transform(tsl.xyz0(), Mat3x4(rot), 1.0f);
+
+			ANKI_CHECK(m_sceneFile.writeText(
+				"\nnode = scene:newReflectionProbeNode(\"%s\", Vec4.new(%f, %f, %f, 0), Vec4.new(%f, %f, %f, 0))\n",
+				node.name,
+				aabbMin.x(),
+				aabbMin.y(),
+				aabbMin.z(),
+				aabbMax.x(),
+				aabbMax.y(),
+				aabbMax.z()));
+		}
+		else if((it = extras.find("gi_probe")) != extras.getEnd() && *it == "true")
+		{
+			Vec3 tsl;
+			Mat3 rot;
+			Vec3 scale;
+			getNodeTransform(node, tsl, rot, scale);
+
+			const Vec3 half = scale;
+			const Vec3 aabbMin = tsl - half - tsl;
+			const Vec3 aabbMax = tsl + half - tsl;
+
+			localTrf = Transform(tsl.xyz0(), Mat3x4(rot), 1.0f);
+
+			F32 fadeDistance = -1.0f;
+			if((it = extras.find("gi_probe_fade_distance")) != extras.getEnd())
+			{
+				ANKI_CHECK(it->toNumber(fadeDistance));
+			}
+
+			F32 cellSize = -1.0f;
+			if((it = extras.find("gi_probe_cell_size")) != extras.getEnd())
+			{
+				ANKI_CHECK(it->toNumber(cellSize));
+			}
+
+			ANKI_CHECK(m_sceneFile.writeText("\nnode = scene:newGlobalIlluminationProbeNode(\"%s\")\n", node.name));
+			ANKI_CHECK(m_sceneFile.writeText("comp = node:getSceneNodeBase():getGlobalIlluminationProbeComponent()\n"));
+
+			ANKI_CHECK(m_sceneFile.writeText("comp:setBoundingBox(Vec4.new(%f, %f, %f, 0), Vec4.new(%f, %f, %f, 0))\n",
+				aabbMin.x(),
+				aabbMin.y(),
+				aabbMin.z(),
+				aabbMax.x(),
+				aabbMax.y(),
+				aabbMax.z()));
+
+			if(fadeDistance > 0.0f)
+			{
+				ANKI_CHECK(m_sceneFile.writeText("comp:setFadeDistance(%f)\n", fadeDistance));
+			}
+
+			if(cellSize > 0.0f)
+			{
+				ANKI_CHECK(m_sceneFile.writeText("comp:setCellSize(%f)\n", cellSize));
+			}
+		}
+		else if((it = extras.find("decal")) != extras.getEnd() && *it == "true")
+		{
+			Vec3 tsl;
+			Mat3 rot;
+			Vec3 scale;
+			getNodeTransform(node, tsl, rot, scale);
+
+			StringAuto diffuseAtlas(m_alloc);
+			if((it = extras.find("decal_diffuse_atlas")) != extras.getEnd())
+			{
+				diffuseAtlas.create(it->toCString());
+			}
+
+			StringAuto diffuseSubtexture(m_alloc);
+			if((it = extras.find("decal_diffuse_sub_texture")) != extras.getEnd())
+			{
+				diffuseSubtexture.create(it->toCString());
+			}
+
+			F32 diffuseFactor = -1.0f;
+			if((it = extras.find("decal_diffuse_factor")) != extras.getEnd())
+			{
+				ANKI_CHECK(it->toNumber(diffuseFactor));
+			}
+
+			StringAuto specularRougnessMetallicAtlas(m_alloc);
+			if((it = extras.find("decal_specular_roughness_metallic_atlas")) != extras.getEnd())
+			{
+				specularRougnessMetallicAtlas.create(it->toCString());
+			}
+
+			StringAuto specularRougnessMetallicSubtexture(m_alloc);
+			if((it = extras.find("decal_specular_roughness_metallic_sub_texture")) != extras.getEnd())
+			{
+				specularRougnessMetallicSubtexture.create(it->toCString());
+			}
+
+			F32 specularRougnessMetallicFactor = -1.0f;
+			if((it = extras.find("decal_specular_roughness_metallic_factor")) != extras.getEnd())
+			{
+				ANKI_CHECK(it->toNumber(specularRougnessMetallicFactor));
+			}
+
+			ANKI_CHECK(m_sceneFile.writeText("\nnode = scene:newDecalNode(\"%s\")\n", node.name));
+			ANKI_CHECK(m_sceneFile.writeText("comp = node:getSceneNodeBase():getDecalComponent()\n"));
+			if(diffuseAtlas)
+			{
+				ANKI_CHECK(m_sceneFile.writeText("comp:setDiffuseDecal(\"%s\", \"%s\", %f)\n",
+					diffuseAtlas.cstr(),
+					diffuseSubtexture.cstr(),
+					diffuseFactor));
+			}
+
+			if(specularRougnessMetallicAtlas)
+			{
+				ANKI_CHECK(m_sceneFile.writeText("comp:setSpecularRoughnessDecal(\"%s\", \"%s\", %f)\n",
+					specularRougnessMetallicAtlas.cstr(),
+					specularRougnessMetallicSubtexture.cstr(),
+					specularRougnessMetallicFactor));
+			}
+		}
+		else
+		{
+			ANKI_CHECK(writeModel(*node.mesh));
+			ANKI_CHECK(writeModelNode(node, parentExtras));
+		}
 	}
 	else
 	{
@@ -284,8 +483,6 @@ Error Importer::visitNode(
 	}
 
 	// Write transform
-	Transform localTrf;
-	ANKI_CHECK(getNodeTransform(node, localTrf));
 	Transform trf = parentTrf.combineTransformations(localTrf);
 	if(!dummyNode)
 	{