Browse Source

Some more work on the gltf exporter

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
13e6703a76
2 changed files with 107 additions and 17 deletions
  1. 103 16
      tools/gltf_exporter/Exporter.cpp
  2. 4 1
      tools/gltf_exporter/Exporter.h

+ 103 - 16
tools/gltf_exporter/Exporter.cpp

@@ -45,37 +45,119 @@ Error Exporter::load()
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-Error Exporter::exportMeshes()
+void Exporter::getAttributeInfo(
+	const tinygltf::Primitive& primitive, CString attribName, const U8*& buff, U32& stride, U32& count) const
 {
 {
-	for(const tinygltf::Mesh& mesh : m_model.meshes)
+	const tinygltf::Accessor& accessor = m_model.accessors[primitive.attributes.find(attribName.cstr())->second];
+	count = accessor.count;
+	const tinygltf::BufferView& view = m_model.bufferViews[accessor.bufferView];
+	buff = reinterpret_cast<const U8*>(&(m_model.buffers[view.buffer].data[accessor.byteOffset + view.byteOffset]));
+	stride = view.byteStride;
+}
+
+Error Exporter::exportMesh(const tinygltf::Mesh& mesh)
+{
+	if(mesh.primitives.size() != 1)
+	{
+		ANKI_LOGE("Can't handle this");
+		return Error::USER_DATA;
+	}
+	const tinygltf::Primitive& primitive = mesh.primitives[0];
+
+	// Get indices
+	DynamicArrayAuto<U16> indices(m_alloc);
 	{
 	{
-		if(mesh.primitives.size() != 1)
+		const tinygltf::Accessor& accessor = m_model.accessors[primitive.indices];
+		const tinygltf::BufferView& bufferView = m_model.bufferViews[accessor.bufferView];
+		const tinygltf::Buffer& buffer = m_model.buffers[bufferView.buffer];
+
+		indices.create(accessor.count);
+
+		switch(accessor.componentType)
 		{
 		{
-			ANKI_LOGE("Can't handle this");
-			return Error::USER_DATA;
+		case TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT:
+			for(U i = 0; i < indices.getSize(); ++i)
+			{
+				indices[i] = *reinterpret_cast<const U32*>(buffer.data[i * sizeof(U32)]);
+			}
+			break;
+		case TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT:
+			for(U i = 0; i < indices.getSize(); ++i)
+			{
+				indices[i] = *reinterpret_cast<const U16*>(buffer.data[i * sizeof(U16)]);
+			}
+			break;
+		default:
+			ANKI_ASSERT(!"TODO");
+			break;
 		}
 		}
-		const tinygltf::Primitive& primitive = mesh.primitives[0];
+	}
 
 
-		// Get positions
+	// Get positions
+	DynamicArrayAuto<Vec3> positions(m_alloc);
+	Vec3 minPos, maxPos;
+	U32 vertCount;
+	{
 		if(primitive.attributes.find("POSITION") != primitive.attributes.end())
 		if(primitive.attributes.find("POSITION") != primitive.attributes.end())
 		{
 		{
 			ANKI_LOGE("Positions are missing for mesh %s", mesh.name.c_str());
 			ANKI_LOGE("Positions are missing for mesh %s", mesh.name.c_str());
 			return Error::USER_DATA;
 			return Error::USER_DATA;
 		}
 		}
-		const tinygltf::Accessor& posAccessor = m_model.accessors[primitive.attributes.find("POSITION")->second];
-		const U32 vertCount = posAccessor.count;
-		const tinygltf::BufferView& posView = m_model.bufferViews[posAccessor.bufferView];
-		const U8* posBuff = reinterpret_cast<const U8*>(
-			&(m_model.buffers[posView.buffer].data[posAccessor.byteOffset + posView.byteOffset]));
-		const PtrSize posStride = posView.byteStride;
+
+		const U8* posBuff;
+		U32 posStride;
+		getAttributeInfo(primitive, "POSITION", posBuff, posStride, vertCount);
+
 		if(posStride < sizeof(Vec3))
 		if(posStride < sizeof(Vec3))
 		{
 		{
 			ANKI_LOGE("Position stride is wrong for mesh %s", mesh.name.c_str());
 			ANKI_LOGE("Position stride is wrong for mesh %s", mesh.name.c_str());
 			return Error::USER_DATA;
 			return Error::USER_DATA;
 		}
 		}
 
 
-		Vec3 posMin(posAccessor.minValues[0], posAccessor.minValues[1], posAccessor.minValues[2]);
-		Vec3 posMax(posAccessor.maxValues[0], posAccessor.maxValues[1], posAccessor.maxValues[2]);
+		positions.create(vertCount);
+		for(U v = 0; v < vertCount; ++v)
+		{
+			positions[v] = Vec3(reinterpret_cast<const F32*>(&posBuff[v * posStride]));
+
+			// TODO minPos, maxPos
+		}
+	}
+
+	// Get normals and UVs
+	DynamicArrayAuto<Vec3> normals(m_alloc);
+	DynamicArrayAuto<Vec2> uvs(m_alloc);
+
+	{
+		if(primitive.attributes.find("NORMAL") != primitive.attributes.end())
+		{
+			ANKI_LOGE("Normals are missing for mesh %s", mesh.name.c_str());
+			return Error::USER_DATA;
+		}
+		if(primitive.attributes.find("TEXCOORD_0") != primitive.attributes.end())
+		{
+			ANKI_LOGE("Texcoords are missing for mesh %s", mesh.name.c_str());
+			return Error::USER_DATA;
+		}
+
+		const U8* normalBuff;
+		U32 normalStride;
+		U32 count;
+		getAttributeInfo(primitive, "NORMAL", normalBuff, normalStride, count);
+		ANKI_ASSERT(count == vertCount);
+
+		const U8* uvBuff;
+		U32 uvStride;
+		getAttributeInfo(primitive, "TEXCOORD_0", uvBuff, uvStride, count);
+		ANKI_ASSERT(count == vertCount);
+
+		normals.create(vertCount);
+		uvs.create(vertCount);
+
+		for(U v = 0; v < vertCount; ++v)
+		{
+			normals[v] = Vec3(reinterpret_cast<const F32*>(&normalBuff[v * normalStride]));
+			uvs[v] = Vec2(reinterpret_cast<const F32*>(&uvBuff[v * uvStride]));
+		}
 	}
 	}
 
 
 	return Error::NONE;
 	return Error::NONE;
@@ -83,7 +165,12 @@ Error Exporter::exportMeshes()
 
 
 Error Exporter::exportAll()
 Error Exporter::exportAll()
 {
 {
-	// m_model.
+	for(const tinygltf::Mesh& mesh : m_model.meshes)
+	{
+		ANKI_CHECK(exportMesh(mesh));
+	}
+
+	return Error::NONE;
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

+ 4 - 1
tools/gltf_exporter/Exporter.h

@@ -30,7 +30,10 @@ public:
 	Error exportAll();
 	Error exportAll();
 
 
 private:
 private:
-	Error exportMeshes();
+	Error exportMesh(const tinygltf::Mesh& mesh);
+
+	void getAttributeInfo(
+		const tinygltf::Primitive& primitive, CString attribName, const U8*& buff, U32& stride, U32& count) const;
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki