iMSTK
Interactive Medical Simulation Toolkit
imstkObjectControllerGhost.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 "imstkObjectControllerGhost.h"
8 #include "imstkGeometry.h"
9 #include "imstkPbdObjectController.h"
10 #include "imstkRenderMaterial.h"
11 #include "imstkRigidObjectController.h"
12 #include "imstkSceneObject.h"
13 #include "imstkVisualModel.h"
14 
15 namespace imstk
16 {
17 ObjectControllerGhost::ObjectControllerGhost(const std::string& name) : SceneBehaviour(name),
18  m_ghostVisualModel(std::make_shared<VisualModel>("GhostVisualModel"))
19 {
20  m_ghostVisualModel->getRenderMaterial()->setColor(Color::Orange);
21  m_ghostVisualModel->getRenderMaterial()->setLineWidth(5.0);
22  m_ghostVisualModel->getRenderMaterial()->setOpacity(0.3);
23  m_ghostVisualModel->getRenderMaterial()->setIsDynamicMesh(false);
24 }
25 
26 void
28 {
29  // Add a visual representation for the object
30  // how to avoid adding it twice?
31  std::shared_ptr<Entity> entity = m_entity.lock();
32  CHECK(entity != nullptr) << "ObjectControllerGhost must have entity to initialize";
33  if (!entity->containsComponent(m_ghostVisualModel))
34  {
35  m_ghostVisualModel->setName(entity->getName() + "_GhostVisualModel");
36  entity->addComponent(m_ghostVisualModel);
37  }
38 
39  CHECK(m_pbdController != nullptr || m_rbdController != nullptr)
40  << "ObjectControllerGhost must have a controller";
41 
42  // Copy the geometry to the ghost visual model
43  std::shared_ptr<SceneObject> controlledObj = nullptr;
44  if (m_pbdController != nullptr)
45  {
46  controlledObj = m_pbdController->getControlledObject();
47  }
48  else
49  {
50  controlledObj = m_rbdController->getControlledObject();
51  }
52  std::shared_ptr<Geometry> ghostGeom = controlledObj->getVisualGeometry()->clone();
53  CHECK(ghostGeom != nullptr) << "Failed to copy controller geometry";
54 
55  if (m_pbdController != nullptr)
56  {
57  ghostGeom->translate(-1.0 * m_pbdController->getHapticOffset(), Geometry::TransformType::ApplyToData);
58  }
59 
60  m_ghostVisualModel->setGeometry(ghostGeom);
61 }
62 
63 void
64 ObjectControllerGhost::visualUpdate(const double&)
65 {
66  Quatd orientation = Quatd::Identity();
67  Vec3d position = Vec3d::Zero();
68  Vec3d force = Vec3d::Zero();
69  if (m_pbdController != nullptr)
70  {
71  orientation = m_pbdController->getOrientation();
72  position = m_pbdController->getPosition(); //
73  force = m_pbdController->getDeviceForce();
74  }
75  else
76  {
77  orientation = m_rbdController->getOrientation();
78  position = m_rbdController->getPosition();
79  force = m_rbdController->getDeviceForce();
80  }
81 
82  // Update the ghost debug geometry
83  std::shared_ptr<Geometry> toolGhostMesh = m_ghostVisualModel->getGeometry();
84  toolGhostMesh->setTranslation(position);
85  toolGhostMesh->setRotation(orientation);
86  toolGhostMesh->updatePostTransformData();
87  toolGhostMesh->postModified();
88 
89  if (m_useForceFade)
90  {
91  // Could be desirable to set based off maximum device force (if you could query for it)
92  m_ghostVisualModel->getRenderMaterial()->setOpacity(std::min(1.0, force.norm() / 15.0));
93  }
94 }
95 } // namespace imstk
std::weak_ptr< Entity > m_entity
Parent entity this component exists on.
Compound Geometry.
void init() override
Initialize the component, called at a later time after all component construction is complete...