bool DraggerVolumeTileCallback::receive(const osgManipulator::MotionCommand &command) { if (!_locator) return false; switch (command.getStage()) { case osgManipulator::MotionCommand::START: { // Save the current matrix _startMotionMatrix = _locator->getTransform(); // Get the LocalToWorld and WorldToLocal matrix for this node. osg::NodePath nodePathToRoot; osgManipulator::computeNodePathToRoot(*_volume, nodePathToRoot); _localToWorld = _startMotionMatrix * osg::computeLocalToWorld(nodePathToRoot); _worldToLocal = osg::Matrix::inverse(_localToWorld); return true; } case osgManipulator::MotionCommand::MOVE: { // Transform the command's motion matrix into local motion matrix. osg::Matrix localMotionMatrix = _localToWorld * command.getWorldToLocal() * command.getMotionMatrix() * command.getLocalToWorld() * _worldToLocal; // Transform by the localMotionMatrix _locator->setTransform(localMotionMatrix * _startMotionMatrix); // osg::notify(osg::NOTICE)<<"New locator matrix "<<_locator->getTransform()<<std::endl; return true; } case osgManipulator::MotionCommand::FINISH: { return true; } case osgManipulator::MotionCommand::NONE: default: return false; } }