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" 16 #include "imstkRbdConstraint.h" 17 #include "imstkRenderMaterial.h" 18 #include "imstkRigidBodyModel2.h" 19 #include "imstkRigidObject2.h" 20 #include "imstkRigidObjectCollision.h" 21 #include "imstkScene.h" 22 #include "imstkSceneManager.h" 23 #include "imstkSimulationManager.h" 24 #include "imstkSimulationUtils.h" 25 #include "imstkSphere.h" 26 #include "imstkSurfaceMesh.h" 27 #include "imstkVisualModel.h" 28 #include "imstkVTKViewer.h" 30 using namespace imstk;
32 std::shared_ptr<SurfaceMesh>
38 auto sphereVerticesPtr = sphereMesh->getVertexPositions();
39 auto sphereIndicesPtr = sphereMesh->getCells();
42 auto bowlVerticesPtr = std::make_shared<VecDataArray<double, 3>>();
43 auto bowlIndicesPtr = std::make_shared<VecDataArray<int, 3>>();
45 std::unordered_map<int, int> sphereVertexToBowlVertex;
46 for (
int i = 0; i < sphereVerticesPtr->size(); i++)
48 const Vec3d sphereVertex = (*sphereVerticesPtr)[i];
49 if (sphereVertex[1] < 1.0)
51 const int vertexId = bowlVerticesPtr->size();
52 sphereVertexToBowlVertex[i] = vertexId;
53 bowlVerticesPtr->push_back(sphereVertex);
58 for (
int i = 0; i < sphereIndicesPtr->size(); i++)
60 const Vec3i& tri = (*sphereIndicesPtr)[i];
62 if (sphereVertexToBowlVertex.count(tri[0]) != 0
63 && sphereVertexToBowlVertex.count(tri[1]) != 0
64 && sphereVertexToBowlVertex.count(tri[2]) != 0)
67 sphereVertexToBowlVertex[tri[0]],
68 sphereVertexToBowlVertex[tri[1]],
69 sphereVertexToBowlVertex[tri[2]]);
70 std::swap(newTri[0], newTri[1]);
71 bowlIndicesPtr->push_back(newTri);
74 auto results = std::make_shared<SurfaceMesh>();
75 results->initialize(bowlVerticesPtr, bowlIndicesPtr);
76 results->scale(Vec3d(1.0, 0.5, 1.0), Geometry::TransformType::ApplyToData);
77 results->translate(Vec3d(0.0, 0.0, 0.0), Geometry::TransformType::ApplyToData);
95 rbdModel->getConfig()->m_maxNumIterations = 10;
100 std::shared_ptr<SurfaceMesh> bowlMesh = createBowlMesh();
103 floorObj->setVisualGeometry(bowlMesh);
104 floorObj->setCollidingGeometry(bowlMesh);
106 auto material = std::make_shared<RenderMaterial>();
107 material->setDisplayMode(RenderMaterial::DisplayMode::WireframeSurface);
109 material->setDiffuseColor(
Color(1.0, 0.8, 0.74));
110 material->setRoughness(0.5);
111 material->setMetalness(0.1);
112 floorObj->getVisualModel(0)->setRenderMaterial(material);
114 scene->addSceneObject(floorObj);
117 std::array<std::shared_ptr<RigidObject2>, 6> rigidObjects;
118 const int rbdObjCount =
static_cast<int>(rigidObjects.size());
119 for (
int i = 0; i < rbdObjCount; i++)
121 rigidObjects[i] = std::make_shared<RigidObject2>(
"RbdObject" + std::to_string(i));
122 const double radius = 0.8;
126 rigidObjects[i]->setDynamicalModel(rbdModel);
127 rigidObjects[i]->setPhysicsGeometry(sphere);
128 rigidObjects[i]->setCollidingGeometry(sphere);
129 rigidObjects[i]->setVisualGeometry(sphere);
130 rigidObjects[i]->getRigidBody()->m_mass = 1.0;
131 const double t =
static_cast<double>(i) / (rbdObjCount - 1);
132 rigidObjects[i]->getRigidBody()->m_initPos = Vec3d((t - 0.5) * rbdObjCount * radius * 2.0, 1.0, 0.0);
133 rigidObjects[i]->getRigidBody()->m_intertiaTensor = Mat3d::Identity();
135 auto material = std::make_shared<RenderMaterial>();
136 material->setDiffuseColor(Color::lerpRgb(
Color(1.0, 0.333, 0.259),
Color(0.427, 1.0, 0.58), t));
138 material->setRoughness(0.5);
139 material->setMetalness(0.5);
140 rigidObjects[i]->getVisualModel(0)->setRenderMaterial(material);
142 scene->addSceneObject(rigidObjects[i]);
147 for (
int i = 0; i < rbdObjCount; i++)
149 auto rbdInteraction = std::make_shared<RigidObjectCollision>(rigidObjects[i], floorObj,
"SurfaceMeshToSphereCD");
150 rbdInteraction->setFriction(0.0);
151 rbdInteraction->setBaumgarteStabilization(0.0001);
152 scene->addInteraction(rbdInteraction);
155 for (
int i = 0; i < rbdObjCount; i++)
157 for (
int j = i + 1; j < rbdObjCount; j++)
159 auto rbdInteraction = std::make_shared<RigidObjectCollision>(rigidObjects[i], rigidObjects[j],
"SphereToSphereCD");
160 rbdInteraction->setFriction(0.0);
161 rbdInteraction->setBaumgarteStabilization(0.0001);
162 scene->addInteraction(rbdInteraction);
168 scene->getActiveCamera()->setPosition(0.0252374, 2.85008, 17.0338);
169 scene->getActiveCamera()->setFocalPoint(0.0, 0.0, 0.0);
170 scene->getActiveCamera()->setViewUp(0.0016057, 0.999996, 0.00220191);
175 scene->addLight(
"light", light);
186 sceneManager->pause();
194 std::shared_ptr<Entity> mouseAndKeyControls =
195 SimulationUtils::createDefaultSceneControl(driver);
196 scene->addSceneObject(mouseAndKeyControls);
200 LOG(INFO) <<
"RbdObj Controls:";
201 LOG(INFO) <<
"----------------------------------------------------------------------";
202 LOG(INFO) <<
" | click and drag to pick up sphere";
206 int sphereSelected = -1;
209 connect<MouseEvent>(viewer->
getMouseDevice(), &MouseDeviceClient::mouseButtonPress,
212 if (e->m_buttonId == 0)
217 const Vec3d rayDir = scene->getActiveCamera()->getEyeRayDir(
218 Vec2d(mousePos[0] * 2.0 - 1.0, mousePos[1] * 2.0 - 1.0));
219 const Vec3d rayStart = scene->getActiveCamera()->getPosition();
221 double minDist = IMSTK_DOUBLE_MAX;
222 for (
int i = 0; i < rbdObjCount; i++)
224 auto sphere = std::dynamic_pointer_cast<
Sphere>(rigidObjects[i]->getPhysicsGeometry());
226 if (CollisionUtils::testRayToSphere(rayStart, rayDir,
227 sphere->getCenter(), sphere->getRadius(), iPt))
229 const double dist = (iPt - rayStart).norm();
241 connect<MouseEvent>(viewer->
getMouseDevice(), &MouseDeviceClient::mouseButtonRelease,
244 if (e->m_buttonId == 0)
249 connect<Event>(sceneManager, &SceneManager::postUpdate,
253 std::shared_ptr<RigidBodyModel2> rbdModel = rigidObjects[0]->getRigidBodyModel2();
254 rbdModel->getConfig()->m_dt = sceneManager->getDt();
256 if (sphereSelected != -1)
260 const Vec3d rayDir = scene->getActiveCamera()->getEyeRayDir(
261 Vec2d(mousePos[0] * 2.0 - 1.0, mousePos[1] * 2.0 - 1.0));
262 const Vec3d rayStart = scene->getActiveCamera()->getPosition();
265 auto sphere = std::dynamic_pointer_cast<
Sphere>(rigidObjects[sphereSelected]->getPhysicsGeometry());
267 CollisionUtils::testRayToPlane(rayStart, rayDir, planePos, scene->getActiveCamera()->getForward(), iPt);
268 const Vec3d fS = (iPt - sphere->getPosition()) * 100.0;
269 const Vec3d fD = -rigidObjects[sphereSelected]->getRigidBody()->getVelocity() * 10.0;
270 *rigidObjects[sphereSelected]->getRigidBody()->m_force += (fS + fD);
void setDesiredDt(const double dt)
Sets the target fixed timestep (may violate), seconds This ultimately effects the number of iteration...
void setActiveScene(std::shared_ptr< Scene > scene) override
Set scene to be rendered.
Base class for events which contain a type, priority, and data priority defaults to 0 and uses a grea...
void addModule(std::shared_ptr< Module > module) override
Add a module to run.
void setIntensity(const double intensity)
Set the light intensity. This value is unbounded.
std::shared_ptr<T> obj = std::make_shared<T>(); equivalent, convenience class for STL shared allocati...
virtual Vec3d getCenter()
Returns the bounding box center.
Represents a sphere via its position & radius.
std::shared_ptr< SurfaceMesh > toUVSphereSurfaceMesh(std::shared_ptr< Sphere > sphere, const unsigned int phiDivisions, const unsigned int thetaDivisions)
UV sphere from imstkSphere.
Provides the information of a mouse event, this includes button presses/releases and scrolling...
void setActiveScene(std::string newSceneName)
Sets the currently updating scene.
Physically based rendering.
std::shared_ptr< MouseDeviceClient > getMouseDevice() const override
Returns the device that emits mouse events.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.