iMSTK
Interactive Medical Simulation Toolkit
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
RbdBallDropExample.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 "imstkCollisionUtils.h"
9 #include "imstkDirectionalLight.h"
10 #include "imstkGeometryUtilities.h"
11 #include "imstkKeyboardDeviceClient.h"
12 #include "imstkKeyboardSceneControl.h"
13 #include "imstkMouseDeviceClient.h"
14 #include "imstkMouseSceneControl.h"
15 #include "imstkNew.h"
16 #include "imstkPlane.h"
17 #include "imstkRbdConstraint.h"
18 #include "imstkRenderMaterial.h"
19 #include "imstkRigidBodyModel2.h"
20 #include "imstkRigidObject2.h"
21 #include "imstkRigidObjectCollision.h"
22 #include "imstkScene.h"
23 #include "imstkSceneManager.h"
24 #include "imstkSimulationManager.h"
25 #include "imstkSimulationUtils.h"
26 #include "imstkSphere.h"
27 #include "imstkSurfaceMesh.h"
28 #include "imstkUnidirectionalPlaneToSphereCD.h"
29 #include "imstkVisualModel.h"
30 #include "imstkVTKViewer.h"
31 
32 using namespace imstk;
33 
34 namespace
35 {
36 } // namespace
37 
42 int
43 main()
44 {
45  // Write log to stdout and file
47 
48  auto scene = std::make_shared<Scene>("RbdMeshMeshCollision");
49 
50  // This model is shared among interacting rigid bodies
51  // In most cases instances of iMSTK object should be created
52  // on the heap and stored in std::shared_ptr
53  auto rbdModel = std::make_shared<RigidBodyModel2>();
54 
55  // iMSTK coordinates are right handed with Y pointing up
56  // While we have defined types for Vectors and Matrices
57  // these are all Eigen https://eigen.tuxfamily.org/index.php
58  // types and all of Eigen is available in iMSTK
59  rbdModel->getConfig()->m_gravity = Vec3d(0.0, -9.8, 0.0);
60  rbdModel->getConfig()->m_maxNumIterations = 10;
61 
62  // iMSTK knows about various kinds of geometry, amongst others
63  // analytical shapes and meshes, here a analytical sphere is used
64  auto sphere = std::make_shared<Sphere>(Vec3d(0, 0, 0), 0.5);
65 
66  // Create a SceneObject that is a RigidObject
67  // Then we set up the object with all the data necessary
68  auto sphereObject = std::make_shared<RigidObject2>("Sphere");
69 
70  // Give the object something to visualize, this can be shortcut by using
71  // addVisualGeometry()
72  auto sphereVisualModel = std::make_shared<VisualModel>();
73  sphereVisualModel->setGeometry(sphere);
74  sphereObject->addVisualModel(sphereVisualModel);
75 
76  // Customize the look using a material
77  auto sphereMaterial = std::make_shared<RenderMaterial>();
78  sphereMaterial->setDiffuseColor(Color(1.0, 0.333, 0.259));
79  sphereMaterial->setShadingModel(RenderMaterial::ShadingModel::PBR);
80  sphereMaterial->setRoughness(0.5);
81  sphereMaterial->setMetalness(0.5);
82  sphereVisualModel->setRenderMaterial(sphereMaterial);
83 
84  // This is the geometry used for collision detection
85  sphereObject->setCollidingGeometry(sphere);
86 
87  // Forces and physical effects are applied to the physics geometry
88  sphereObject->setPhysicsGeometry(sphere);
89 
90  sphereObject->setDynamicalModel(rbdModel);
91  sphereObject->getRigidBody()->m_mass = 1.0;
92 
93  sphereObject->getRigidBody()->m_initPos = Vec3d(0.0, 3.0, 0.0);
94  sphereObject->getRigidBody()->m_intertiaTensor = Mat3d::Identity();
95 
96  // Finally add the object to the scene
97  scene->addSceneObject(sphereObject);
98 
99  // Create a plane at the origin with a normal along the Y-Axis
100  auto plane = std::make_shared<Plane>(Vec3d::Zero(), Vec3d::UnitY());
101 
102  // This "width" is just used visually, this is an analytical plane
103  // that is infinite
104  plane->setWidth(10.0);
105 
106  // A CollidingObject is static and will not react to forces
107  auto planeObject = std::make_shared<CollidingObject>("Plane");
108  planeObject->setVisualGeometry(plane);
109  planeObject->setCollidingGeometry(plane);
110  scene->addSceneObject(planeObject);
111 
112  // To affect collision detection and response the appropriate interaction has to be instantiated
113  // and added to the scene, the type of the interaction is dependent on the interacting model types
114  // in this case Rigid and Colliding (Static) object
115  // the type of the collision detection is dependent on the kinds of geometry involved
116  // Add collisions for all the rigid bodies with the bowl
117  scene->addInteraction(
118  std::make_shared<RigidObjectCollision>(sphereObject, planeObject, UnidirectionalPlaneToSphereCD::getStaticTypeName()));
119 
120  // Camera
121  scene->getActiveCamera()->setPosition(0, 3, 20);
122  scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
123  scene->getActiveCamera()->setViewUp(0, 1, 0);
124 
125  // Light
127  light->setIntensity(1.0);
128  scene->addLight("light", light);
129 
130  // Setup a viewer to render in its own thread
131  auto viewer = std::make_shared<VTKViewer>();
132  viewer->setActiveScene(scene);
133 
134  // Setup a scene manager to advance the scene in its own thread
135  auto sceneManager = std::make_shared<SceneManager>();
136  sceneManager->setActiveScene(scene);
137  sceneManager->pause();
138 
139  // The simulation manager is responsible to direct multiple modules
140  auto simulationManager = std::make_shared<SimulationManager>();
141  simulationManager->addModule(viewer);
142  simulationManager->addModule(sceneManager);
143  simulationManager->setDesiredDt(0.001);
144 
145  // Add default mouse and keyboard controls to the viewer
146  std::shared_ptr<Entity> mouseAndKeyControls =
147  SimulationUtils::createDefaultSceneControl(simulationManager);
148  scene->addSceneObject(mouseAndKeyControls);
149 
150  // iMSTK utilizes an event system this is one of many ways to connect to this system
151  // postUpdateFunction will be called every time the SceneManager posts a
152  // postUdate event, in this case a lambda is used to capture the scene by
153  // value as we don't have an object scope to use use, depending on your needs a free function
154  // or a member function can be used as callbacks for events.
155  connect<Event>(sceneManager, &SceneManager::postUpdate, [scene](Event*) {
156  // Remove comment to print out the elapsed time every frame
157  // LOG(INFO) << "Elapsed: " << scene->getSceneTime();
158  });
159 
160  // By default the scene will start "paused" press space to start the simulation
161  // look at the console for more instructions about available key strokes
162  simulationManager->start();
163 
164  return 0;
165 }
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
Compound Geometry.
void setIntensity(const double intensity)
Set the light intensity. This value is unbounded.
Definition: imstkLight.h:71
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
Definition: imstkNew.h:29
Color in RGB space.
Definition: imstkColor.h:24
Physically based rendering.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.