Преглед изворни кода

Merge pull request #23991 from glaforte/bugfix/19195

Generate the tangents without de-indexing and re-indexing the vertices.
Rémi Verschelde пре 6 година
родитељ
комит
6f9aa8727c
3 измењених фајлова са 71 додато и 35 уклоњено
  1. 1 0
      editor/import/editor_import_collada.cpp
  2. 70 34
      scene/resources/surface_tool.cpp
  3. 0 1
      scene/resources/surface_tool.h

+ 1 - 0
editor/import/editor_import_collada.cpp

@@ -1191,6 +1191,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
 							if (collada.state.mesh_data_map.has(meshid)) {
 							if (collada.state.mesh_data_map.has(meshid)) {
 								Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
 								Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
 								const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
 								const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
+								mesh->set_name(meshdata.name);
 								Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
 								Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), false);
 								ERR_FAIL_COND_V(err, err);
 								ERR_FAIL_COND_V(err, err);
 
 

+ 70 - 34
scene/resources/surface_tool.cpp

@@ -764,10 +764,22 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
 }
 }
 
 
 //mikktspace callbacks
 //mikktspace callbacks
+namespace {
+struct TangentGenerationContextUserData {
+	Vector<List<SurfaceTool::Vertex>::Element *> vertices;
+	Vector<List<int>::Element *> indices;
+};
+} // namespace
+
 int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
 int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
 
 
-	Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
-	return varr.size() / 3;
+	TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+
+	if (triangle_data.indices.size() > 0) {
+		return triangle_data.indices.size() / 3;
+	} else {
+		return triangle_data.vertices.size() / 3;
+	}
 }
 }
 int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
 int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
 
 
@@ -775,8 +787,17 @@ int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, c
 }
 }
 void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
 void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
 
 
-	Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
-	Vector3 v = varr[iFace * 3 + iVert]->get().vertex;
+	TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+	Vector3 v;
+	if (triangle_data.indices.size() > 0) {
+		int index = triangle_data.indices[iFace * 3 + iVert]->get();
+		if (index < triangle_data.vertices.size()) {
+			v = triangle_data.vertices[index]->get().vertex;
+		}
+	} else {
+		v = triangle_data.vertices[iFace * 3 + iVert]->get().vertex;
+	}
+
 	fvPosOut[0] = v.x;
 	fvPosOut[0] = v.x;
 	fvPosOut[1] = v.y;
 	fvPosOut[1] = v.y;
 	fvPosOut[2] = v.z;
 	fvPosOut[2] = v.z;
@@ -784,38 +805,56 @@ void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvP
 
 
 void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
 void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
 
 
-	Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
-	Vector3 v = varr[iFace * 3 + iVert]->get().normal;
+	TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+	Vector3 v;
+	if (triangle_data.indices.size() > 0) {
+		int index = triangle_data.indices[iFace * 3 + iVert]->get();
+		if (index < triangle_data.vertices.size()) {
+			v = triangle_data.vertices[index]->get().normal;
+		}
+	} else {
+		v = triangle_data.vertices[iFace * 3 + iVert]->get().normal;
+	}
+
 	fvNormOut[0] = v.x;
 	fvNormOut[0] = v.x;
 	fvNormOut[1] = v.y;
 	fvNormOut[1] = v.y;
 	fvNormOut[2] = v.z;
 	fvNormOut[2] = v.z;
 }
 }
 void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
 void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
 
 
-	Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
-	Vector2 v = varr[iFace * 3 + iVert]->get().uv;
+	TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+	Vector2 v;
+	if (triangle_data.indices.size() > 0) {
+		int index = triangle_data.indices[iFace * 3 + iVert]->get();
+		if (index < triangle_data.vertices.size()) {
+			v = triangle_data.vertices[index]->get().uv;
+		}
+	} else {
+		v = triangle_data.vertices[iFace * 3 + iVert]->get().uv;
+	}
+
 	fvTexcOut[0] = v.x;
 	fvTexcOut[0] = v.x;
 	fvTexcOut[1] = v.y;
 	fvTexcOut[1] = v.y;
-	//fvTexcOut[1]=1.0-v.y;
 }
 }
 
 
 void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
 void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
 		const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
 		const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
 
 
-	Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
-	Vertex *vtx = &varr[iFace * 3 + iVert]->get();
-
-	vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
-	vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
-}
-
-void SurfaceTool::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) {
-
-	Vector<List<Vertex>::Element *> &varr = *((Vector<List<Vertex>::Element *> *)pContext->m_pUserData);
-	Vertex &vtx = varr[iFace * 3 + iVert]->get();
+	TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
+	Vertex *vtx = NULL;
+	if (triangle_data.indices.size() > 0) {
+		int index = triangle_data.indices[iFace * 3 + iVert]->get();
+		if (index < triangle_data.vertices.size()) {
+			vtx = &triangle_data.vertices[index]->get();
+		}
+	} else {
+		vtx = &triangle_data.vertices[iFace * 3 + iVert]->get();
+	}
 
 
-	vtx.tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
-	vtx.binormal = vtx.normal.cross(vtx.tangent) * fSign;
+	if (vtx != NULL) {
+		vtx->tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]);
+		vtx->binormal = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]);
+	}
 }
 }
 
 
 void SurfaceTool::generate_tangents() {
 void SurfaceTool::generate_tangents() {
@@ -823,10 +862,6 @@ void SurfaceTool::generate_tangents() {
 	ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV));
 	ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV));
 	ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL));
 	ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL));
 
 
-	bool indexed = index_array.size() > 0;
-	if (indexed)
-		deindex();
-
 	SMikkTSpaceInterface mkif;
 	SMikkTSpaceInterface mkif;
 	mkif.m_getNormal = mikktGetNormal;
 	mkif.m_getNormal = mikktGetNormal;
 	mkif.m_getNumFaces = mikktGetNumFaces;
 	mkif.m_getNumFaces = mikktGetNumFaces;
@@ -839,24 +874,25 @@ void SurfaceTool::generate_tangents() {
 	SMikkTSpaceContext msc;
 	SMikkTSpaceContext msc;
 	msc.m_pInterface = &mkif;
 	msc.m_pInterface = &mkif;
 
 
-	Vector<List<Vertex>::Element *> vtx;
-	vtx.resize(vertex_array.size());
+	TangentGenerationContextUserData triangle_data;
+	triangle_data.vertices.resize(vertex_array.size());
 	int idx = 0;
 	int idx = 0;
 	for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
 	for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
-		vtx.write[idx++] = E;
+		triangle_data.vertices.write[idx++] = E;
 		E->get().binormal = Vector3();
 		E->get().binormal = Vector3();
 		E->get().tangent = Vector3();
 		E->get().tangent = Vector3();
 	}
 	}
-	msc.m_pUserData = &vtx;
+	triangle_data.indices.resize(index_array.size());
+	idx = 0;
+	for (List<int>::Element *E = index_array.front(); E; E = E->next()) {
+		triangle_data.indices.write[idx++] = E;
+	}
+	msc.m_pUserData = &triangle_data;
 
 
 	bool res = genTangSpaceDefault(&msc);
 	bool res = genTangSpaceDefault(&msc);
 
 
 	ERR_FAIL_COND(!res);
 	ERR_FAIL_COND(!res);
 	format |= Mesh::ARRAY_FORMAT_TANGENT;
 	format |= Mesh::ARRAY_FORMAT_TANGENT;
-
-	if (indexed) {
-		index();
-	}
 }
 }
 
 
 void SurfaceTool::generate_normals(bool p_flip) {
 void SurfaceTool::generate_normals(bool p_flip) {

+ 0 - 1
scene/resources/surface_tool.h

@@ -90,7 +90,6 @@ private:
 	static void mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert);
 	static void mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert);
 	static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert);
 	static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert);
 	static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert);
 	static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert);
-	static void mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert);
 	static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
 	static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
 			const tbool bIsOrientationPreserving, const int iFace, const int iVert);
 			const tbool bIsOrientationPreserving, const int iFace, const int iVert);