1#include "SplineConstraint.h"
3#include "Topology/TriangleSet.h"
6#include "tinyobjloader/tiny_obj_loader.h"
7#include "GLSurfaceVisualModule.h"
12 IMPLEMENT_TCLASS(SplineConstraint, TDataType)
14 template<typename TDataType>
15 SplineConstraint<TDataType>::SplineConstraint()
16 : ModelEditing<TDataType>()
18 auto triSet = std::make_shared<TriangleSet<TDataType>>();
20 this->stateTopology()->setDataPtr(triSet);
22 auto module = std::make_shared<GLSurfaceVisualModule>();
24 module->setColor(Color(0.8, 0.52, 0.25));
25 module->setVisible(true);
26 this->stateTopology()->connect(module->inTriangleSet());
27 this->graphicsPipeline()->pushModule(module);
30 template<typename TDataType>
31 void SplineConstraint<TDataType>::resetStates()
41 template <typename Coord, typename Matrix>
42 __global__ void K_InitKernelFunctionMesh(
44 DArray<Coord> posInit,
50 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
51 if (pId >= posArr.size())
54 pos = posInit[pId] - centerInit;
56 posArr[pId] = pos + center;
61 template<typename TDataType>
62 void SplineConstraint<TDataType>::updateStates()
72 template<typename TDataType>
73 void SplineConstraint<TDataType>::updateTransform()
75 auto triSet = TypeInfo::cast<TriangleSet<TDataType>>(this->stateTopology()->getDataPtr());
76 //auto Velocity = this->varVelocity()->getData();
77 auto VertexIn = this->inSpline()->getData().getPoints();
78 auto VertexIn2 = this->inTriangleSet()->getData().getPoints();
79 auto lengthV2 = this->inTriangleSet()->getData().getPointSize();
80 auto TriIn = this->inTriangleSet()->getData().getTriangles();
82 if (this->varAccelerate()->getData())
84 int sa = this->stateFrameNumber()->getData();
85 std::cout << "CurrentFrame" << sa << std::endl;
86 float st = this->stateElapsedTime()->getData();
87 std::cout << "CurrentTime" << st << std::endl;
89 UpdateCurrentVelocity();
93 CurrentVelocity = this->varVelocity()->getData();
96 CArray<Coord> c_point1;
97 c_point1.assign(VertexIn);
99 CArray<Coord> c_point2;
100 c_point2.assign(VertexIn2);
102 int lengthV = VertexIn.size();
103 totalIndex = lengthV;
105 std::vector<Coord> vertices;
106 std::vector<TopologyModule::Triangle> triangle;
108 Real dt = this->stateTimeStep()->getData();
109 tempLength = tempLength + CurrentVelocity * dt;
118 Coord offestLocation = Coord(0, 0, 0);
122 Vec3f LocationTemp1 = { 0,1,0 };
128 for (size_t i = 0; i < lengthV - 2; i++)
130 Vec3f ab = Vec3f(c_point1[i + 1][0] - c_point1[i][0], c_point1[i + 1][1] - c_point1[i][1], c_point1[i + 1][2] - c_point1[i][2]);
131 if (tlength < tempLength)
133 tlength += ab.norm();
138 dis = ab.norm() - (tlength - tempLength);
144 disP = dis/ab.norm();
146 auto l = ab.normalize();
148 offestLocation = Coord(c_point1[i][0]+dis*l[0], c_point1[i][1] + dis * l[1], c_point1[i][2] + dis * l[2]) ;//+ Coord(dis * l[0], dis * l[1], dis * l[2])
151 Location2 = Vec3f(c_point1[P1][0], c_point1[P1][1], c_point1[P1][2]);
153 LocationTemp1 = Vec3f(c_point1[P2][0], c_point1[P2][1], c_point1[P2][2]);
155 Vec3f vb = Vec3f(0, 1, 0);
156 Vec3f va = LocationTemp1 - Location2;
157 Vec3f vc = Vec3f(c_point1[P3][0], c_point1[P3][1], c_point1[P3][2]) - Vec3f(c_point1[P2][0], c_point1[P2][1], c_point1[P2][2]);
159 getQuatFromVector(va, vb, q);
160 getQuatFromVector(vc, vb, q2);
163 SLerp(q, q2, disP,qrotator);
164 auto RV = [&](const Coord& v)->Coord
166 return qrotator.rotate(v);//
169 for (size_t k = 0; k < lengthV2; k++)
172 Location1 = { c_point2[k][0], c_point2[k][1], c_point2[k][2] };
174 Location1 = RV(Location1)+offestLocation;
176 vertices.push_back(Location1);
186 triSet->setPoints(vertices);
187 triSet->setTriangles(TriIn);
195 template<typename TDataType>
196 void SplineConstraint<TDataType>::SLerp(Quat<Real> a, Quat<Real> b, double t, Quat<Real>& out)
198 double cosHalfTheta = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
199 if (cosHalfTheta < 0.0F) {
201 cosHalfTheta = -cosHalfTheta;
208 double halfTheta = (double)acos((double)cosHalfTheta);
209 double sinHalfTheta = (double)sqrt((double)(1.0F - cosHalfTheta * cosHalfTheta));
212 if ((double)abs(sinHalfTheta) > 0.001F) {
214 double oneOverSinHalfTheta = 1.0F / sinHalfTheta;
215 ratioA = (double)sin((double)((1.0F - t) * halfTheta)) * oneOverSinHalfTheta;
216 ratioB = (double)sin((double)(t * halfTheta)) * oneOverSinHalfTheta;
225 out.x = (float)(ratioA * a.x + ratioB * b.x);
226 out.y = (float)(ratioA * a.y + ratioB * b.y);
227 out.z = (float)(ratioA * a.z + ratioB * b.z);
228 out.w = (float)(ratioA * a.w + ratioB * b.w);
236 template<typename TDataType>
237 void SplineConstraint<TDataType>::getQuatFromVector(Vec3f va, Vec3f vb, Quat<Real>& q)
243 Vec3f v = va.cross(vb);
244 Vec3f vs = va.cross(vb);
247 float ca = vb.dot(va);
249 float scale = 1 - ca;
251 Vec3f vt = Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);
253 SquareMatrix<Real, 3>rotationMatrix;
254 rotationMatrix(0, 0) = vt[0] * v[0] + ca;
255 rotationMatrix(1, 1) = vt[1] * v[1] + ca;
256 rotationMatrix(2, 2) = vt[2] * v[2] + ca;
261 rotationMatrix(0, 1) = vt[0] - vs[2];
262 rotationMatrix(0, 2) = vt[2] + vs[1];
263 rotationMatrix(1, 0) = vt[0] + vs[2];
264 rotationMatrix(1, 2) = vt[1] - vs[0];
265 rotationMatrix(2, 0) = vt[2] - vs[1];
266 rotationMatrix(2, 1) = vt[1] + vs[0];
268 q = Quat<Real>(rotationMatrix);
273 template<typename TDataType>
274 void SplineConstraint<TDataType>::UpdateCurrentVelocity()
276 Real dt = this->stateTimeStep()->getData();
277 float AcceleratedSpeed = this->varAcceleratedSpeed()->getData();
278 float MaxSpeed = this->varVelocity()->getData();
280 if (CurrentVelocity + AcceleratedSpeed *dt < MaxSpeed )
282 CurrentVelocity = CurrentVelocity + AcceleratedSpeed * dt;
286 CurrentVelocity = MaxSpeed;
293 DEFINE_CLASS(SplineConstraint);