iMSTK
Interactive Medical Simulation Toolkit
rigidBody2.cs
1 using System;
2 using Imstk;
3 
4 public class RigidBody2
5 {
6  public static void Main(string[] args)
7  {
8  // Write log to stdout and file
9  Logger.startLogger();
10 
11  Scene scene = new Scene("Rigid Body Dynamics");
12  RigidObject2 cubeObj = new RigidObject2("Cube");
13  {
14  // This model is shared among interacting rigid bodies
15  RigidBodyModel2 rbdModel = new RigidBodyModel2();
16  rbdModel.getConfig().m_gravity = new Vec3d(0.0, -2500.0, 0.0);
17  rbdModel.getConfig().m_maxNumIterations = 10;
18 
19  // Create the first rbd, plane floor
20  CollidingObject planeObj = new CollidingObject("Plane");
21  {
22  // Subtract the sphere from the plane to make a crater
23  Plane planeGeom = new Plane();
24  planeGeom.setWidth(40.0);
25  Sphere sphereGeom = new Sphere();
26  sphereGeom.setRadius(25.0);
27  sphereGeom.setPosition(0.0, 10.0, 0.0);
28  CompositeImplicitGeometry compGeom = new CompositeImplicitGeometry();
29  compGeom.addImplicitGeometry(planeGeom, CompositeImplicitGeometry.GeometryBoolType.Union);
30  compGeom.addImplicitGeometry(sphereGeom, CompositeImplicitGeometry.GeometryBoolType.Difference);
31 
32  // Rasterize the SDF into an image
33  ImplicitGeometryToImageData toImage = new ImplicitGeometryToImageData();
34  toImage.setInputGeometry(compGeom);
35  Vec6d bounds = new Vec6d();
36  bounds[0] = -20.0;
37  bounds[1] = 20.0;
38  bounds[2] = -20.0;
39  bounds[3] = 20.0;
40  bounds[4] = -20.0;
41  bounds[5] = 20.0;
42  toImage.setBounds(bounds);
43  toImage.setDimensions(new Vec3i(80, 80, 80));
44  toImage.update();
45 
46  // Extract surface
47  SurfaceMeshFlyingEdges toSurfMesh = new SurfaceMeshFlyingEdges();
48  toSurfMesh.setInputImage(toImage.getOutputImage());
49  toSurfMesh.update();
50  toSurfMesh.getOutputMesh().flipNormals();
51 
52  // Create the visual model
53  VisualModel visualModel = new VisualModel();
54  visualModel.setGeometry(toSurfMesh.getOutputMesh());
55 
56  // Create the object
57  planeObj.addVisualModel(visualModel);
58  planeObj.setCollidingGeometry(compGeom);
59  //planeObj.getRigidBody().m_isStatic = true;
60  //planeObj.getRigidBody().m_mass = 100.0;
61 
62  scene.addSceneObject(planeObj);
63  }
64 
65  // Create surface mesh cube (so we can use pointset for point.implicit collision)
66  {
67  OrientedBox cubeGeom = new OrientedBox(new Vec3d(0.0, 0.0, 0.0), new Vec3d(1.5, 3.0, 1.0));
68  SurfaceMesh surfMesh = Utils.toSurfaceMesh(cubeGeom);
69 
70  SurfaceMeshSubdivide subdivide = new SurfaceMeshSubdivide();
71  subdivide.setInputMesh(surfMesh);
72  subdivide.setNumberOfSubdivisions(1);
73  subdivide.update();
74 
75  // Create the visual model
76  VisualModel visualModel = new VisualModel();
77  visualModel.setGeometry(subdivide.getOutputMesh());
78  RenderMaterial mat = new RenderMaterial();
79  mat.setDisplayMode(RenderMaterial.DisplayMode.WireframeSurface);
80  mat.setLineWidth(2.0f);
81  mat.setColor(Color.Orange);
82  visualModel.setRenderMaterial(mat);
83 
84  // Create the cube rigid object
85  cubeObj.setDynamicalModel(rbdModel);
86  cubeObj.setPhysicsGeometry(subdivide.getOutputMesh());
87  cubeObj.setCollidingGeometry(subdivide.getOutputMesh());
88  cubeObj.addVisualModel(visualModel);
89  cubeObj.getRigidBody().m_mass = 100.0;
90  cubeObj.getRigidBody().m_initPos = new Vec3d(0.0, 8.0, 0.0);
91  Rotd rotd = new Rotd(0.4, new Vec3d(1.0, 0.0, 0.0));
92  cubeObj.getRigidBody().m_initOrientation = new Quatd(new Rotd(0.4, new Vec3d(1.0, 0.0, 0.0)));
93  cubeObj.getRigidBody().m_intertiaTensor = Mat3d.Identity();
94 
95  scene.addSceneObject(cubeObj);
96  }
97 
98  RigidObjectCollision rbdInteraction = new RigidObjectCollision(cubeObj, planeObj, "ImplicitGeometryToPointSetCD");
99  rbdInteraction.setFriction(0.0);
100  rbdInteraction.setBaumgarteStabilization(0.05);
101  scene.addInteraction(rbdInteraction);
102  scene.getActiveCamera().setPosition(0.0, 40.0, 40.0);
103 
104  // Light
105  DirectionalLight light = new DirectionalLight();
106  light.setIntensity(1.0);
107  scene.addLight("light", light);
108  }
109 
110  // Run the simulation
111  {
112  // Setup a viewer to render in its own thread
113  VTKViewer viewer = new VTKViewer("Viewer");
114  viewer.setActiveScene(scene);
115 
116  // Setup a scene manager to advance the scene in its own thread
117  SceneManager sceneManager = new SceneManager("Scene Manager");
118  sceneManager.setActiveScene(scene);
119  sceneManager.setExecutionType(Module.ExecutionType.ADAPTIVE);
120  sceneManager.pause();
121 
122  SimulationManager driver = new SimulationManager();
123  driver.addModule(viewer);
124  driver.addModule(sceneManager);
125  driver.setDesiredDt(0.001);
126 
127  // Add mouse and keyboard controls to the viewer
128  {
129  MouseSceneControl mouseControl = new MouseSceneControl();
130  mouseControl.setDevice(viewer.getMouseDevice());
131  mouseControl.setSceneManager(sceneManager);
132  scene.addControl(mouseControl);
133 
134  KeyboardSceneControl keyControl = new KeyboardSceneControl();
135  keyControl.setDevice(viewer.getKeyboardDevice());
136  keyControl.setSceneManager(new SceneManagerWeakPtr(sceneManager));
137  keyControl.setModuleDriver(new ModuleDriverWeakPtr(driver));
138  scene.addControl(keyControl);
139  }
140 
141  // LOG(INFO) << "Cube Controls:";
142  // LOG(INFO) << "----------------------------------------------------------------------";
143  // LOG(INFO) << " | i - forward movement";
144  // LOG(INFO) << " | j - left movement";
145  // LOG(INFO) << " | l - right movement";
146  // LOG(INFO) << " | k - backwards movement";
147  // LOG(INFO) << " | u - rotate left";
148  // LOG(INFO) << " | o - rotate right";
149 
150 
151  Vec3d dx = Utils.vec_subtract_3d(scene.getActiveCamera().getPosition(), scene.getActiveCamera().getFocalPoint());
152  KeyboardDeviceClient keyDevice = viewer.getKeyboardDevice();
153  Utils.connectEvent(sceneManager, Utils.SceneManager_getPostUpdate_cb,
154  (Event e) =>
155  {
156  Vec3d extForce = new Vec3d(0.0, 0.0, 0.0);
157  Vec3d extTorque = new Vec3d(0.0, 0.0, 0.0);
158  // If w down, move forward
159  if (keyDevice.getButton('i') == 1)
160  {
161  extForce = Utils.vec_add_3d(extForce, new Vec3d(0.0, 0.0, -900.0));
162  }
163  if (keyDevice.getButton('k') == 1)
164  {
165  extForce = Utils.vec_add_3d(extForce, new Vec3d(0.0, 0.0, 900.0));
166  }
167  if (keyDevice.getButton('j') == 1)
168  {
169  extForce = Utils.vec_add_3d(extForce, new Vec3d(-900.0, 0.0, 0.0));
170  }
171  if (keyDevice.getButton('l') == 1)
172  {
173  extForce = Utils.vec_add_3d(extForce, new Vec3d(900.0, 0.0, 0.0));
174  }
175  if (keyDevice.getButton('u') == 1)
176  {
177  extForce = Utils.vec_add_3d(extForce, new Vec3d(0.0, 1.5, 0.0));
178  }
179  if (keyDevice.getButton('o') == 1)
180  {
181  extForce = Utils.vec_add_3d(extForce, new Vec3d(0.0, -1.5, 0.0));
182  }
183  // \todo: Add setters to imstk
184  cubeObj.getRigidBody().m_force = extForce;
185  cubeObj.getRigidBody().m_torque = extTorque;
186  scene.getActiveCamera().setFocalPoint(cubeObj.getRigidBody().getPosition());
187  scene.getActiveCamera().setPosition(Utils.vec_add_3d(cubeObj.getRigidBody().getPosition(), dx));
188  cubeObj.getRigidBodyModel2().getConfig().m_dt = sceneManager.getDt();
189  });
190 
191  driver.start();
192  }
193  }
194 }
lazy initialized singleton