diff --git a/Examples/PDBPicking/PBDPickingExample.cpp b/Examples/PDBPicking/PBDPickingExample.cpp index c7f8b0eef6d44f663f13d292ef53ec34c8d4934c..f9c655267a487deffe73e0cd52092d68b0b8b7e5 100644 --- a/Examples/PDBPicking/PBDPickingExample.cpp +++ b/Examples/PDBPicking/PBDPickingExample.cpp @@ -211,22 +211,26 @@ main() imstkNew<Capsule> geomUpperJaw; geomUpperJaw->setLength(30.0); - //geomUpperJaw->setPosition(Vec3d(0.0, 0.0, -12.5)); + geomUpperJaw->setPosition(Vec3d(0.0, 0.0, -12.5)); geomUpperJaw->setRadius(1.0); geomUpperJaw->setOrientationAxis(Vec3d(0.0, 0.0, 1.0)); imstkNew<CollidingObject> objUpperJaw("UpperJawObject"); objUpperJaw->setVisualGeometry(geomUpperJaw); objUpperJaw->setCollidingGeometry(geomUpperJaw); - //auto mapUpperJaw = std::make_shared<IsometricMap>(geomUpperJaw, upperSurfMesh); - //objUpperJaw->setCollidingToVisualMap(mapUpperJaw); + /* auto mapUpperJaw = std::make_shared<IsometricMap>(geomUpperJaw, upperSurfMesh); + objUpperJaw->setCollidingToVisualMap(mapUpperJaw);*/ scene->addSceneObject(objUpperJaw); imstkNew<Capsule> geomLowerJaw; + geomLowerJaw->setLength(30.0); + geomLowerJaw->setPosition(Vec3d(0.0, 0.0, -12.5)); + geomLowerJaw->setRadius(1.0); + geomLowerJaw->setOrientationAxis(Vec3d(0.0, 0.0, 1.0)); imstkNew<CollidingObject> objLowerJaw("LowerJawObject"); - objLowerJaw->setVisualGeometry(lowerSurfMesh); + objLowerJaw->setVisualGeometry(geomLowerJaw); objLowerJaw->setCollidingGeometry(geomLowerJaw); - auto mapLowerJaw = std::make_shared<IsometricMap>(geomLowerJaw, lowerSurfMesh); - objLowerJaw->setCollidingToVisualMap(mapLowerJaw); + //auto mapLowerJaw = std::make_shared<IsometricMap>(geomLowerJaw, lowerSurfMesh); + //objLowerJaw->setCollidingToVisualMap(mapLowerJaw); scene->addSceneObject(objLowerJaw); std::shared_ptr<PbdObject> clothObj = makeClothObj("Cloth", width, height, nRows, nCols); @@ -242,7 +246,7 @@ main() scene->getCollisionGraph()->addInteraction(pair); // Camera - scene->getActiveCamera()->setPosition(Vec3d(200, 200, 200)); + scene->getActiveCamera()->setPosition(Vec3d(1, 1, 1) * 100.0); scene->getActiveCamera()->setFocalPoint(Vec3d(0, 0, 0)); // Light diff --git a/Source/Common/imstkMath.h b/Source/Common/imstkMath.h index fed99309ed902ad6667757fc1ef7919b27b7f07a..feeef99e175b2f886ba4611a797b2d3184e90af2 100644 --- a/Source/Common/imstkMath.h +++ b/Source/Common/imstkMath.h @@ -166,4 +166,56 @@ using AffineTransform3d = Eigen::Affine3d; #define MAX_F std::numeric_limits<float>::max() #define MIN_F std::numeric_limits<float>::min() #define VERY_SMALL_EPSILON_F std::numeric_limits<float>::epsilon() + +static inline Mat4d mat4dTranslate(const Vec3d& translate) +{ + return AffineTransform3d(Eigen::Translation3d(translate)).matrix(); +} +static inline Mat4d mat4dScale(const Vec3d& scale) +{ + Mat4d mScale = Mat4d::Identity(); + mScale(0, 0) = scale[0]; + mScale(1, 1) = scale[1]; + mScale(2, 2) = scale[2]; + return mScale; +} +static inline Mat4d mat4dRotation(const Quatd& rotation) +{ + Mat4d mRot = Mat4d::Identity(); + mRot.block<3, 3>(0, 0) = rotation.toRotationMatrix(); + return mRot; +} +static inline Mat4d mat4dRotation(const Rotd& rotation) +{ + Mat4d mRot = Mat4d::Identity(); + mRot.block<3, 3>(0, 0) = rotation.toRotationMatrix(); + return mRot; +} +static inline Mat4d mat4dRotation(const Mat3d& rotation) +{ + Mat4d mRot = Mat4d::Identity(); + mRot.block<3, 3>(0, 0) = rotation; + return mRot; +} +/// +/// \brief Translation, Rotation, Scaling decomposition, ignores shears +/// +static inline void mat4dTRS(const Mat4d& m, Vec3d& t, Mat3d& r, Vec3d& s) +{ + // Assumes affine, no shear + const Vec3d& x = m.block<3, 1>(0, 0); + const Vec3d& y = m.block<3, 1>(0, 1); + const Vec3d& z = m.block<3, 1>(0, 2); + + s = Vec3d(m.block<3, 1>(0, 0).norm(), + m.block<3, 1>(0, 1).norm(), + m.block<3, 1>(0, 2).norm()); + + r = Mat3d::Identity(); + r.block<3, 1>(0, 0) = x.normalized(); + r.block<3, 1>(0, 1) = y.normalized(); + r.block<3, 1>(0, 2) = z.normalized(); + + t = m.block<3, 1>(0, 3); +} } diff --git a/Source/Controllers/imstkLaparoscopicToolController.cpp b/Source/Controllers/imstkLaparoscopicToolController.cpp index 8a32aa270ccc19c18731e32d9b2a5c791f905411..c9991925f8ba3bf4eb8211837950e1808c3adcfa 100644 --- a/Source/Controllers/imstkLaparoscopicToolController.cpp +++ b/Source/Controllers/imstkLaparoscopicToolController.cpp @@ -39,6 +39,15 @@ LaparoscopicToolController::LaparoscopicToolController( m_jawRotationAxis(Vec3d(1, 0, 0)) { trackingDevice->setButtonsEnabled(true); + + // Record the transforms as 4x4 matrices (this should capture initial displacement/rotation of the jaws from the shaft) + m_shaftWorldTransform = mat4dRotation(m_shaft->getMasterGeometry()->getRotation()) * mat4dTranslate(m_shaft->getMasterGeometry()->getTranslation()); + + m_upperJawLocalTransform = mat4dRotation(m_upperJaw->getMasterGeometry()->getRotation()) * mat4dTranslate(m_upperJaw->getMasterGeometry()->getTranslation()); + m_lowerJawLocalTransform = mat4dRotation(m_lowerJaw->getMasterGeometry()->getRotation()) * mat4dTranslate(m_lowerJaw->getMasterGeometry()->getTranslation()); + + m_upperJawWorldTransform = m_shaftWorldTransform * m_upperJawLocalTransform; + m_lowerJawWorldTransform = m_shaftWorldTransform * m_lowerJawLocalTransform; } void @@ -53,8 +62,19 @@ LaparoscopicToolController::updateControlledObjects() } } - Vec3d p = getPosition(); - Quatd r = getRotation(); + const Vec3d controllerPosition = getPosition(); + const Quatd controllerOrientation = getRotation(); + + // Controller transform + m_shaftWorldTransform = mat4dTranslate(controllerPosition) * mat4dRotation(controllerOrientation); + { + // TRS decompose and set shaft + Vec3d t, s; + Mat3d r; + mat4dTRS(m_shaftWorldTransform, t, r, s); + m_shaft->getMasterGeometry()->setRotation(r); + m_shaft->getMasterGeometry()->setTranslation(t); + } // Update jaw angles if (m_deviceClient->getButton(0)) @@ -62,28 +82,31 @@ LaparoscopicToolController::updateControlledObjects() m_jawAngle += m_change; m_jawAngle = (m_jawAngle > m_maxJawAngle) ? m_maxJawAngle : m_jawAngle; } - if (m_deviceClient->getButton(1)) { m_jawAngle -= m_change; m_jawAngle = (m_jawAngle < 0.0) ? 0.0 : m_jawAngle; } - // Update orientation of parts - Quatd jawRotUpper; - jawRotUpper = r * Rotd(m_jawAngle, m_jawRotationAxis); - m_upperJaw->getMasterGeometry()->setRotation(jawRotUpper); + m_upperJawLocalTransform = mat4dRotation(Rotd(m_jawAngle, m_jawRotationAxis)); + m_lowerJawLocalTransform = mat4dRotation(Rotd(-m_jawAngle, m_jawRotationAxis)); + m_upperJawWorldTransform = m_shaftWorldTransform * m_upperJawLocalTransform; + m_lowerJawWorldTransform = m_shaftWorldTransform * m_lowerJawLocalTransform; - Quatd jawRotLower; - jawRotLower = r * Rotd(-m_jawAngle, m_jawRotationAxis); - m_lowerJaw->getMasterGeometry()->setRotation(jawRotLower); - - m_shaft->getMasterGeometry()->setRotation(r); - - // Update positions of parts - m_shaft->getMasterGeometry()->setTranslation(p); - m_upperJaw->getMasterGeometry()->setTranslation(p); - m_lowerJaw->getMasterGeometry()->setTranslation(p); + { + Vec3d t, s; + Mat3d r; + mat4dTRS(m_upperJawWorldTransform, t, r, s); + m_upperJaw->getMasterGeometry()->setRotation(r); + m_upperJaw->getMasterGeometry()->setTranslation(t); + } + { + Vec3d t, s; + Mat3d r; + mat4dTRS(m_lowerJawWorldTransform, t, r, s); + m_lowerJaw->getMasterGeometry()->setRotation(r); + m_lowerJaw->getMasterGeometry()->setTranslation(t); + } } void diff --git a/Source/Controllers/imstkLaparoscopicToolController.h b/Source/Controllers/imstkLaparoscopicToolController.h index 2c1e1c9c41d504478ec2cafe31863fbe9de52a16..4b7d498fa154b02debd9165887771f9efd69047a 100644 --- a/Source/Controllers/imstkLaparoscopicToolController.h +++ b/Source/Controllers/imstkLaparoscopicToolController.h @@ -97,5 +97,13 @@ protected: double m_maxJawAngle = PI / 6.0; ///< Maximum angle of the jaws Vec3d m_jawRotationAxis; ///< Angle of the jaws + + Mat4d m_shaftWorldTransform = Mat4d::Identity(); // Final world transform of the shaft + + Mat4d m_upperJawWorldTransform = Mat4d::Identity(); // Final world transform of the upper jaw + Mat4d m_lowerJawWorldTransform = Mat4d::Identity();// Final world transform of the lower jaw + + Mat4d m_upperJawLocalTransform = Mat4d::Identity(); // m_upperJawWorldTransform = m_shaftWorldTransform * m_upperJawLocalTransform + Mat4d m_lowerJawLocalTransform = Mat4d::Identity(); // m_lowerJawWorldTransform = m_shaftWorldTransform * m_lowerJawLocalTransform }; } // imstk