1#include "TriangularMeshConstraint.h"
3#include "Primitive/Primitive3D.h"
4#include "Primitive/PrimitiveSweep3D.h"
8 IMPLEMENT_TCLASS(TriangularMeshConstraint, TDataType)
10 template<typename TDataType>
11 TriangularMeshConstraint<TDataType>::TriangularMeshConstraint()
16 template<typename TDataType>
17 TriangularMeshConstraint<TDataType>::~TriangularMeshConstraint()
21 mPreviousPosition.clear();
22 mPrivousVertex.clear();
25 template<typename Real, typename Coord>
26 __global__ void TMC_MeshConstrain(
27 DArray<Coord> particle_position,
28 DArray<Coord> particle_velocity,
29 DArray<Coord> particle_position_previous,
30 DArray<Coord> triangle_vertex,
31 DArray<Coord> triangle_vertex_previous,
32 DArray<TopologyModule::Triangle> triangle_index,
33 DArrayList<int> triangle_neighbors,
35 Real friction_tangent,
36 Real thickness, //thickness of the boundary
39 typedef typename ::dyno::TPoint3D<Real> Point3D;
40 typedef typename ::dyno::TTriangle3D<Real> Triangle3D;
41 typedef typename ::dyno::TPointSweep3D<Real> PointSweep3D;
43 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
44 if (pId >= particle_position.size()) return;
46 List<int>& nbrTriIds_i = triangle_neighbors[pId];
47 int nbrSize = nbrTriIds_i.size();
49 Coord pos_i = particle_position[pId];
50 Coord pos_i_old = particle_position_previous[pId];
51 Coord vel_i = particle_velocity[pId];
53 Point3D point_start(pos_i_old);
54 Point3D point_end(pos_i);
55 PointSweep3D ptSweep(point_start, point_end);
60 Coord weighted_pos(0);
61 Coord weighted_normal(0);
64 for (int ne = 0; ne < nbrSize; ne++)
66 int j = nbrTriIds_i[ne];
68 Triangle3D triangle_start(triangle_vertex_previous[triangle_index[j][0]], triangle_vertex_previous[triangle_index[j][1]], triangle_vertex_previous[triangle_index[j][2]]);
69 Triangle3D triangle_end(triangle_vertex[triangle_index[j][0]], triangle_vertex[triangle_index[j][1]], triangle_vertex[triangle_index[j][2]]);
71 TriangleSweep3D triSweep(triangle_start, triangle_end);
75// typename Triangle3D::Param baryc;
76// bool intersected = ptSweep.intersect(triSweep, baryc, t);
78// //If the particle intersects a triangle according to CCD, move its position back to the middle point
79// point_end = ptSweep.interpolate(t / 2);
82 TPoint3D<Real> proj_end = point_end.project(triangle_end);
84 Real dist_end = (proj_end.origin - point_end.origin).norm();
86 if (dist_end <= thickness)
88 Coord dir_j = point_end.origin - proj_end.origin;
90 if (dir_j.norm() > REAL_EPSILON) {
94 Coord newpos = proj_end.origin + dir_j * thickness;
96 weighted_normal += dir_j;
97 weighted_pos += newpos;
105 //Calculate a weighted displacement
107 weighted_normal /= num;
109 particle_position[pId] = weighted_pos;
111 vel_i += (weighted_pos - pos_i) / dt;
113 Real vel_mag_i = vel_i.dot(weighted_normal);
114 Coord vel_norm_i = vel_mag_i * weighted_normal;
115 Coord vel_tan_i = vel_i - vel_norm_i;
116 vel_norm_i *= (1.0f - friction_normal);
117 vel_tan_i *= (1.0f - friction_tangent);
119 particle_velocity[pId] = vel_norm_i + vel_tan_i;
123 template<typename TDataType>
124 void TriangularMeshConstraint<TDataType>::constrain()
126 Real thickness = this->varThickness()->getValue();
128 Real dt = this->inTimeStep()->getValue();
130 auto& positions = this->inPosition()->getData();
131 auto& velocities = this->inVelocity()->getData();
133 auto ts = this->inTriangleSet()->constDataPtr();
135 auto& vertices = ts->getPoints();
136 auto& triangles = ts->getTriangles();
138 auto& neighborIds = this->inTriangleNeighborIds()->getData();
140 int p_num = positions.size();
141 if (p_num == 0) return;
143 if (positions.size() != mPosBuffer.size()) {
144 mPosBuffer.resize(p_num);
145 mPreviousPosition.assign(positions);
148 mPrivousVertex.assign(vertices);
150 if (neighborIds.size() > 0) {
160 this->varNormalFriction()->getValue(),
161 this->varTangentialFriction()->getValue(),
166 mPrivousVertex.assign(vertices);
167 mPreviousPosition.assign(positions);
170 DEFINE_CLASS(TriangularMeshConstraint);