PeriDyno 1.0.0
Loading...
Searching...
No Matches
CapsuleModel.cpp
Go to the documentation of this file.
1#include "CapsuleModel.h"
2
4
8
9#include "Mapping/Extract.h"
10#include "Topology/EdgeSet.h"
11#include <memory>
12
13struct Index2D
14{
15 Index2D() : x(), y() {}
16 Index2D(int x, int y) : x(x), y(y) {}
17 int x, y;
18};
19
20bool operator<(const Index2D& lhs, const Index2D& rhs)
21{
22 return lhs.x != rhs.x ? lhs.x < rhs.x : lhs.y < rhs.y;
23}
24
25namespace dyno
26{
27 template<typename TDataType>
29 : BasicShape<TDataType>()
30 {
31 this->varRadius()->setRange(0.001f, 100.0f);
32
33 this->stateTriangleSet()->setDataPtr(std::make_shared<TriangleSet<TDataType>>());
34
35 this->statePolygonSet()->setDataPtr(std::make_shared<PolygonSet<TDataType>>());
36
37 this->stateCenterLine()->setDataPtr(std::make_shared<EdgeSet<TDataType>>());
38
39 this->varLatitude()->setRange(2, 10000);
40 this->varLongitude()->setRange(3, 10000);
41 this->varHeight()->setRange(0, 100);
42 this->varHeightSegment()->setRange(1, 10000);
43
44 auto callback = std::make_shared<FCallBackFunc>(std::bind(&CapsuleModel<TDataType>::varChanged, this));
45
46
47 this->varLocation()->attach(callback);
48 this->varScale()->attach(callback);
49 this->varRotation()->attach(callback);
50 this->varRadius()->attach(callback);
51 this->varLatitude()->attach(callback);
52 this->varLongitude()->attach(callback);
53
54 auto tsRender = std::make_shared<GLSurfaceVisualModule>();
55 tsRender->setVisible(true);
56 this->stateTriangleSet()->connect(tsRender->inTriangleSet());
57 this->graphicsPipeline()->pushModule(tsRender);
58
59 auto exES = std::make_shared<ExtractEdgeSetFromPolygonSet<TDataType>>();
60 this->statePolygonSet()->connect(exES->inPolygonSet());
61 this->graphicsPipeline()->pushModule(exES);
62
63 auto clRender = std::make_shared<GLWireframeVisualModule>();
64 clRender->varBaseColor()->setValue(Color(46.f / 255.f , 107.f / 255.f, 202.f / 255.f));
65 clRender->varLineWidth()->setValue(1.f);
66 clRender->varRenderMode()->setCurrentKey(GLWireframeVisualModule::CYLINDER);
67
68 this->stateCenterLine()->connect(clRender->inEdgeSet());
69 this->graphicsPipeline()->pushModule(clRender);
70
71 auto esRender = std::make_shared<GLWireframeVisualModule>();
72 esRender->varBaseColor()->setValue(Color(0, 0, 0));
73 exES->outEdgeSet()->connect(esRender->inEdgeSet());
74 this->graphicsPipeline()->pushModule(esRender);
75
76 this->stateTriangleSet()->promoteOuput();
77 this->statePolygonSet()->promoteOuput();
78
79 }
80
81 template<typename TDataType>
86
87 template<typename TDataType>
89 {
90 auto center = this->varLocation()->getData();
91 auto rot = this->varRotation()->getData();
92 auto scale = this->varScale()->getData();
93
94 auto radius = this->varRadius()->getData();
95
96 Coord length(radius);
97 length[0] *= scale[0];
98 length[1] *= scale[1];
99 length[2] *= scale[2];
100
101 Quat<Real> q = this->computeQuaternion();
102
103 q.normalize();
104
106 box.center = center;
107 box.u = q.rotate(Coord(1, 0, 0));
108 box.v = q.rotate(Coord(0, 1, 0));
109 box.w = q.rotate(Coord(0, 0, 1));
110 box.extent = length;
111
112 auto AABB = box.aabb();
113 auto& v0 = AABB.v0;
114 auto& v1 = AABB.v1;
115
116
117 NBoundingBox ret;
118 ret.lower = Vec3f(v0.x, v0.y, v0.z);
119 ret.upper = Vec3f(v1.x, v1.y, v1.z);
120
121 return ret;
122 }
123
124
125
126
127 template<typename TDataType>
129 {
130 auto center = this->varLocation()->getValue();
131 auto rot = this->varRotation()->getValue();
132 auto scale = this->varScale()->getValue();
133
134 auto radius = this->varRadius()->getValue();
135 auto latitude = this->varLatitude()->getValue();
136 auto longitude = this->varLongitude()->getValue();
137 Real halfHeight = this->varHeight()->getValue() / 2;
138 auto row = this->varHeightSegment()->getValue();
139
140 Quat<Real> q = this->computeQuaternion();
141
142 //Setup a capsule primitive
143 TCapsule3D<Real> capsulePrim = TCapsule3D<Real>(center, q, radius, halfHeight);
144
145 this->outCapsule()->setValue(capsulePrim);
146
147 auto polySet = this->statePolygonSet()->getDataPtr();
148
149 std::vector<Coord> vertices;
150 std::map<Index2D, uint> index_ID;
151 std::map<Index2D, Coord> index_Coord;
152
153 {
154 Real deltaTheta = M_PI / latitude;
155 Real deltaPhi = 2 * M_PI / longitude;
156
157 //Setup vertices
158 Real theta = 0;
159
160 vertices.push_back(Coord(0, radius + halfHeight, 0));
161
162 for (uint i = 0; i < (latitude) / 2; i++)
163 {
164 theta += deltaTheta;
165
166 Real tempheight = i <= (latitude) / 2 ? halfHeight : - halfHeight;
167
168 Real phi = 0;
169 for (uint j = 0; j < longitude; j++)
170 {
171 phi += deltaPhi;
172
173 Real y = radius * std::cos(theta) + tempheight;
174 Real x = (std::sin(theta) * radius) * std::sin(phi);
175 Real z = (std::sin(theta) * radius) * std::cos(phi);
176
177 vertices.push_back(Coord(x, y, z));
178
179 if (i == latitude / 2 - 1)
180 {
181 Index2D RC = Index2D(row,j);
182 index_ID[RC] = vertices.size() - 1;
183
184 index_Coord[RC] = Coord(x, y, z);
185 }
186 }
187
188 }
189
190 uint halfVtNum = vertices.size();
191 for (size_t i = 0; i < halfVtNum; i++)
192 {
193 vertices.push_back(Coord(vertices[i][0], - vertices[i][1], vertices[i][2]));
194 }
195
196 for (auto list : index_ID)
197 {
198 auto f = list.first;
199 auto s = list.second;
200 Index2D RC = Index2D(0, f.y);
201 index_ID[RC] = s + halfVtNum;
202 }
203
204 theta = 0;
205
206 for (int i = 0; i <= row ; i++)
207 {
208 Real tempy = halfHeight * 2 / row * i - halfHeight;
209 theta += deltaTheta;
210
211
212 if (i != 0 && i != row )
213 {
214 Real phi = deltaPhi * longitude;
215
216 for (int j = 0; j < longitude; j++) {
217 Index2D RC = Index2D(i, j);
218
219 Coord v = index_Coord.find(Index2D(row,j))->second;
220 v = Coord(v[0], tempy,v[2]);
221
222 vertices.push_back(v);
223
224 index_ID[RC] = vertices.size() - 1;
225 }
226 }
227 }
228
229
230 //Setup polygon indices
231 uint numOfPolygon = 0;
232
233 if (latitude % 2)
234 numOfPolygon = latitude * longitude + row * longitude - longitude;
235 else
236 numOfPolygon = latitude * longitude + row * longitude;
237
238
239 CArray<uint> counter(numOfPolygon);
240
241
242 uint incre = 0;
243
244 //up
245 for (uint j = 0; j < longitude; j++)
246 {
247 counter[incre] = 3;
248 incre++;
249 }
250
251 for (uint i = 0; i < std::floor((latitude - 2)/2); i++)
252 {
253 for (uint j = 0; j < longitude; j++)
254 {
255 counter[incre] = 4;
256 incre++;
257 }
258 }
259 //down
260 for (uint j = 0; j < longitude; j++)
261 {
262 counter[incre] = 3;
263 incre++;
264 }
265
266 for (uint i = 0; i < std::floor((latitude - 2) / 2); i++)
267 {
268 for (uint j = 0; j < longitude; j++)
269 {
270 counter[incre] = 4;
271 incre++;
272 }
273 }
274
275 //side
276 for (uint i = 0; i < row; i++)
277 {
278 for (uint j = 0; j < longitude; j++)
279 {
280 counter[incre] = 4;
281 incre++;
282 }
283 }
284
285
286
287 CArrayList<uint> polygonIndices;
288 polygonIndices.resize(counter);
289
290 incre = 0;
291 uint offset = 1;
292
293
294 for (uint j = 0; j < longitude; j++)
295 {
296 auto& index = polygonIndices[incre];
297 index.insert(0);
298 index.insert(offset + j);
299 index.insert(offset + (j + 1) % longitude);
300
301 incre++;
302 }
303
304 for (uint i = 0; i < (latitude - 2)/2; i++)
305 {
306 for (uint j = 0; j < longitude; j++)
307 {
308 auto& index = polygonIndices[incre];
309 index.insert(offset + j);
310 index.insert(offset + j + longitude);
311 index.insert(offset + (j + 1) % longitude + longitude);
312 index.insert(offset + (j + 1) % longitude);
313
314 incre++;
315 }
316 offset += longitude;
317 }
318
319 for (size_t i = 0; i < incre; i++)
320 {
321 auto& source = polygonIndices[i];
322 auto& index = polygonIndices[i + incre];
323
324 for (size_t j = 0; j < source.size(); j++)
325 {
326 uint N = source.size() - 1;
327 index.insert(source[N - j] + halfVtNum);
328
329 }
330
331 }
332
333 //side
334 incre = incre * 2;
335 for (size_t i = 0; i < row ; i++)
336 {
337 for (size_t j = 0; j < longitude; j++)
338 {
339 auto& index = polygonIndices[incre];
340 index.insert(index_ID.find(Index2D(i, (j + 1) % longitude))->second);
341 index.insert(index_ID.find(Index2D(i + 1, (j + 1) % longitude))->second);
342 index.insert(index_ID.find(Index2D(i + 1, j))->second);
343 index.insert(index_ID.find(Index2D(i, j))->second);
344
345 incre++;
346 }
347 }
348
349
350 //Apply transformation
351 Quat<Real> q = this->computeQuaternion();
352
353 auto RV = [&](const Coord& v)->Coord {
354 return center + q.rotate(v - center);
355 };
356
357 int numpt = vertices.size();
358
359 for (int i = 0; i < numpt; i++) {
360 vertices[i] = RV(vertices[i] * scale + RV(center));
361 }
362
363 polySet->setPoints(vertices);
364 polySet->setPolygons(polygonIndices);
365 polySet->update();
366
367 polygonIndices.clear();
368 }
369
370
371 auto& ts = this->stateTriangleSet()->getData();
372 polySet->turnIntoTriangleSet(ts);
373
374 // Center Line
375 std::vector<TopologyModule::Edge> edges;
376 vertices.clear();
377 vertices.push_back(center + q.rotate(Coord(0, + halfHeight, 0)));
378 vertices.push_back(center + q.rotate(Coord(0, - halfHeight, 0)));
379 edges.push_back(TopologyModule::Edge(0, 1));
380
381 auto edgeSet = this->stateCenterLine()->getDataPtr();
382 edgeSet->setPoints(vertices);
383 edgeSet->setEdges(edges);
384 edgeSet->update();
385
386 edges.clear();
387 vertices.clear();
388 }
389
390
392}
bool operator<(const Index2D &lhs, const Index2D &rhs)
#define DEFINE_CLASS(name)
Definition Object.h:140
#define M_PI
Definition Typedef.inl:36
NBoundingBox boundingBox() override
TDataType::Coord Coord
TDataType::Real Real
void resetStates() override
std::shared_ptr< GraphicsPipeline > graphicsPipeline()
Definition Node.cpp:320
Quat< Real > computeQuaternion()
a class to store polygon whose vertex number is greater or equal than 3
Definition PolygonSet.h:29
DYN_FUNC Quat< Real > & normalize()
Definition Quat.inl:183
DYN_FUNC Vector< Real, 3 > rotate(const Vector< Real, 3 > &v) const
Rotate a vector by the quaternion, guarantee the quaternion is normalized before rotating the vector.
Definition Quat.inl:259
Coord3D u
three unit vectors u, v and w forming a right-handed orthornormal basis
Coord3D extent
half the dimension in each of the u, v, and w directions
Coord3D center
centerpoint
DYN_FUNC TAlignedBox3D< Real > aabb()
VectorND< PointType, 2 > Edge
#define N(x, y, z)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
ArrayList< T, DeviceType::CPU > CArrayList
Definition ArrayList.h:207
::dyno::TAlignedBox3D< Real > AABB
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
Array< T, DeviceType::CPU > CArray
Definition Array.h:151
unsigned int uint
Definition VkProgram.h:14
Index2D(int x, int y)