| 284 | } |
| 285 | |
| 286 | void TetModel::updateVisMesh(const ParticleData &pd) |
| 287 | { |
| 288 | if (m_attachments.size() == 0) |
| 289 | return; |
| 290 | |
| 291 | // The collision mesh is the boundary of the tet mesh |
| 292 | unsigned int *faces = m_surfaceMesh.getFaces().data(); |
| 293 | const unsigned int nFaces = m_surfaceMesh.numFaces(); |
| 294 | |
| 295 | const Vector3r *normals = m_surfaceMesh.getVertexNormals().data(); |
| 296 | |
| 297 | #pragma omp parallel default(shared) |
| 298 | { |
| 299 | #pragma omp for schedule(static) |
| 300 | for (int i = 0; i < (int) m_attachments.size(); i++) |
| 301 | { |
| 302 | const unsigned int pindex = m_attachments[i].m_index; |
| 303 | const unsigned int triindex = m_attachments[i].m_triIndex; |
| 304 | const Real *bary = m_attachments[i].m_bary; |
| 305 | |
| 306 | const unsigned int indexA = faces[3 * triindex] + m_indexOffset; |
| 307 | const unsigned int indexB = faces[3 * triindex + 1] + m_indexOffset; |
| 308 | const unsigned int indexC = faces[3 * triindex + 2] + m_indexOffset; |
| 309 | |
| 310 | const Vector3r &a = pd.getPosition(indexA); |
| 311 | const Vector3r &b = pd.getPosition(indexB); |
| 312 | const Vector3r &c = pd.getPosition(indexC); |
| 313 | Vector3r p2 = bary[0] * a + bary[1] * b + bary[2] * c; |
| 314 | Vector3r n = bary[0] * normals[faces[3 * triindex]] + bary[1] * normals[faces[3 * triindex + 1]] + bary[2] * normals[faces[3 * triindex + 2]]; |
| 315 | n.normalize(); |
| 316 | |
| 317 | Vector3r &p = m_visVertices.getPosition(pindex); |
| 318 | p = p2 - n*m_attachments[i].m_dist; |
| 319 | } |
| 320 | } |
| 321 | |
| 322 | m_visMesh.updateNormals(m_visVertices, 0); |
| 323 | m_visMesh.updateVertexNormals(m_visVertices); |
| 324 | } |
| 325 | |
| 326 | |
| 327 | bool TetModel::pointInTriangle(const Vector3r& p0, const Vector3r& p1, const Vector3r& p2, const Vector3r& p, |
no test coverage detected