iMSTK
Interactive Medical Simulation Toolkit
CameraControllerExample.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 "imstkCameraController.h"
9 #include "imstkDeviceManager.h"
10 #include "imstkDeviceManagerFactory.h"
11 #include "imstkKeyboardDeviceClient.h"
12 #include "imstkKeyboardSceneControl.h"
13 #include "imstkMeshIO.h"
14 #include "imstkMouseDeviceClient.h"
15 #include "imstkMouseSceneControl.h"
16 #include "imstkPlane.h"
17 #include "imstkScene.h"
18 #include "imstkSceneManager.h"
19 #include "imstkSceneObject.h"
20 #include "imstkSimulationManager.h"
21 #include "imstkSimulationUtils.h"
22 #include "imstkSpotLight.h"
23 #include "imstkSurfaceMesh.h"
24 #include "imstkVTKViewer.h"
25 
26 using namespace imstk;
27 
34 int
35 main()
36 {
37  // Setup logger (write to file and stdout)
39 
40  // Create Scene
41  auto scene = std::make_shared<Scene>("CameraController");
42 
43  // Setup default haptics manager
44  std::shared_ptr<DeviceManager> hapticManager = DeviceManagerFactory::makeDeviceManager();
45  std::shared_ptr<DeviceClient> deviceClient = hapticManager->makeDeviceClient();
46 
47  // Load Mesh
48  auto mesh = MeshIO::read<SurfaceMesh>(iMSTK_DATA_ROOT "/asianDragon/asianDragon.obj");
49  mesh->scale(0.01, Geometry::TransformType::ApplyToData);
50  auto meshObj = std::make_shared<SceneObject>("MeshObj");
51  meshObj->setVisualGeometry(mesh);
52  scene->addSceneObject(meshObj);
53 
54  auto planeObj = std::make_shared<SceneObject>("Plane");
55  auto plane = std::make_shared<Plane>(Vec3d(0.0, -0.05, 0.0));
56  plane->setWidth(0.5);
57  planeObj->setVisualGeometry(plane);
58  scene->addSceneObject(planeObj);
59 
60  // Update Camera position
61  scene->getActiveCamera()->setPosition(Vec3d(0.0, 0.0, 1.0));
62 
63  // Light
64  auto light = std::make_shared<SpotLight>();
65  light->setFocalPoint(Vec3d(0.0, 0.0, 0.0));
66  light->setPosition(Vec3d(0.0, 10.0, 0.0));
67  light->setIntensity(1.0);
68  light->setSpotAngle(10.0);
69  //light->setAttenuationValues(0.0, 0.0, 1.0); // Constant
70  //light->setAttenuationValues(0.0, 0.5, 0.0); // Linear falloff
71  light->setAttenuationValues(50.0, 0.0, 0.0); // Quadratic
72  scene->addLight("light0", light);
73 
74  // Run the simulation
75  {
76  // Setup a viewer to render
77  auto viewer = std::make_shared<VTKViewer>();
78  viewer->setActiveScene(scene);
79 
80  // Setup a scene manager to advance the scene
81  auto sceneManager = std::make_shared<SceneManager>();
82  sceneManager->setActiveScene(scene);
83 
84  auto driver = std::make_shared<SimulationManager>();
85  driver->addModule(hapticManager);
86  driver->addModule(viewer);
87  driver->addModule(sceneManager);
88  driver->setDesiredDt(0.001);
89 
90  // Attach the camera controller to the viewer
91  auto camController = std::make_shared<CameraController>();
92  camController->setCamera(scene->getActiveCamera());
93  camController->setDevice(deviceClient);
94  scene->addControl(camController);
95 
96  // Add default mouse and keyboard controls to the viewer
97  std::shared_ptr<Entity> mouseAndKeyControls =
98  SimulationUtils::createDefaultSceneControl(driver);
99  scene->addSceneObject(mouseAndKeyControls);
100 
101  // Change the spot angle when haptic button is pressed
102  connect<ButtonEvent>(deviceClient, &DeviceClient::buttonStateChanged,
103  [&](ButtonEvent* e)
104  {
105  if (e->m_buttonState == BUTTON_PRESSED)
106  {
107  if (e->m_button == 0)
108  {
109  light->setSpotAngle(light->getSpotAngle() + 5.0);
110  }
111  else if (e->m_button == 1)
112  {
113  light->setSpotAngle(light->getSpotAngle() - 5.0);
114  }
115  }
116  });
117 
118  // Manually make the light follow the camera controller
119  connect<Event>(sceneManager, &SceneManager::postUpdate,
120  [&](Event*)
121  {
122  const Vec3d pos = camController->getPosition();
123  const Quatd orientation = camController->getOrientation();
124 
125  light->setPosition(pos);
126  light->setFocalPoint(pos - orientation.toRotationMatrix().col(2));
127  });
128 
129  driver->start();
130  }
131 
132  return 0;
133 }
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
Compound Geometry.
static std::shared_ptr< DeviceManager > makeDeviceManager()
Attempts to create a new DeviceManager by whichever is default If multiple haptic managers are built ...
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.