7 #include "imstkCamera.h" 8 #include "imstkDirectionalLight.h" 9 #include "imstkGeometryUtilities.h" 10 #include "imstkImageData.h" 11 #include "imstkKeyboardDeviceClient.h" 12 #include "imstkKeyboardSceneControl.h" 13 #include "imstkMeshIO.h" 14 #include "imstkMouseDeviceClient.h" 15 #include "imstkMouseSceneControl.h" 16 #include "imstkPbdModel.h" 17 #include "imstkPbdModelConfig.h" 18 #include "imstkPbdObject.h" 19 #include "imstkPbdObjectCollision.h" 20 #include "imstkRenderMaterial.h" 21 #include "imstkScene.h" 22 #include "imstkSceneManager.h" 23 #include "imstkSimulationManager.h" 24 #include "imstkSimulationUtils.h" 25 #include "imstkVisualModel.h" 26 #include "imstkVTKViewer.h" 28 #ifdef iMSTK_USE_HAPTICS 29 #include "imstkDeviceManager.h" 30 #include "imstkDeviceManagerFactory.h" 33 using namespace imstk;
38 static std::shared_ptr<PbdObject>
39 makeTissueObj(
const std::string& name,
46 std::shared_ptr<SurfaceMesh> clothMesh =
48 Vec2d(width, height), Vec2i(rowCount, colCount));
51 auto pbdParams = std::make_shared<PbdModelConfig>();
52 pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Distance, 5000.0);
53 pbdParams->enableConstraint(PbdModelConfig::ConstraintGenType::Dihedral, 5000.0);
54 pbdParams->m_gravity = Vec3d(0.0, -20.0, 0.0);
55 pbdParams->m_dt = 0.005;
56 pbdParams->m_iterations = 2;
57 pbdParams->m_linearDampingCoeff = 0.0;
60 auto pbdModel = std::make_shared<PbdModel>();
61 pbdModel->configure(pbdParams);
64 auto material = std::make_shared<RenderMaterial>();
65 material->setBackFaceCulling(
false);
66 material->setDisplayMode(RenderMaterial::DisplayMode::Surface);
68 auto diffuseTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshDiffuse.jpg");
69 material->addTexture(std::make_shared<Texture>(diffuseTex, Texture::Type::Diffuse));
70 auto normalTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshNormal.jpg");
71 material->addTexture(std::make_shared<Texture>(normalTex, Texture::Type::Normal));
72 auto ormTex = MeshIO::read<ImageData>(iMSTK_DATA_ROOT
"/textures/fleshORM.jpg");
73 material->addTexture(std::make_shared<Texture>(ormTex, Texture::Type::ORM));
75 auto visualModel = std::make_shared<VisualModel>();
76 visualModel->setGeometry(clothMesh);
77 visualModel->setRenderMaterial(material);
80 auto pbdObject = std::make_shared<PbdObject>(name);
81 pbdObject->addVisualModel(visualModel);
82 pbdObject->setPhysicsGeometry(clothMesh);
83 pbdObject->setCollidingGeometry(clothMesh);
84 pbdObject->setDynamicalModel(pbdModel);
85 pbdObject->getPbdBody()->uniformMassValue = width * height / (rowCount * colCount);
86 for (
int x = 0; x < rowCount; x++)
88 for (
int y = 0; y < colCount; y++)
90 if (x == 0 || y == 0 || x == rowCount - 1 || y == colCount - 1)
92 pbdObject->getPbdBody()->fixedNodeIds.push_back(x * colCount + y);
111 auto scene = std::make_shared<Scene>(
"PbdThinTissueContact");
112 scene->getActiveCamera()->setPosition(0.12, 4.51, 16.51);
113 scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
114 scene->getActiveCamera()->setViewUp(0.0, 0.96, -0.28);
117 std::shared_ptr<PbdObject> tissueObj = makeTissueObj(
"Tissue", 10.0, 10.0, 16, 16);
118 scene->addSceneObject(tissueObj);
121 auto toolGeom = std::make_shared<LineMesh>();
124 toolGeom->initialize(
128 auto toolObj = std::make_shared<CollidingObject>(
"Tool");
129 toolObj->setVisualGeometry(toolGeom);
130 toolObj->setCollidingGeometry(toolGeom);
131 toolObj->getVisualModel(0)->getRenderMaterial()->setDisplayMode(RenderMaterial::DisplayMode::Wireframe);
132 toolObj->getVisualModel(0)->getRenderMaterial()->setLineWidth(5.0);
133 toolObj->getVisualModel(0)->getRenderMaterial()->setRecomputeVertexNormals(
false);
134 toolObj->getVisualModel(0)->getRenderMaterial()->setBackFaceCulling(
false);
135 scene->addSceneObject(toolObj);
138 scene->addInteraction(std::make_shared<PbdObjectCollision>(tissueObj, toolObj));
141 auto light = std::make_shared<DirectionalLight>();
142 light->setFocalPoint(Vec3d(5.0, -8.0, -5.0));
143 light->setIntensity(1.0);
144 scene->addLight(
"Light", light);
149 auto viewer = std::make_shared<VTKViewer>();
150 viewer->setVtkLoggerMode(VTKViewer::VTKLoggerMode::MUTE);
151 viewer->setActiveScene(scene);
154 auto sceneManager = std::make_shared<SceneManager>();
155 sceneManager->setActiveScene(scene);
156 sceneManager->pause();
158 auto driver = std::make_shared<SimulationManager>();
159 driver->setDesiredDt(0.005);
160 driver->addModule(viewer);
161 driver->addModule(sceneManager);
163 #ifdef iMSTK_USE_HAPTICS 166 std::shared_ptr<DeviceClient> deviceClient = hapticManager->makeDeviceClient();
167 driver->addModule(hapticManager);
169 Mat3d rotationalOffset = Mat3d::Identity();
170 connect<Event>(sceneManager, SceneManager::preUpdate, [&](
Event*)
172 const Quatd deviceOrientation = (Quatd(rotationalOffset) * deviceClient->getOrientation()).normalized();
173 const Vec3d devicePosition = (rotationalOffset * deviceClient->getPosition()) * 50.0 + Vec3d(0.0, 0.0, 0.0);
174 toolGeom->setRotation(deviceOrientation);
175 toolGeom->setTranslation(devicePosition);
176 toolGeom->postModified();
179 connect<Event>(sceneManager, &SceneManager::preUpdate, [&](
Event*)
181 const Vec2d mousePos = viewer->getMouseDevice()->getPos();
182 const Vec3d worldPos = Vec3d(mousePos[0] - 0.5, mousePos[1] - 0.5, 0.0) * 10.0 + Vec3d(0.5, 2.0, 0.5);
184 toolGeom->setTranslation(worldPos);
185 toolGeom->postModified();
190 std::shared_ptr<Entity> mouseAndKeyControls =
191 SimulationUtils::createDefaultSceneControl(driver);
192 scene->addSceneObject(mouseAndKeyControls);
std::shared_ptr< SurfaceMesh > toTriangleGrid(const Vec3d ¢er, 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.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
static std::shared_ptr< DeviceManager > makeDeviceManager()
Attempts to create a new DeviceManager by whichever is default If multiple haptic managers are built ...
Physically based rendering.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.