PeriDyno 1.0.0
Loading...
Searching...
No Matches
ConfigurableBody.cpp
Go to the documentation of this file.
1#include "ConfigurableBody.h"
2
3#include "Module/CarDriver.h"
4
5//Collision
8
9//RigidBody
14
15//Rendering
17
18namespace dyno
19{
20 //ConfigurableVehicle
22
23 template<typename TDataType>
25 : ParametricModel<TDataType>()
26 , ArticulatedBody<TDataType>()
27 {
28 auto elementQuery = std::make_shared<NeighborElementQuery<TDataType>>();
29 elementQuery->varSelfCollision()->setValue(false);
30 this->stateTopology()->connect(elementQuery->inDiscreteElements());
31 this->stateCollisionMask()->connect(elementQuery->inCollisionMask());
32 this->stateAttribute()->connect(elementQuery->inAttribute());
33 this->animationPipeline()->pushModule(elementQuery);
34
35 auto cdBV = std::make_shared<CollistionDetectionTriangleSet<TDataType>>();
36 this->stateTopology()->connect(cdBV->inDiscreteElements());
37 this->inTriangleSet()->connect(cdBV->inTriangleSet());
38 // auto cdBV = std::make_shared<CollistionDetectionBoundingBox<TDataType>>();
39 // this->stateTopology()->connect(cdBV->inDiscreteElements());
40 this->animationPipeline()->pushModule(cdBV);
41
42
43 auto merge = std::make_shared<ContactsUnion<TDataType>>();
44 elementQuery->outContacts()->connect(merge->inContactsA());
45 cdBV->outContacts()->connect(merge->inContactsB());
46 this->animationPipeline()->pushModule(merge);
47
48 auto iterSolver = std::make_shared<TJConstraintSolver<TDataType>>();
49 this->stateTimeStep()->connect(iterSolver->inTimeStep());
50 this->varFrictionEnabled()->connect(iterSolver->varFrictionEnabled());
51 this->varGravityEnabled()->connect(iterSolver->varGravityEnabled());
52 this->varGravityValue()->connect(iterSolver->varGravityValue());
53 //this->varFrictionCoefficient()->connect(iterSolver->varFrictionCoefficient());
54 this->varFrictionCoefficient()->setValue(20.0f);
55 this->varSlop()->connect(iterSolver->varSlop());
56 this->stateMass()->connect(iterSolver->inMass());
57 this->stateCenter()->connect(iterSolver->inCenter());
58 this->stateVelocity()->connect(iterSolver->inVelocity());
59 this->stateAngularVelocity()->connect(iterSolver->inAngularVelocity());
60 this->stateRotationMatrix()->connect(iterSolver->inRotationMatrix());
61 this->stateInertia()->connect(iterSolver->inInertia());
62 this->stateQuaternion()->connect(iterSolver->inQuaternion());
63 this->stateInitialInertia()->connect(iterSolver->inInitialInertia());
64
65 this->stateTopology()->connect(iterSolver->inDiscreteElements());
66
67 merge->outContacts()->connect(iterSolver->inContacts());
68
69 this->animationPipeline()->pushModule(iterSolver);
70
71 /*auto driver = std::make_shared<SimpleVechicleDriver>();
72
73 this->stateFrameNumber()->connect(driver->inFrameNumber());
74 this->stateInstanceTransform()->connect(driver->inInstanceTransform());
75
76 this->animationPipeline()->pushModule(driver);*/
77
78 this->inTriangleSet()->tagOptional(true);
79
80 // auto mapper = std::make_shared<DiscreteElementsToTriangleSet<DataType3f>>();
81 // this->stateTopology()->connect(mapper->inDiscreteElements());
82 // this->graphicsPipeline()->pushModule(mapper);
83 //
84 // auto sRender = std::make_shared<GLSurfaceVisualModule>();
85 // sRender->setColor(Color(0.3f, 0.5f, 0.9f));
86 // sRender->setAlpha(0.2f);
87 // sRender->setRoughness(0.7f);
88 // sRender->setMetallic(3.0f);
89 // mapper->outTriangleSet()->connect(sRender->inTriangleSet());
90 // this->graphicsPipeline()->pushModule(sRender);
91 // sRender->setVisible(false);
92
93 this->inTriangleSet()->tagOptional(true);
94 }
95
96 template<typename TDataType>
101
102 template<typename TDataType>
104 {
105 this->clearRigidBodySystem();
106 this->clearVechicle();
107
108 if (!this->inTextureMesh()->isEmpty())
109 {
110 this->stateTextureMesh()->setDataPtr(this->inTextureMesh()->constDataPtr());
111 }
112
113 if (!this->varVehicleConfiguration()->getValue().isValid() && !bool(this->varVehiclesTransform()->getValue().size()) || this->stateTextureMesh()->isEmpty())
114 return;
115
116 auto texMesh = this->stateTextureMesh()->constDataPtr();
117 const auto config = this->varVehicleConfiguration()->getValue();
118
119 const auto rigidInfo = config.mVehicleRigidBodyInfo;
120 const auto jointInfo = config.mVehicleJointInfo;
121
122 // **************************** Create RigidBody **************************** //
123 auto instances = this->varVehiclesTransform()->getValue();
124 uint vehicleNum = instances.size();
125 int maxGroup = 0;
126 for (size_t i = 0; i < rigidInfo.size(); i++)
127 {
128 if (rigidInfo[i].rigidGroup > maxGroup)
129 maxGroup = rigidInfo[i].rigidGroup;
130 }
131
132 for (size_t j = 0; j < vehicleNum; j++)
133 {
134
135
136 std::vector<std::shared_ptr<PdActor>> Actors;
137
138 Actors.resize(rigidInfo.size());
139
140
141 for (size_t i = 0; i < rigidInfo.size(); i++)
142 {
143 RigidBodyInfo rigidbody;
144 rigidbody.bodyId = j * (maxGroup + 1) + rigidInfo[i].rigidGroup;
145
146 rigidbody.offset = rigidInfo[i].Offset;
147 rigidbody.friction = this->varFrictionCoefficient()->getValue();
148
149 auto type = rigidInfo[i].shapeType;
150 auto shapeId = rigidInfo[i].meshShapeId;
151 auto transform = rigidInfo[i].transform;
152 Real density = rigidInfo[i].mDensity;
153
154 if (shapeId > texMesh->shapes().size() - 1)
155 continue;
156
157 Vec3f up;
158 Vec3f down;
159 Vec3f T;
160
161 if (shapeId != -1)
162 {
163 up = texMesh->shapes()[shapeId]->boundingBox.v1;
164 down = texMesh->shapes()[shapeId]->boundingBox.v0;
165 T = texMesh->shapes()[shapeId]->boundingTransform.translation();
166 }
167 else
168 {
169
170
171 }
172
173 BoxInfo currentBox;
174 CapsuleInfo currentCapsule;
175 SphereInfo currentSphere;
176 TetInfo currentTet;
177
178 if (shapeId != -1)
179 {
180 switch (type)
181 {
182 case dyno::Box:
183 currentBox.center = Vec3f(0.0f);
184 currentBox.halfLength = (up - down) / 2 * rigidInfo[i].mHalfLength;
185 currentBox.rot = Quat1f(transform.rotation());
186
187 rigidbody.position = Quat1f(instances[j].rotation()).rotate(T + rigidInfo[i].transform.translation()) + instances[j].translation();
188 rigidbody.angle = Quat1f(instances[j].rotation());
189 Actors[i] = this->addBox(currentBox, rigidbody, density);
190 break;
191
192 case dyno::Tet:
193 printf("Need Tet Configuration\n");
194 break;
195
196 case dyno::Capsule:
197 currentCapsule.center = Vec3f(0.0f);
198 currentCapsule.rot = Quat1f(transform.rotation());
199 currentCapsule.halfLength = (up.y - down.y) / 2 * rigidInfo[i].capsuleLength;
200 currentCapsule.radius = std::abs(up.y - down.y) / 2 * rigidInfo[i].radius;
201
202 rigidbody.position = Quat1f(instances[j].rotation()).rotate(T + rigidInfo[i].transform.translation()) + instances[j].translation();
203 rigidbody.angle = Quat1f(instances[j].rotation());
204 Actors[i] = this->addCapsule(currentCapsule, rigidbody, density);
205 break;
206
207 case dyno::Sphere:
208 currentSphere.center = Vec3f(0.0f);
209 currentSphere.rot = Quat1f(transform.rotation());
210 currentSphere.radius = std::abs(up.y - down.y) / 2 * rigidInfo[i].radius;
211
212 rigidbody.position = Quat1f(instances[j].rotation()).rotate(T + rigidInfo[i].transform.translation()) + instances[j].translation();
213 rigidbody.angle = Quat1f(instances[j].rotation());
214 Actors[i] = this->addSphere(currentSphere, rigidbody, density);
215 break;
216
217 case dyno::Tri:
218 printf("Need Tri Configuration\n");
219 Actors[i] = NULL;
220 break;
221
222 case dyno::OtherShape:
223 printf("Need OtherShape Configuration\n");
224 Actors[i] = NULL;
225 break;
226
227 default:
228 break;
229 }
230 }
231 else if (shapeId == -1)
232 {
233 switch (type)
234 {
235 case dyno::Box:
236 currentBox.center = Vec3f(0.0f);
237 currentBox.halfLength = rigidInfo[i].mHalfLength;
238 currentBox.rot = Quat<Real>(rigidInfo[i].transform.rotation());
239
240 rigidbody.position = Quat1f(instances[j].rotation()).rotate(rigidInfo[i].transform.translation()) + instances[j].translation();
241 rigidbody.angle = Quat1f(instances[j].rotation());
242 Actors[i] = this->addBox(currentBox, rigidbody, density);
243 break;
244
245 case dyno::Tet:
246 printf("Need Tet Configuration\n");
247 currentTet.v[0] = rigidInfo[i].tet[0];
248 currentTet.v[1] = rigidInfo[i].tet[1];
249 currentTet.v[2] = rigidInfo[i].tet[2];
250 currentTet.v[3] = rigidInfo[i].tet[3];
251
252 break;
253
254 case dyno::Capsule:
255 currentCapsule.center = Vec3f(0.0f);
256 currentCapsule.rot = Quat<Real>(rigidInfo[i].transform.rotation());
257 currentCapsule.halfLength = rigidInfo[i].capsuleLength;
258 currentCapsule.radius = rigidInfo[i].radius;
259
260 rigidbody.position = Quat1f(instances[j].rotation()).rotate(rigidInfo[i].transform.translation()) + instances[j].translation();
261 rigidbody.angle = Quat1f(instances[j].rotation());
262 Actors[i] = this->addCapsule(currentCapsule, rigidbody, density);
263 break;
264
265 case dyno::Sphere:
266 currentSphere.center = Vec3f(0.0f);
267 currentSphere.rot = Quat<Real>(rigidInfo[i].transform.rotation());
268 currentSphere.radius = rigidInfo[i].radius;
269
270 rigidbody.position = Quat1f(instances[j].rotation()).rotate(rigidInfo[i].transform.translation()) + instances[j].translation();
271 rigidbody.angle = Quat1f(instances[j].rotation());
272 Actors[i] = this->addSphere(currentSphere, rigidbody, density);
273 break;
274
275 case dyno::Tri:
276 printf("Need Tri Configuration\n");
277 break;
278
279 case dyno::OtherShape:
280 printf("Need OtherShape Configuration\n");
281 break;
282
283 default:
284 break;
285 }
286 }
287
288 if (shapeId != -1 && Actors[i] != NULL)
289 {
291 this->bind(Actors[i], Pair<uint, uint>(shapeId, j));
292
293 }
294 }
295
296 for (size_t i = 0; i < jointInfo.size(); i++)
297 {
299 auto type = jointInfo[i].mJointType;
300 int first = jointInfo[i].mRigidBodyName_1.rigidBodyId;
301 int second = jointInfo[i].mRigidBodyName_2.rigidBodyId;
302 Real speed = jointInfo[i].mMoter;
303 auto axis = Quat1f(instances[j].rotation()).rotate(jointInfo[i].mAxis);
304 auto anchorOffset = jointInfo[i].mAnchorPoint;
305
306 if (first == -1 || second == -1)
307 continue;
308 if (Actors[first] == NULL || Actors[second] == NULL)
309 continue;
310
311
312 if (type == Hinge)
313 {
314 auto& joint = this->createHingeJoint(Actors[first], Actors[second]);
315 joint.setAnchorPoint(Actors[first]->center + anchorOffset);
316 joint.setAxis(axis);
317 if (jointInfo[i].mUseMoter)
318 joint.setMoter(speed);
319 if (jointInfo[i].mUseRange)
320 joint.setRange(jointInfo[i].mMin, jointInfo[i].mMax);
321
322 }
323 if (type == Slider)
324 {
325 auto& sliderJoint = this->createSliderJoint(Actors[first], Actors[second]);
326 sliderJoint.setAnchorPoint((Actors[first]->center + Actors[first]->center) / 2 + anchorOffset);
327 sliderJoint.setAxis(axis);
328 if (jointInfo[i].mUseMoter)
329 sliderJoint.setMoter(speed);
330 if (jointInfo[i].mUseRange)
331 sliderJoint.setRange(jointInfo[i].mMin, jointInfo[i].mMax);
332 }
333 if (type == Fixed)
334 {
335 auto& fixedJoint1 = this->createFixedJoint(Actors[first], Actors[second]);
336 fixedJoint1.setAnchorPoint((Actors[first]->center + Actors[first]->center) / 2 + anchorOffset);
337 }
338 if (type == Point)
339 {
340 auto& pointJoint = this->createPointJoint(Actors[first]);
341 pointJoint.setAnchorPoint(Actors[first]->center + anchorOffset);
342 }
343 if (type == BallAndSocket)
344 {
345 auto& ballAndSocketJoint = this->createBallAndSocketJoint(Actors[first], Actors[second]);
346 ballAndSocketJoint.setAnchorPoint((Actors[first]->center + Actors[first]->center) / 2 + anchorOffset);
347 }
348
349 //Joint(Actor)
350
351
352
353
354 }
355 }
356
357
358 /***************** Reset *************/
360
362
364 }
365
367
368
369
370}
#define DEFINE_CLASS(name)
Definition Object.h:140
#define IMPLEMENT_TCLASS(name, T1)
Definition Object.h:103
void bind(std::shared_ptr< PdActor > actor, Pair< uint, uint > shapeId)
void resetStates() override
std::shared_ptr< AnimationPipeline > animationPipeline()
Definition Node.cpp:311
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
std::shared_ptr< PdActor > addBox(const BoxInfo &box, const RigidBodyInfo &bodyDef, const Real density=Real(100))
SliderJoint & createSliderJoint(std::shared_ptr< PdActor > actor1, std::shared_ptr< PdActor > actor2)
HingeJoint & createHingeJoint(std::shared_ptr< PdActor > actor1, std::shared_ptr< PdActor > actor2)
FixedJoint & createFixedJoint(std::shared_ptr< PdActor > actor1, std::shared_ptr< PdActor > actor2)
std::shared_ptr< PdActor > addCapsule(const CapsuleInfo &capsule, const RigidBodyInfo &bodyDef, const Real density=Real(100))
void postUpdateStates() override
PointJoint & createPointJoint(std::shared_ptr< PdActor > actor1)
std::shared_ptr< PdActor > addSphere(const SphereInfo &sphere, const RigidBodyInfo &bodyDef, const Real density=Real(100))
BallAndSocketJoint & createBallAndSocketJoint(std::shared_ptr< PdActor > actor1, std::shared_ptr< PdActor > actor2)
#define T(t)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
int joint
Definition GltfFunc.h:19
@ Point
Definition VehicleInfo.h:37
@ BallAndSocket
Definition VehicleInfo.h:33
@ Slider
Definition VehicleInfo.h:34
@ Hinge
Definition VehicleInfo.h:35
@ Fixed
Definition VehicleInfo.h:36
@ Sphere
Definition VehicleInfo.h:26
@ OtherShape
Definition VehicleInfo.h:28
@ Capsule
Definition VehicleInfo.h:25
Quat< float > Quat1f
Definition Quat.h:136
Vector< float, 3 > Vec3f
Definition Vector3D.h:93
unsigned int uint
Definition VkProgram.h:14
Quat< Real > rot
Vector< Real, 3 > halfLength
Vector< Real, 3 > center
Vector< Real, 3 > center
Vector< Real, 3 > offset
An offset from the barycenter to the geometric center.
Vector< Real, 3 > position
The barycenter of the body.
Quat< Real > rot
Vector< Real, 3 > center
Vector< Real, 3 > v[4]