summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2018-12-03 17:35:50 +0100
committerGitHub <noreply@github.com>2018-12-03 17:35:50 +0100
commit6f9aa8727c8905fbc0c10ea8d214c7d31f01f467 (patch)
tree3323aa7211455d752fd185af9cef5033afc606e5
parentb0c66154a4359674f27e4a6c8f13acb1e6fd04a7 (diff)
parent675dc00d04823e21ba9ea5ea6358c3eb322eb9f8 (diff)
Merge pull request #23991 from glaforte/bugfix/19195
Generate the tangents without de-indexing and re-indexing the vertices.
-rw-r--r--editor/import/editor_import_collada.cpp1
-rw-r--r--scene/resources/surface_tool.cpp104
-rw-r--r--scene/resources/surface_tool.h1
3 files changed, 71 insertions, 35 deletions
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index cdc35a98e2..8e69090da3 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/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)) {
Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
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);
ERR_FAIL_COND_V(err, err);
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 5d4c7861e3..9907636e91 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -764,10 +764,22 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
}
//mikktspace callbacks
+namespace {
+struct TangentGenerationContextUserData {
+ Vector<List<SurfaceTool::Vertex>::Element *> vertices;
+ Vector<List<int>::Element *> indices;
+};
+} // namespace
+
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) {
@@ -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) {
- 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[1] = v.y;
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) {
- 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[1] = v.y;
fvNormOut[2] = v.z;
}
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[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,
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() {
@@ -823,10 +862,6 @@ void SurfaceTool::generate_tangents() {
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV));
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL));
- bool indexed = index_array.size() > 0;
- if (indexed)
- deindex();
-
SMikkTSpaceInterface mkif;
mkif.m_getNormal = mikktGetNormal;
mkif.m_getNumFaces = mikktGetNumFaces;
@@ -839,24 +874,25 @@ void SurfaceTool::generate_tangents() {
SMikkTSpaceContext msc;
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;
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().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);
ERR_FAIL_COND(!res);
format |= Mesh::ARRAY_FORMAT_TANGENT;
-
- if (indexed) {
- index();
- }
}
void SurfaceTool::generate_normals(bool p_flip) {
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 459d399380..cc8599e90a 100644
--- a/scene/resources/surface_tool.h
+++ b/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 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 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,
const tbool bIsOrientationPreserving, const int iFace, const int iVert);