diff --git a/Source/Geometry/Mesh/imstkPointSet.cpp b/Source/Geometry/Mesh/imstkPointSet.cpp index b2a1c7527642a0e4d29c7f354975b4de2a795e5f..702c81b67b10df8ca1338a6b510447eef97bc6b2 100644 --- a/Source/Geometry/Mesh/imstkPointSet.cpp +++ b/Source/Geometry/Mesh/imstkPointSet.cpp @@ -218,6 +218,17 @@ PointSet::getPointDataArray(const std::string& arrayName) const return &(it->second); } +bool +PointSet::hasPointDataArray(const std::string& arrayName) const +{ + auto it = m_pointDataMap.find(arrayName); + if (it == m_pointDataMap.end()) + { + return false; + } + return true; +} + size_t PointSet::getNumVertices() const { diff --git a/Source/Geometry/Mesh/imstkPointSet.h b/Source/Geometry/Mesh/imstkPointSet.h index 479336e455bfd9240c5eb5c620513d3370eebc54..3f7f2ddd2002f750a45e540f5d259fd888581f2d 100644 --- a/Source/Geometry/Mesh/imstkPointSet.h +++ b/Source/Geometry/Mesh/imstkPointSet.h @@ -144,6 +144,11 @@ public: /// const StdVectorOfVectorf* getPointDataArray(const std::string& arrayName) const; + /// + /// \brief Check if a specific data array exists. + /// + bool hasPointDataArray(const std::string& arrayName) const; + /// /// \brief Returns the number of total vertices in the mesh /// diff --git a/Source/Geometry/Mesh/imstkSurfaceMesh.cpp b/Source/Geometry/Mesh/imstkSurfaceMesh.cpp index 4ce703802bd01ae8583e95089f4c50d7d3ae6b52..b019a66b2929a54b8164fed93bae70d874fbbf89 100644 --- a/Source/Geometry/Mesh/imstkSurfaceMesh.cpp +++ b/Source/Geometry/Mesh/imstkSurfaceMesh.cpp @@ -62,6 +62,7 @@ SurfaceMesh::clear() m_vertexNeighborVertices.clear(); m_triangleNormals.clear(); m_vertexNormals.clear(); + m_triangleTangents.clear(); } void @@ -135,6 +136,7 @@ void SurfaceMesh::computeTrianglesNormals() { m_triangleNormals.resize(m_trianglesVertices.size()); + m_triangleTangents.resize(m_trianglesVertices.size()); for (size_t triangleId = 0; triangleId < m_triangleNormals.size(); ++triangleId) { @@ -145,6 +147,35 @@ SurfaceMesh::computeTrianglesNormals() m_triangleNormals.at(triangleId) = ((p1 - p0).cross(p2 - p0)).normalized(); } + + bool hasUVs = this->hasPointDataArray(m_defaultTCoords); + const StdVectorOfVectorf* UVs; + + if (hasUVs) + { + UVs = this->getPointDataArray(m_defaultTCoords); + } + + if (hasUVs) + { + for (size_t triangleId = 0; triangleId < m_triangleNormals.size(); ++triangleId) + { + const auto& t = m_trianglesVertices.at(triangleId); + const auto& p0 = m_vertexPositions.at(t.at(0)); + const auto& p1 = m_vertexPositions.at(t.at(1)); + const auto& p2 = m_vertexPositions.at(t.at(2)); + const auto& uv0 = (*UVs)[t.at(0)]; + const auto& uv1 = (*UVs)[t.at(1)]; + const auto& uv2 = (*UVs)[t.at(2)]; + + auto diffPos1 = p1 - p0; + auto diffPos2 = p2 - p0; + float diffUV1[2] = { uv1[0] - uv0[0], uv1[1] - uv0[1] }; + float diffUV2[2] = { uv2[0] - uv0[0], uv2[1] - uv0[1] }; + + m_triangleTangents.at(triangleId) = (diffPos1 * diffUV2[1] - diffPos2 * diffUV1[0]) / (diffUV1[0] * diffUV2[1] - diffUV1[1] * diffUV2[0]); + } + } } void @@ -158,21 +189,33 @@ SurfaceMesh::computeVertexNormals() } m_vertexNormals.resize(m_vertexPositions.size()); + m_vertexTangents.resize(m_vertexPositions.size()); this->computeTrianglesNormals(); StdVectorOfVec3d temp_normals(m_vertexNormals.size()); + StdVectorOfVec3d temp_tangents(m_vertexTangents.size()); for (size_t vertexId = 0; vertexId < m_vertexNormals.size(); ++vertexId) { temp_normals[vertexId] = Vec3d(0, 0, 0); + temp_tangents[vertexId] = Vec3d(0, 0, 0); for (const size_t& triangleId : m_vertexNeighborTriangles.at(vertexId)) { temp_normals[vertexId] += m_triangleNormals[triangleId]; + temp_tangents[vertexId] += m_triangleTangents[triangleId]; } } // Correct for UV seams - Vec3d normal; + Vec3d normal, tangent; + bool hasUVs = this->hasPointDataArray(m_defaultTCoords); + const StdVectorOfVectorf* UVs; + + if (hasUVs) + { + UVs = this->getPointDataArray(m_defaultTCoords); + } + for (size_t vertexId = 0; vertexId < m_vertexNormals.size(); ++vertexId) { NormalGroup group = {m_vertexPositions[vertexId], m_vertexNormals[vertexId]}; @@ -195,6 +238,13 @@ SurfaceMesh::computeVertexNormals() normal.normalize(); m_vertexNormals[vertexId] = normal; + + if (hasUVs) + { + tangent = temp_tangents[vertexId]; + tangent.normalize(); + m_vertexTangents[vertexId] = tangent; + } } } diff --git a/Source/Geometry/Mesh/imstkSurfaceMesh.h b/Source/Geometry/Mesh/imstkSurfaceMesh.h index e0438af10a27b33caeec8b099b41f5a733672592..f208c72167a61660bbdde8649bada2708c574912 100644 --- a/Source/Geometry/Mesh/imstkSurfaceMesh.h +++ b/Source/Geometry/Mesh/imstkSurfaceMesh.h @@ -236,6 +236,7 @@ protected: std::vector<NeighborsType> m_vertexNeighborVertices; ///> Neighbor vertices to vertices StdVectorOfVec3d m_triangleNormals; ///> Normals to the triangles + StdVectorOfVec3d m_triangleTangents; ///> Tangents to the triangles StdVectorOfVec3d m_vertexNormals; ///> Normals of the vertices StdVectorOfVec3d m_vertexTangents; ///> Tangents of the vertices diff --git a/Source/Rendering/VulkanRenderer/VulkanShaders/mesh/mesh_vert.vert b/Source/Rendering/VulkanRenderer/VulkanShaders/mesh/mesh_vert.vert index b80e71979c04a53fd472cf78c7c58ab459cfcc4c..c0b6d92db3d65c9328427756f99509a6f2c36c65 100644 --- a/Source/Rendering/VulkanRenderer/VulkanShaders/mesh/mesh_vert.vert +++ b/Source/Rendering/VulkanRenderer/VulkanShaders/mesh/mesh_vert.vert @@ -47,6 +47,7 @@ void main(void) vec4 tangent = normalize(locals.transform * vec4(normalize(vertexTangent), 0.0)); vec4 bitangent = vec4(cross(normal.xyz, tangent.xyz), 0.0); + tangent = vec4(cross(bitangent.xyz, normal.xyz), 0.0); vertex.TBN = mat3(tangent.xyz, bitangent.xyz, normal.xyz);