PeriDyno 1.0.0
Loading...
Searching...
No Matches
SplineConstraint.cu
Go to the documentation of this file.
1#include "SplineConstraint.h"
2
3#include "Topology/TriangleSet.h"
4#include <iostream>
5#include <sys/stat.h>
6#include "tinyobjloader/tiny_obj_loader.h"
7#include "GLSurfaceVisualModule.h"
8#include "math.h"
9
10namespace dyno
11{
12 IMPLEMENT_TCLASS(SplineConstraint, TDataType)
13
14 template<typename TDataType>
15 SplineConstraint<TDataType>::SplineConstraint()
16 : ModelEditing<TDataType>()
17 {
18 auto triSet = std::make_shared<TriangleSet<TDataType>>();
19
20 this->stateTopology()->setDataPtr(triSet);
21
22 auto module = std::make_shared<GLSurfaceVisualModule>();
23
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);
28 }
29
30 template<typename TDataType>
31 void SplineConstraint<TDataType>::resetStates()
32 {
33
34 Node::resetStates();
35
36 tempLength = 0;
37 updateTransform();
38 CurrentVelocity = 0;
39 }
40
41 template <typename Coord, typename Matrix>
42 __global__ void K_InitKernelFunctionMesh(
43 DArray<Coord> posArr,
44 DArray<Coord> posInit,
45 Coord center,
46 Coord centerInit,
47 Matrix rotation
48 )
49 {
50 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
51 if (pId >= posArr.size())
52 return;
53 Coord pos;
54 pos = posInit[pId] - centerInit;
55 pos = rotation * pos;
56 posArr[pId] = pos + center;
57
58 }
59
60
61 template<typename TDataType>
62 void SplineConstraint<TDataType>::updateStates()
63 {
64
65 updateTransform();
66
67
68 }
69
70
71
72 template<typename TDataType>
73 void SplineConstraint<TDataType>::updateTransform()
74 {
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();
81
82 if (this->varAccelerate()->getData())
83 {
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;
88
89 UpdateCurrentVelocity();
90 }
91 else
92 {
93 CurrentVelocity = this->varVelocity()->getData();
94 }
95
96 CArray<Coord> c_point1;
97 c_point1.assign(VertexIn);
98
99 CArray<Coord> c_point2;
100 c_point2.assign(VertexIn2);
101
102 int lengthV = VertexIn.size();
103 totalIndex = lengthV;
104
105 std::vector<Coord> vertices;
106 std::vector<TopologyModule::Triangle> triangle;
107
108 Real dt = this->stateTimeStep()->getData();
109 tempLength = tempLength + CurrentVelocity * dt;
110
111 double tlength = 0;
112 size_t P1 = 0;
113 size_t P2 = 1;
114 size_t P3 = 2;
115 double dis = 0;
116 double disP = 0;
117 bool update = false;
118 Coord offestLocation = Coord(0, 0, 0);
119
120 Coord Location1;
121 Vec3f Location2;
122 Vec3f LocationTemp1 = { 0,1,0 };
123
124 Quat<Real> q;
125 Quat<Real> q2;
126 Quat<Real> qrotator;
127
128 for (size_t i = 0; i < lengthV - 2; i++)
129 {
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)
132 {
133 tlength += ab.norm();
134 update = false;
135 }
136 else
137 {
138 dis = ab.norm() - (tlength - tempLength);
139
140
141 P1 = i;
142 P2 = i + 1;
143 P3 = i + 2;
144 disP = dis/ab.norm();
145
146 auto l = ab.normalize();
147
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])
149
150
151 Location2 = Vec3f(c_point1[P1][0], c_point1[P1][1], c_point1[P1][2]);
152
153 LocationTemp1 = Vec3f(c_point1[P2][0], c_point1[P2][1], c_point1[P2][2]);
154
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]);
158
159 getQuatFromVector(va, vb, q);
160 getQuatFromVector(vc, vb, q2);
161
162
163 SLerp(q, q2, disP,qrotator);
164 auto RV = [&](const Coord& v)->Coord
165 {
166 return qrotator.rotate(v);//
167 };
168
169 for (size_t k = 0; k < lengthV2; k++)
170 {
171
172 Location1 = { c_point2[k][0], c_point2[k][1], c_point2[k][2] };
173
174 Location1 = RV(Location1)+offestLocation;
175
176 vertices.push_back(Location1);
177
178 }
179 update = true;
180 break;
181 }
182
183 }
184 if (update)
185 {
186 triSet->setPoints(vertices);
187 triSet->setTriangles(TriIn);
188 triSet->update();
189 }
190
191 vertices.clear();
192
193 }
194
195 template<typename TDataType>
196 void SplineConstraint<TDataType>::SLerp(Quat<Real> a, Quat<Real> b, double t, Quat<Real>& out)
197 {
198 double cosHalfTheta = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
199 if (cosHalfTheta < 0.0F) {
200
201 cosHalfTheta = -cosHalfTheta;
202 b.x = -b.x;
203 b.y = -b.y;
204 b.z = -b.z;
205 b.w = -b.w;
206 }
207
208 double halfTheta = (double)acos((double)cosHalfTheta);
209 double sinHalfTheta = (double)sqrt((double)(1.0F - cosHalfTheta * cosHalfTheta));
210 double ratioA;
211 double ratioB;
212 if ((double)abs(sinHalfTheta) > 0.001F) {
213
214 double oneOverSinHalfTheta = 1.0F / sinHalfTheta;
215 ratioA = (double)sin((double)((1.0F - t) * halfTheta)) * oneOverSinHalfTheta;
216 ratioB = (double)sin((double)(t * halfTheta)) * oneOverSinHalfTheta;
217 }
218 else {
219
220 ratioA = 1.0F - t;
221 ratioB = t;
222 }
223
224
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);
229
230 out.normalize();
231
232
233
234 }
235
236 template<typename TDataType>
237 void SplineConstraint<TDataType>::getQuatFromVector(Vec3f va, Vec3f vb, Quat<Real>& q)
238 {
239
240 va.normalize();
241 vb.normalize();
242
243 Vec3f v = va.cross(vb);
244 Vec3f vs = va.cross(vb);
245 v.normalize();
246
247 float ca = vb.dot(va);
248
249 float scale = 1 - ca;
250
251 Vec3f vt = Vec3f(v[0] * scale, v[1] * scale, v[2] * scale);
252
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;
257 vt[0] *= v[1];
258 vt[2] *= v[0];
259 vt[1] *= v[2];
260
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];
267
268 q = Quat<Real>(rotationMatrix);
269
270
271 }
272
273 template<typename TDataType>
274 void SplineConstraint<TDataType>::UpdateCurrentVelocity()
275 {
276 Real dt = this->stateTimeStep()->getData();
277 float AcceleratedSpeed = this->varAcceleratedSpeed()->getData();
278 float MaxSpeed = this->varVelocity()->getData();
279
280 if (CurrentVelocity + AcceleratedSpeed *dt < MaxSpeed )
281 {
282 CurrentVelocity = CurrentVelocity + AcceleratedSpeed * dt;
283 }
284 else
285 {
286 CurrentVelocity = MaxSpeed;
287 }
288
289 }
290
291
292
293 DEFINE_CLASS(SplineConstraint);
294}