void FiberApplication::ObjectDragger::dragStartCallback(Vrui::DraggingTool::DragStartCallbackData* cbData) { if(application->m_SelectionBox.size()>0) { bool isHit = false; std::vector<SelectionBox*> selectionBox = application->getSelectionBoxVector(); float minLambda=Math::Constants<float>::max; //Find the picked object: if(cbData->rayBased) { for(int i=0; i<selectionBox.size();i++) { Geometry::Box<float,3>::HitResult hr = selectionBox[i]->pickBox(cbData->ray); if(hr.isValid() && hr.getParameter()<minLambda) { isHit = true; m_selectedBox=selectionBox[i]; minLambda=hr.getParameter(); } } } else { for(int i=0; i<selectionBox.size();i++) { float dist = selectionBox[i]->pickBox(cbData->startTransformation.getOrigin()); if(dist<minLambda) { isHit = true; m_selectedBox=selectionBox[i]; minLambda=dist; } } } if(isHit) { dragging =true; //Calculate the initial transformation from the dragger to the dragged object: dragTransform=ONTransform(cbData->startTransformation.getTranslation(),cbData->startTransformation.getRotation()); dragTransform.doInvert(); dragTransform*= ONTransform(m_selectedBox->getCenter() - Geometry::Point<float,3>::origin,SelectionBox::Rotation::identity); m_selectedBox->toggleIsBoxSelected(); } } }
void TwoRayTransformTool::frame(void) { /* Check if the device is currently dragging a ray: */ if(active) { /* Calculate the device's ray equation in navigational coordinates: */ rays[numRays]=sourceDevice->getRay(); rays[numRays].transform(getInverseNavigationTransformation()); /* Check if there are two rays (one final and one intermediate): */ if(numRays==1) { /* Calculate the "intersection" point between the two rays: */ Geometry::Matrix<Scalar,3,3> a; Geometry::ComponentArray<Scalar,3> b; Vector bin=rays[0].getDirection()^rays[1].getDirection(); for(int i=0;i<3;++i) { a(i,0)=rays[0].getDirection()[i]; a(i,1)=-rays[1].getDirection()[i]; a(i,2)=bin[i]; b[i]=rays[1].getOrigin()[i]-rays[0].getOrigin()[i]; } Geometry::ComponentArray<Scalar,3> x=b/a; intersection=Geometry::mid(rays[0](x[0]),rays[1](x[1])); } } if(numRays>=(active?1:2)) { /* Set the transformed device's position and orientation: */ transformedDevice->setDeviceRay(sourceDevice->getDeviceRayDirection(),Scalar(0)); transformedDevice->setTransformation(ONTransform(getNavigationTransformation().transform(intersection)-Point::origin,sourceDevice->getTransformation().getRotation())); } }
void Jello::AtomDragger::dragCallback(Vrui::DraggingTool::DragCallbackData* cbData) { if(dragging) { /* Apply the dragging transformation to the dragged atom: */ ONTransform transform=ONTransform(cbData->currentTransformation.getTranslation(),cbData->currentTransformation.getRotation()); transform*=dragTransform; application->crystal.setAtomState(draggedAtom,transform); } }
void FiberApplication::ObjectDragger::dragCallback(Vrui::DraggingTool::DragCallbackData* cbData) { if(dragging) { // Apply the dragging transformation to the dragged atom: ONTransform transform=ONTransform(cbData->currentTransformation.getTranslation(),cbData->currentTransformation.getRotation()); transform*=dragTransform; m_selectedBox->move(transform.getOrigin()); } }
void Jello::AtomDragger::dragStartCallback(Vrui::DraggingTool::DragStartCallbackData* cbData) { /* Find the picked atom: */ if(cbData->rayBased) draggedAtom=application->crystal.pickAtom(cbData->ray); else draggedAtom=application->crystal.pickAtom(cbData->startTransformation.getOrigin()); /* Try locking the atom: */ if(application->crystal.lockAtom(draggedAtom)) { dragging=true; /* Calculate the initial transformation from the dragger to the dragged atom: */ dragTransform=ONTransform(cbData->startTransformation.getTranslation(),cbData->startTransformation.getRotation()); dragTransform.doInvert(); dragTransform*=application->crystal.getAtomState(draggedAtom); } }
ONTransform UIManagerSpherical::calcUITransform(const Point& point) const { /* Project the given point onto the sphere: */ Vector d=point-sphere.getCenter(); Scalar dLen=d.mag(); if(dLen==Scalar(0)) { d=getForwardDirection(); dLen=d.mag(); } Point spherePoint=sphere.getCenter()+d*(sphere.getRadius()/dLen); /* Calculate the UI transformation: */ Vector x=d^getUpDirection(); if(x.mag()==Scalar(0)) x=getForwardDirection()^getUpDirection(); Vector y=x^d; return ONTransform(spherePoint-Point::origin,Rotation::fromBaseVectors(x,y)); }
void VRScreen::initialize(const Misc::ConfigurationFileSection& configFileSection) { /* Read the screen's name: */ std::string name=configFileSection.retrieveString("./name"); screenName=new char[name.size()+1]; strcpy(screenName,name.c_str()); /* Determine whether screen is device-mounted: */ deviceMounted=configFileSection.retrieveValue<bool>("./deviceMounted",false); if(deviceMounted) { /* Retrieve the input device this screen is attached to: */ std::string deviceName=configFileSection.retrieveString("./deviceName"); device=findInputDevice(deviceName.c_str()); if(device==0) Misc::throwStdErr("VRScreen: Mounting device \"%s\" not found",deviceName.c_str()); } /* Retrieve screen position/orientation in physical or device coordinates: */ try { /* Try reading the screen transformation directly: */ transform=configFileSection.retrieveValue<ONTransform>("./transform"); } catch(std::runtime_error) { /* Fall back to reading the screen's origin and axis directions: */ Point origin=configFileSection.retrieveValue<Point>("./origin"); Vector horizontalAxis=configFileSection.retrieveValue<Vector>("./horizontalAxis"); Vector verticalAxis=configFileSection.retrieveValue<Vector>("./verticalAxis"); ONTransform::Rotation rot=ONTransform::Rotation::fromBaseVectors(horizontalAxis,verticalAxis); transform=ONTransform(origin-Point::origin,rot); } /* Read the screen's size: */ screenSize[0]=configFileSection.retrieveValue<Scalar>("./width"); screenSize[1]=configFileSection.retrieveValue<Scalar>("./height"); /* Apply a rotation around a single axis: */ Point rotateCenter=configFileSection.retrieveValue<Point>("./rotateCenter",Point::origin); Vector rotateAxis=configFileSection.retrieveValue<Vector>("./rotateAxis",Vector(1,0,0)); Scalar rotateAngle=configFileSection.retrieveValue<Scalar>("./rotateAngle",Scalar(0)); if(rotateAngle!=Scalar(0)) { ONTransform screenRotation=ONTransform::translateFromOriginTo(rotateCenter); screenRotation*=ONTransform::rotate(ONTransform::Rotation::rotateAxis(rotateAxis,Math::rad(rotateAngle))); screenRotation*=ONTransform::translateToOriginFrom(rotateCenter); transform.leftMultiply(screenRotation); } /* Apply an arbitrary pre-transformation: */ ONTransform preTransform=configFileSection.retrieveValue<ONTransform>("./preTransform",ONTransform::identity); transform.leftMultiply(preTransform); /* Finalize the screen transformation: */ transform.renormalize(); inverseTransform=Geometry::invert(transform); /* Check if the screen is projected off-axis: */ offAxis=configFileSection.retrieveValue<bool>("./offAxis",offAxis); if(offAxis) { /* Create the inverse of the 2D homography from clip space to rectified screen space in screen coordinates: */ PTransform2 sHomInv=PTransform2::identity; sHomInv.getMatrix()(0,0)=Scalar(2)/screenSize[0]; sHomInv.getMatrix()(0,2)=Scalar(-1); sHomInv.getMatrix()(1,1)=Scalar(2)/screenSize[1]; sHomInv.getMatrix()(1,2)=Scalar(-1); sHomInv.getMatrix()(2,2)=Scalar(1); /* Retrieve the 2D homography from clip space to projected screen space in screen coordinates: */ PTransform2 pHom=configFileSection.retrieveValue<PTransform2>("./homography"); /* Calculate the screen space homography: */ screenHomography=pHom*sHomInv; /* Calculate the clip space homography: */ PTransform2 hom=sHomInv*pHom; for(int i=0;i<3;++i) for(int j=0;j<3;++j) inverseClipHomography.getMatrix()(i<2?i:3,j<2?j:3)=hom.getMatrix()(i,j); /* Put in correction factors to keep the frustum's far plane in the same position: */ inverseClipHomography.getMatrix()(2,0)=inverseClipHomography.getMatrix()(3,0); inverseClipHomography.getMatrix()(2,1)=inverseClipHomography.getMatrix()(3,1); inverseClipHomography.doInvert(); } }
void SharedJello::AtomDragger::dragCallback(Vrui::DraggingTool::DragCallbackData* cbData) { /* Update the dragger position: */ draggerTransformation=ONTransform(cbData->currentTransformation.getTranslation(),cbData->currentTransformation.getRotation()); }
void ClusterJello::AtomDragger::idleMotionCallback(Vrui::DraggingTool::IdleMotionCallbackData* cbData) { /* Update the dragger position: */ draggerTransformation=ONTransform(cbData->currentTransformation.getTranslation(),cbData->currentTransformation.getRotation()); }