* @brief Compute a transformation matrix to convert coordinates in world space coordinates into the triangle space. * The triangle space is define by the Z-axis as the normal of the triangle, * the X-axis aligned with the horizontal line in the texture file (using texture/UV coordinates). * * @param[in] mesh: input mesh * @param[in] f: facet/triangle index * @param[in] triPts: UV Coordinates
| 230 | * @return Rotation matrix to convert from world space coordinates in the triangle space |
| 231 | */ |
| 232 | inline Eigen::Matrix3d computeTriangleTransform(const Mesh& mesh, int f, const Point2d* triPts) |
| 233 | { |
| 234 | const Eigen::Vector3d p0 = toEigen((mesh.pts)[(mesh.tris)[f].v[0]]); |
| 235 | const Eigen::Vector3d p1 = toEigen((mesh.pts)[(mesh.tris)[f].v[1]]); |
| 236 | const Eigen::Vector3d p2 = toEigen((mesh.pts)[(mesh.tris)[f].v[2]]); |
| 237 | |
| 238 | const Eigen::Vector3d tX = (p1 - p0).normalized(); // edge0 => local triangle X-axis |
| 239 | const Eigen::Vector3d N = tX.cross((p2 - p0).normalized()).normalized(); // cross(edge0, edge1) => Z-axis |
| 240 | |
| 241 | // Correct triangle X-axis to be align with X-axis in the texture |
| 242 | const GEO::vec2 t0 = GEO::vec2(triPts[0].m); |
| 243 | const GEO::vec2 t1 = GEO::vec2(triPts[1].m); |
| 244 | const GEO::vec2 tV = GEO::normalize(t1 - t0); |
| 245 | const GEO::vec2 origNormal(1.0, 0.0); // X-axis in the texture |
| 246 | const double tAngle = GEO::Geom::angle(tV, origNormal); |
| 247 | Eigen::Matrix3d transform(Eigen::AngleAxisd(tAngle, N).toRotationMatrix()); |
| 248 | // Rotate triangle v0v1 axis around Z-axis, to get a X axis aligned with the 2d texture |
| 249 | Eigen::Vector3d X = (transform * tX).normalized(); |
| 250 | |
| 251 | const Eigen::Vector3d Y = N.cross(X).normalized(); // Y-axis |
| 252 | |
| 253 | Eigen::Matrix3d m; |
| 254 | m.col(0) = X; |
| 255 | m.col(1) = Y; |
| 256 | m.col(2) = N; |
| 257 | // const Eigen::Matrix3d mInv = m.inverse(); |
| 258 | const Eigen::Matrix3d mT = m.transpose(); |
| 259 | |
| 260 | return mT; |
| 261 | } |
| 262 | |
| 263 | inline void computeNormalHeight(const GEO::Mesh& mesh, |
| 264 | double orientation, |
no test coverage detected