iMSTK
Interactive Medical Simulation Toolkit
pbdRigidBodyExample.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkCamera.h"
8 #include "imstkCapsule.h"
9 #include "imstkCompositeImplicitGeometry.h"
10 #include "imstkDirectionalLight.h"
11 #include "imstkGeometryUtilities.h"
12 #include "imstkImplicitGeometryToImageData.h"
13 #include "imstkKeyboardDeviceClient.h"
14 #include "imstkKeyboardSceneControl.h"
15 #include "imstkMouseDeviceClient.h"
16 #include "imstkMouseSceneControl.h"
17 #include "imstkOrientedBox.h"
18 #include "imstkPbdAngularConstraint.h"
19 #include "imstkPbdModel.h"
20 #include "imstkPbdModelConfig.h"
21 #include "imstkPbdObject.h"
22 #include "imstkPbdObjectCollision.h"
23 #include "imstkPlane.h"
24 #include "imstkRenderMaterial.h"
25 #include "imstkScene.h"
26 #include "imstkSceneManager.h"
27 #include "imstkSimulationManager.h"
28 #include "imstkSimulationUtils.h"
29 #include "imstkSphere.h"
30 #include "imstkSurfaceMeshFlyingEdges.h"
31 #include "imstkSurfaceMeshSubdivide.h"
32 #include "imstkVisualModel.h"
33 #include "imstkVTKViewer.h"
34 
35 using namespace imstk;
36 
40 static std::shared_ptr<PbdObject>
41 makeTissueObj(const std::string& name,
42  std::shared_ptr<PbdModel> model,
43  const double width,
44  const double height,
45  const int rowCount,
46  const int colCount,
47  const double particleMassValue,
48  const double distStiffness, const double bendStiffness)
49 {
50  // Setup the Geometry
51  std::shared_ptr<SurfaceMesh> tissueMesh =
52  GeometryUtils::toTriangleGrid(Vec3d::Zero(),
53  Vec2d(width, height), Vec2i(rowCount, colCount));
54 
55  // Setup the Parameters
56  model->getConfig()->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, distStiffness);
57  model->getConfig()->enableConstraint(PbdModelConfig::ConstraintGenType::Dihedral, bendStiffness);
58 
59  // Setup the VisualModel
60  auto material = std::make_shared<RenderMaterial>();
61  material->setBackFaceCulling(false);
62  material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
63  material->setShadingModel(RenderMaterial::ShadingModel::PBR);
64 
65  auto visualModel = std::make_shared<VisualModel>();
66  visualModel->setGeometry(tissueMesh);
67  visualModel->setRenderMaterial(material);
68 
69  // Setup the Object
70  auto pbdObject = std::make_shared<PbdObject>(name);
71  pbdObject->addVisualModel(visualModel);
72  pbdObject->setPhysicsGeometry(tissueMesh);
73  pbdObject->setCollidingGeometry(tissueMesh);
74  pbdObject->setDynamicalModel(model);
75 
76  pbdObject->getPbdBody()->uniformMassValue = particleMassValue;
77  for (int x = 0; x < rowCount; x++)
78  {
79  for (int y = 0; y < colCount; y++)
80  {
81  if (x == 0 || y == 0 || x == rowCount - 1 || y == colCount - 1)
82  {
83  pbdObject->getPbdBody()->fixedNodeIds.push_back(x * colCount + y);
84  }
85  }
86  }
87 
88  return pbdObject;
89 }
90 
91 static void
92 planeContactScene()
93 {
94  // Write log to stdout and file
96 
97  // Setup a scene
98  auto scene = std::make_shared<Scene>("PbdRigidBody");
99  scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
100  scene->getActiveCamera()->setPosition(-0.0237419, 0.0368787, 0.338374);
101  scene->getActiveCamera()->setViewUp(0.0, 1.0, 0.0);
102 
103  auto pbdModel = std::make_shared<PbdModel>();
104  auto pbdConfig = std::make_shared<PbdModelConfig>();
105  // Slightly larger gravity to compensate damping
106  pbdConfig->m_gravity = Vec3d(0.0, -9.8, 0.0);
107  pbdConfig->m_dt = 0.001;
108  pbdConfig->m_iterations = 10;
109  pbdConfig->m_linearDampingCoeff = 0.001;
110  pbdConfig->m_angularDampingCoeff = 0.001;
111  pbdConfig->m_doPartitioning = false;
112  pbdModel->configure(pbdConfig);
113 
114  auto planeObj = std::make_shared<CollidingObject>("plane");
115  auto planeGeom = std::make_shared<Plane>(Vec3d(0.0, 0.0, 0.0), Vec3d(0.0, 1.0, 0.0));
116  planeGeom->setWidth(1.0);
117  planeObj->setVisualGeometry(planeGeom);
118  planeObj->setCollidingGeometry(planeGeom);
119  scene->addSceneObject(planeObj);
120 
121  // Setup a capsule
122  auto rigidPbdObj = std::make_shared<PbdObject>("rigidPbdObj");
123  {
124  // Setup line geometry
125  //auto rigidGeom = std::make_shared<Sphere>(Vec3d(0.0, 0.0, 0.0), 0.5);
126  auto rigidGeom = std::make_shared<Capsule>(Vec3d(0.0, 0.0, 0.0), 0.05, 0.25);
127  std::shared_ptr<SurfaceMesh> surfMesh = GeometryUtils::toSurfaceMesh(rigidGeom);
128  rigidPbdObj->setVisualGeometry(surfMesh);
129  rigidPbdObj->setCollidingGeometry(surfMesh);
130  rigidPbdObj->setPhysicsGeometry(surfMesh);
131 
132  // Setup material
133  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setColor(Color(0.9, 0.0, 0.0));
134  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setShadingModel(RenderMaterial::ShadingModel::PBR);
135  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
136  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setRoughness(0.5);
137  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setMetalness(1.0);
138  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setIsDynamicMesh(false);
139 
140  rigidPbdObj->setDynamicalModel(pbdModel);
141 
142  // Setup body
143  const Quatd orientation = Quatd::FromTwoVectors(Vec3d(0.0, 1.0, 0.0), Vec3d(1.0, 1.0, 1.0).normalized());
144  rigidPbdObj->getPbdBody()->setRigid(Vec3d(0.0, 0.2, 0.0),
145  1.0, orientation, Mat3d::Identity() * 0.01);
146  }
147  scene->addSceneObject(rigidPbdObj);
148 
149  auto collision = std::make_shared<PbdObjectCollision>(rigidPbdObj, planeObj);
150  collision->setRigidBodyCompliance(0.000001);
151  scene->addSceneObject(collision);
152 
153  // Light
154  auto light = std::make_shared<DirectionalLight>();
155  light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
156  light->setIntensity(1.0);
157  scene->addLight("Light", light);
158 
159  // Run the simulation
160  {
161  // Setup a viewer to render
162  auto viewer = std::make_shared<VTKViewer>();
163  viewer->setVtkLoggerMode(VTKViewer::VTKLoggerMode::MUTE);
164  viewer->setActiveScene(scene);
165  viewer->setDebugAxesLength(0.01, 0.01, 0.01);
166 
167  // Setup a scene manager to advance the scene
168  auto sceneManager = std::make_shared<SceneManager>();
169  sceneManager->setActiveScene(scene);
170  sceneManager->pause(); // Start simulation paused
171 
172  auto driver = std::make_shared<SimulationManager>();
173  driver->addModule(viewer);
174  driver->addModule(sceneManager);
175  driver->setDesiredDt(0.001);
176 
177  {
178  // Add default mouse and keyboard controls to the viewer
179  std::shared_ptr<Entity> mouseAndKeyControls =
180  SimulationUtils::createDefaultSceneControl(driver);
181  scene->addSceneObject(mouseAndKeyControls);
182 
183  std::shared_ptr<KeyboardDeviceClient> keyDevice = viewer->getKeyboardDevice();
184  const Vec3d dx = scene->getActiveCamera()->getPosition() - scene->getActiveCamera()->getFocalPoint();
185  const double speed = 10.0;
186  connect<KeyEvent>(keyDevice, &KeyboardDeviceClient::keyPress, [&](KeyEvent* e)
187  {
188  if (e->m_key == 'f')
189  {
190  if (collision->getFriction() == 0.0)
191  {
192  collision->setFriction(0.5);
193  }
194  else
195  {
196  collision->setFriction(0.0);
197  }
198  }
199  });
200  connect<Event>(sceneManager, &SceneManager::postUpdate, [&](Event*)
201  {
202  Vec3d extForce = Vec3d(0.0, 0.0, 0.0);
203  Vec3d extTorque = Vec3d(0.0, 0.0, 0.0);
204  // If w down, move forward
205  if (keyDevice->getButton('i') == KEY_PRESS)
206  {
207  extForce += Vec3d(0.0, 0.0, -1.0) * speed;
208  }
209  if (keyDevice->getButton('k') == KEY_PRESS)
210  {
211  extForce += Vec3d(0.0, 0.0, 1.0) * speed;
212  }
213  if (keyDevice->getButton('j') == KEY_PRESS)
214  {
215  extForce += Vec3d(-1.0, 0.0, 0.0) * speed;
216  }
217  if (keyDevice->getButton('l') == KEY_PRESS)
218  {
219  extForce += Vec3d(1.0, 0.0, 0.0) * speed;
220  }
221  // Apply torque around global y
222  if (keyDevice->getButton('u') == KEY_PRESS)
223  {
224  extTorque += Vec3d(0.0, -0.1, 0.0);
225  }
226  if (keyDevice->getButton('o') == KEY_PRESS)
227  {
228  extTorque += Vec3d(0.0, 0.1, 0.0);
229  }
230  rigidPbdObj->getPbdBody()->externalForce = extForce;
231  rigidPbdObj->getPbdBody()->externalTorque = extTorque;
232  });
233  }
234 
235  driver->start();
236  }
237 }
238 
239 static void
240 bowlScene()
241 {
242  // Write log to stdout and file
244 
245  auto scene = std::make_shared<Scene>("RbdSDFCollision");
246  auto cubeObj = std::make_shared<PbdObject>("Cube");
247  {
248  // This model is shared among interacting rigid bodies
249  auto pbdModel = std::make_shared<PbdModel>();
250  auto pbdConfig = std::make_shared<PbdModelConfig>();
251  // Slightly larger gravity to compensate damping
252  pbdConfig->m_gravity = Vec3d(0.0, -9.8, 0.0);
253  pbdConfig->m_dt = 0.001;
254  pbdConfig->m_iterations = 10;
255  pbdConfig->m_linearDampingCoeff = 0.001;
256  pbdConfig->m_angularDampingCoeff = 0.001;
257  pbdConfig->m_doPartitioning = false;
258  pbdModel->configure(pbdConfig);
259 
260  // Create the first rbd, plane floor
261  auto planeObj = std::make_shared<CollidingObject>("Plane");
262  {
263  // Subtract the sphere from the plane to make a crater
264  auto planeGeom = std::make_shared<Plane>();
265  planeGeom->setWidth(1.0);
266  auto sphereGeom = std::make_shared<Sphere>();
267  sphereGeom->setRadius(0.625);
268  sphereGeom->setPosition(0.0, 0.4, 0.0);
269  auto compGeom = std::make_shared<CompositeImplicitGeometry>();
270  compGeom->addImplicitGeometry(planeGeom, CompositeImplicitGeometry::GeometryBoolType::Union);
271  compGeom->addImplicitGeometry(sphereGeom, CompositeImplicitGeometry::GeometryBoolType::Difference);
272 
273  // Rasterize the SDF into an image
275  toImage.setInputGeometry(compGeom);
276  Vec6d bounds;
277  bounds[0] = -0.5;
278  bounds[1] = 0.5;
279  bounds[2] = -0.5;
280  bounds[3] = 0.5;
281  bounds[4] = -0.5;
282  bounds[5] = 0.5;
283  toImage.setBounds(bounds);
284  toImage.setDimensions(Vec3i(80, 80, 80));
285  toImage.update();
286 
287  // Extract surface
288  SurfaceMeshFlyingEdges toSurfMesh;
289  toSurfMesh.setInputImage(toImage.getOutputImage());
290  toSurfMesh.update();
291  toSurfMesh.getOutputMesh()->flipNormals();
292 
293  // Create the object
294  planeObj->setVisualGeometry(toSurfMesh.getOutputMesh());
295  planeObj->setCollidingGeometry(compGeom);
296 
297  scene->addSceneObject(planeObj);
298  }
299 
300  // Create surface mesh cube (so we can use pointset for point->implicit collision)
301  {
302  auto cubeGeom = std::make_shared<OrientedBox>(Vec3d::Zero(), Vec3d(0.0375, 0.075, 0.025));
303  std::shared_ptr<SurfaceMesh> surfMesh = GeometryUtils::toSurfaceMesh(cubeGeom);
304 
305  SurfaceMeshSubdivide subdivide;
306  subdivide.setInputMesh(surfMesh);
307  subdivide.setNumberOfSubdivisions(1);
308  subdivide.update();
309 
310  // Create the visual model
311  auto visualModel = std::make_shared<VisualModel>();
312  visualModel->setGeometry(subdivide.getOutputMesh());
313  auto material = std::make_shared<RenderMaterial>();
314  material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
315  material->setLineWidth(2.0);
316  material->setColor(Color::Orange);
317  visualModel->setRenderMaterial(material);
318 
319  // Create the cube rigid object
320  cubeObj->setDynamicalModel(pbdModel);
321  cubeObj->setPhysicsGeometry(subdivide.getOutputMesh());
322  cubeObj->setCollidingGeometry(subdivide.getOutputMesh());
323  cubeObj->addVisualModel(visualModel);
324  cubeObj->getPbdBody()->setRigid(Vec3d(0.0, 0.2, 0.0), 1.0,
325  Quatd(Rotd(0.4, Vec3d(1.0, 0.0, 0.0))), Mat3d::Identity() * 0.01);
326 
327  scene->addSceneObject(cubeObj);
328  }
329 
330  auto rbdInteraction = std::make_shared<PbdObjectCollision>(cubeObj, planeObj, "ImplicitGeometryToPointSetCD");
331  rbdInteraction->setRigidBodyCompliance(0.00001);
332  //rbdInteraction->setFriction(0.5);
333  //rbdInteraction->setUseCorrectVelocity(false);
334  scene->addInteraction(rbdInteraction);
335 
336  // Camera
337  scene->getActiveCamera()->setPosition(0.0, 1.0, 1.0);
338 
339  // Light
340  auto light = std::make_shared<DirectionalLight>();
341  light->setIntensity(1.0);
342  scene->addLight("light", light);
343  }
344 
345  // Run the simulation
346  {
347  // Setup a viewer to render in its own thread
348  auto viewer = std::make_shared<VTKViewer>();
349  viewer->setActiveScene(scene);
350 
351  // Setup a scene manager to advance the scene in its own thread
352  auto sceneManager = std::make_shared<SceneManager>();
353  sceneManager->setActiveScene(scene);
354  sceneManager->pause();
355 
356  auto driver = std::make_shared<SimulationManager>();
357  driver->addModule(viewer);
358  driver->addModule(sceneManager);
359  driver->setDesiredDt(0.001);
360 
361  // Add default mouse and keyboard controls to the viewer
362  std::shared_ptr<Entity> mouseAndKeyControls =
363  SimulationUtils::createDefaultSceneControl(driver);
364  scene->addSceneObject(mouseAndKeyControls);
365 
366  LOG(INFO) << "Cube Controls:";
367  LOG(INFO) << "----------------------------------------------------------------------";
368  LOG(INFO) << " | i - forward movement";
369  LOG(INFO) << " | j - left movement";
370  LOG(INFO) << " | l - right movement";
371  LOG(INFO) << " | k - backwards movement";
372  LOG(INFO) << " | u - rotate left";
373  LOG(INFO) << " | o - rotate right";
374 
375  std::shared_ptr<KeyboardDeviceClient> keyDevice = viewer->getKeyboardDevice();
376 
377  const Vec3d dx = scene->getActiveCamera()->getPosition() - scene->getActiveCamera()->getFocalPoint();
378  const double speed = 10.0;
379  connect<Event>(sceneManager, &SceneManager::postUpdate, [&](Event*)
380  {
381  Vec3d extForce = Vec3d(0.0, 0.0, 0.0);
382  Vec3d extTorque = Vec3d(0.0, 0.0, 0.0);
383  // If w down, move forward
384  if (keyDevice->getButton('i') == KEY_PRESS)
385  {
386  extForce += Vec3d(0.0, 0.0, -1.0) * speed;
387  }
388  if (keyDevice->getButton('k') == KEY_PRESS)
389  {
390  extForce += Vec3d(0.0, 0.0, 1.0) * speed;
391  }
392  if (keyDevice->getButton('j') == KEY_PRESS)
393  {
394  extForce += Vec3d(-1.0, 0.0, 0.0) * speed;
395  }
396  if (keyDevice->getButton('l') == KEY_PRESS)
397  {
398  extForce += Vec3d(1.0, 0.0, 0.0) * speed;
399  }
400  if (keyDevice->getButton('u') == KEY_PRESS)
401  {
402  extTorque += Vec3d(0.0, 1.5, 0.0);
403  }
404  if (keyDevice->getButton('o') == KEY_PRESS)
405  {
406  extTorque += Vec3d(0.0, -1.5, 0.0);
407  }
408  cubeObj->getPbdBody()->externalForce = extForce;
409  cubeObj->getPbdBody()->externalTorque = extTorque;
410  scene->getActiveCamera()->setFocalPoint((*cubeObj->getPbdBody()->vertices)[0]);
411  scene->getActiveCamera()->setPosition((*cubeObj->getPbdBody()->vertices)[0] + dx);
412  });
413  /*connect<Event>(sceneManager, &SceneManager::postUpdate, [&](Event*)
414  {
415  cubeObj->getRigidBodyModel2()->getConfig()->m_dt = sceneManager->getDt();
416  });*/
417 
418  driver->start();
419  }
420 }
421 
422 static void
423 tissueCapsuleDrop()
424 {
425  // Write log to stdout and file
427 
428  // Setup a scene
429  auto scene = std::make_shared<Scene>("PbdRigidBody");
430  scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
431  scene->getActiveCamera()->setPosition(-0.0237419, 0.0368787, 0.338374);
432  scene->getActiveCamera()->setViewUp(0.0, 1.0, 0.0);
433 
434  auto pbdModel = std::make_shared<PbdModel>();
435  auto pbdConfig = std::make_shared<PbdModelConfig>();
436  pbdConfig->m_gravity = Vec3d(0.0, -9.8, 0.0); // Slightly larger gravity to compensate viscosity
437  pbdConfig->m_dt = 0.001;
438  pbdConfig->m_iterations = 5;
439  pbdConfig->m_linearDampingCoeff = 0.0;
440  pbdConfig->m_angularDampingCoeff = 0.0;
441  pbdConfig->m_doPartitioning = false;
442  pbdModel->configure(pbdConfig);
443 
444  // Setup a tissue
445  std::shared_ptr<PbdObject> tissueObj = makeTissueObj("Tissue", pbdModel,
446  0.1, 0.1,
447  5, 5,
448  0.1, // Per Particle Mass
449  1.0, 0.2); // Distance & Bend Stiffness
450  scene->addSceneObject(tissueObj);
451  pbdConfig->setBodyDamping(tissueObj->getPbdBody()->bodyHandle, 0.1);
452 
453  // Setup capsule to drop on tissue
454  auto capsuleObj = std::make_shared<PbdObject>("capsule0");
455  {
456  // Setup line geometry
457  //auto rigidGeom = std::make_shared<Sphere>(Vec3d(-0.005, 0.0, 0.0), 0.005);
458  auto rigidGeom = std::make_shared<Capsule>(Vec3d(-0.005, 0.0, 0.0), 0.005, 0.015);
459  capsuleObj->setVisualGeometry(rigidGeom);
460  capsuleObj->setCollidingGeometry(rigidGeom);
461  capsuleObj->setPhysicsGeometry(rigidGeom);
462 
463  // Setup material
464  capsuleObj->getVisualModel(0)->getRenderMaterial()->setColor(Color(0.9, 0.0, 0.0));
465  capsuleObj->getVisualModel(0)->getRenderMaterial()->setShadingModel(RenderMaterial::ShadingModel::PBR);
466  capsuleObj->getVisualModel(0)->getRenderMaterial()->setRoughness(0.5);
467  capsuleObj->getVisualModel(0)->getRenderMaterial()->setMetalness(1.0);
468  capsuleObj->getVisualModel(0)->getRenderMaterial()->setIsDynamicMesh(false);
469 
470  capsuleObj->setDynamicalModel(pbdModel);
471  pbdConfig->setBodyDamping(capsuleObj->getPbdBody()->bodyHandle, 0.04, 0.01);
472 
473  // Setup body
474  const Quatd orientation = Quatd::FromTwoVectors(Vec3d(0.0, 1.0, 0.0), Vec3d(1.0, 1.0, 0.0).normalized());
475  capsuleObj->getPbdBody()->setRigid(Vec3d(0.0, 0.05, 0.0), 1.0,
476  orientation, Mat3d::Identity() * 0.01);//Vec3d(1.0, 5.0, 1.0).asDiagonal());
477  }
478  scene->addSceneObject(capsuleObj);
479 
480  auto collision = std::make_shared<PbdObjectCollision>(tissueObj, capsuleObj);
481  collision->setRigidBodyCompliance(0.00001);
482  scene->addSceneObject(collision);
483 
484  // Light
485  auto light = std::make_shared<DirectionalLight>();
486  light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
487  light->setIntensity(1.0);
488  scene->addLight("Light", light);
489 
490  // Run the simulation
491  {
492  // Setup a viewer to render
493  auto viewer = std::make_shared<VTKViewer>();
494  viewer->setVtkLoggerMode(VTKViewer::VTKLoggerMode::MUTE);
495  viewer->setActiveScene(scene);
496  viewer->setDebugAxesLength(0.01, 0.01, 0.01);
497 
498  // Setup a scene manager to advance the scene
499  auto sceneManager = std::make_shared<SceneManager>();
500  sceneManager->setActiveScene(scene);
501  sceneManager->pause(); // Start simulation paused
502 
503  connect<Event>(sceneManager, &SceneManager::preUpdate, [&](Event*)
504  {
505  pbdModel->getConfig()->m_dt = sceneManager->getDt();
506  });
507 
508  auto driver = std::make_shared<SimulationManager>();
509  driver->addModule(viewer);
510  driver->addModule(sceneManager);
511  driver->setDesiredDt(0.001);
512 
513  // Add default mouse and keyboard controls to the viewer
514  std::shared_ptr<Entity> mouseAndKeyControls =
515  SimulationUtils::createDefaultSceneControl(driver);
516  scene->addSceneObject(mouseAndKeyControls);
517 
518  driver->start();
519  }
520 }
521 
522 static void
523 hingeScene()
524 {
525  // Write log to stdout and file
527 
528  // Setup a scene
529  auto scene = std::make_shared<Scene>("PbdRigidBody");
530  scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
531  scene->getActiveCamera()->setPosition(-0.0237419, 0.0368787, 0.338374);
532  scene->getActiveCamera()->setViewUp(0.0, 1.0, 0.0);
533 
534  auto pbdModel = std::make_shared<PbdModel>();
535  auto pbdConfig = std::make_shared<PbdModelConfig>();
536  pbdConfig->m_gravity = Vec3d(0.0, 0.0, 0.0); // Slightly larger gravity to compensate viscosity
537  pbdConfig->m_dt = 0.001;
538  pbdConfig->m_iterations = 5;
539  pbdConfig->m_linearDampingCoeff = 0.003;
540  pbdConfig->m_angularDampingCoeff = 0.003;
541  pbdConfig->m_doPartitioning = false;
542  pbdModel->configure(pbdConfig);
543 
544  // Setup a capsule
545  auto rigidPbdObj = std::make_shared<PbdObject>("rigidPbdObj");
546  {
547  // Setup line geometry
548  //auto rigidGeom = std::make_shared<Sphere>(Vec3d(0.0, 0.0, 0.0), 0.5);
549  auto rigidGeom = std::make_shared<Capsule>(Vec3d(0.0, 0.0, 0.0), 0.5, 2.0);
550  std::shared_ptr<SurfaceMesh> surfMesh = GeometryUtils::toSurfaceMesh(rigidGeom);
551  rigidPbdObj->setVisualGeometry(surfMesh);
552  rigidPbdObj->setCollidingGeometry(surfMesh);
553  rigidPbdObj->setPhysicsGeometry(surfMesh);
554 
555  // Setup material
556  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setColor(Color(0.9, 0.0, 0.0));
557  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setShadingModel(RenderMaterial::ShadingModel::PBR);
558  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setRoughness(0.5);
559  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setMetalness(1.0);
560  rigidPbdObj->getVisualModel(0)->getRenderMaterial()->setIsDynamicMesh(false);
561 
562  rigidPbdObj->setDynamicalModel(pbdModel);
563 
564  // Setup body such that z is now pointing in -x
565  const Quatd orientation = Quatd::FromTwoVectors(Vec3d(1.0, 0.0, 0.0), Vec3d(0.0, 0.0, 1.0).normalized());
566  //const Quatd orientation = Quatd::Identity();
567  const Mat3d inertia = Vec3d(1.0, 1.0, 100.0).asDiagonal(); // Resistance on z
568  rigidPbdObj->getPbdBody()->setRigid(Vec3d(0.0, 0.0, 0.0),
569  1.0, orientation, inertia);
570 
571  // Custom constaint addition
572  pbdModel->getConfig()->addPbdConstraintFunctor([&](PbdConstraintContainer& container)
573  {
574  auto hingeConstraint = std::make_shared<PbdAngularHingeConstraint>();
575  hingeConstraint->initConstraint({ rigidPbdObj->getPbdBody()->bodyHandle, 0 }, Vec3d(1.0, 0.0, 0.0), 0.1);
576  container.addConstraint(hingeConstraint);
577  });
578  }
579  scene->addSceneObject(rigidPbdObj);
580 
581  // Light
582  auto light = std::make_shared<DirectionalLight>();
583  light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
584  light->setIntensity(1.0);
585  scene->addLight("Light", light);
586 
587  // Run the simulation
588  {
589  // Setup a viewer to render
590  auto viewer = std::make_shared<VTKViewer>();
591  viewer->setVtkLoggerMode(VTKViewer::VTKLoggerMode::MUTE);
592  viewer->setActiveScene(scene);
593  //viewer->setDebugAxesLength(0.1, 0.1, 0.1);
594 
595  // Setup a scene manager to advance the scene
596  auto sceneManager = std::make_shared<SceneManager>();
597  sceneManager->setActiveScene(scene);
598  sceneManager->pause(); // Start simulation paused
599 
600  auto driver = std::make_shared<SimulationManager>();
601  driver->addModule(viewer);
602  driver->addModule(sceneManager);
603  driver->setDesiredDt(0.001);
604 
605  // Add default mouse and keyboard controls to the viewer
606  std::shared_ptr<Entity> mouseAndKeyControls =
607  SimulationUtils::createDefaultSceneControl(driver);
608  scene->addSceneObject(mouseAndKeyControls);
609 
610  driver->start();
611  }
612 }
613 
614 int
615 main()
616 {
617  //tissueCapsuleDrop();
618  planeContactScene();
619  //hingeScene();
620  //bowlScene();
621 
622  return 0;
623 }
std::shared_ptr< SurfaceMesh > toTriangleGrid(const Vec3d &center, const Vec2d &size, const Vec2i &dim, const Quatd orientation=Quatd::Identity(), const double uvScale=1.0)
Produces a triangle grid on a plane given the imstkPlane.
Container for pbd constraints.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
Compound Geometry.
This filter rasterizes an implicit function to image of specified dimensions and bounds.
void setInputGeometry(std::shared_ptr< ImplicitGeometry > inputGeometry)
Required input, port 0.
This filter extracts a single isocontour from an imstkImageData.
void update()
Do the actual algorithm.
Provides the information of a key event (press, release, & which key)
void setInputImage(std::shared_ptr< ImageData > inputImage)
Required input, port 0.
Color in RGB space.
Definition: imstkColor.h:24
virtual void addConstraint(std::shared_ptr< PbdConstraint > constraint)
Adds a constraint to the system, thread safe.
std::shared_ptr< SurfaceMesh > toSurfaceMesh(std::shared_ptr< AnalyticalGeometry > geom)
Produces SurfaceMesh from an analytical geometry.
Physically based rendering.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.