void ValuatorFlyTurnNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Get the current state of the input device: */ const TrackerState& ts=getDeviceTransformation(0); /* Check whether to change the super acceleration factor: */ if(Math::abs(currentValues[0])==Scalar(1)) superAcceleration*=Math::pow(factory->superAccelerationFactor,getFrameTime()); /* Calculate the current flying velocity: */ Vector v=factory->flyDirectionDeviceCoordinates?ts.transform(factory->flyDirection):factory->flyDirection; v*=-currentValues[0]*factory->flyFactor*superAcceleration*getFrameTime(); /* Calculate the current angular velocity: */ Vector w=factory->rotationAxisDeviceCoordinates?ts.transform(factory->rotationAxis):factory->rotationAxis; w*=currentValues[1]*factory->rotationFactor*getFrameTime(); /* Compose the new navigation transformation: */ Point p=factory->rotationCenterDeviceCoordinates?ts.transform(factory->rotationCenter):factory->rotationCenter; NavTransform t=NavTransform::translate(v); t*=NavTransform::translateFromOriginTo(p); t*=NavTransform::rotate(NavTransform::Rotation::rotateScaledAxis(w)); t*=NavTransform::translateToOriginFrom(p); t*=getNavigationTransformation(); /* Update Vrui's navigation transformation: */ setNavigationTransformation(t); } }
void DesktopDeviceTool::frame(void) { int aib=axisIndexBase*factory->numValuators; /* Convert translational axes into translation vector: */ Vector translation=Vector::zero; for(int i=0;i<factory->numTranslationAxes;++i) if(factory->translationAxes[i].index>=aib&&factory->translationAxes[i].index<aib+factory->numValuators) translation+=factory->translationAxes[i].axis*getDeviceValuator(0,factory->translationAxes[i].index-aib); translation*=factory->translateFactor*getFrameTime(); /* Convert rotational axes into rotation axis vector and rotation angle: */ Vector scaledRotationAxis=Vector::zero; for(int i=0;i<factory->numRotationAxes;++i) if(factory->rotationAxes[i].index>=aib&&factory->rotationAxes[i].index<aib+factory->numValuators) scaledRotationAxis+=factory->rotationAxes[i].axis*getDeviceValuator(0,factory->rotationAxes[i].index-aib); scaledRotationAxis*=factory->rotateFactor*getFrameTime(); /* Calculate an incremental transformation for the virtual input device: */ ONTransform deltaT=ONTransform::translate(translation); Point pos=transformedDevice->getPosition(); deltaT*=ONTransform::translateFromOriginTo(pos); deltaT*=ONTransform::rotate(ONTransform::Rotation::rotateScaledAxis(scaledRotationAxis)); deltaT*=ONTransform::translateToOriginFrom(pos); /* Update the virtual input device's transformation: */ deltaT*=transformedDevice->getTransformation(); deltaT.renormalize(); transformedDevice->setTransformation(deltaT); requestUpdate(); }
void ViewpointFileNavigationTool::buttonCallback(int,InputDevice::ButtonCallbackData* cbData) { if(cbData->newButtonState) // Activation button has just been pressed { #if 0 /* Set the next saved viewpoint if the tool can be activated: */ if(!viewpoints.empty()&&activate()) { /* Compute the appropriate navigation transformation from the next viewpoint: */ const Viewpoint& v=viewpoints[nextViewpointIndex]; NavTransform nav=NavTransform::identity; nav*=NavTransform::translateFromOriginTo(getDisplayCenter()); nav*=NavTransform::rotate(Rotation::fromBaseVectors(Geometry::cross(getForwardDirection(),getUpDirection()),getForwardDirection())); nav*=NavTransform::scale(getDisplaySize()/Math::exp(v.size)); // Scales are interpolated logarithmically nav*=NavTransform::rotate(Geometry::invert(Rotation::fromBaseVectors(Geometry::cross(v.forward,v.up),v.forward))); nav*=NavTransform::translateToOriginFrom(v.center); /* Set the viewpoint: */ setNavigationTransformation(nav); /* Go to the next viewpoint: */ ++nextViewpointIndex; if(nextViewpointIndex==viewpoints.size()) nextViewpointIndex=0U; /* Deactivate the tool: */ deactivate(); } #else /* Start animating the viewpoint if there are spline segments and the tool can be activated: */ if(!splines.empty()) { if(paused&&activate()) { /* Unpause the animation: */ paused=false; parameter-=Scalar(getFrameTime())*speed; } else if(isActive()) { /* Pause the animation: */ paused=true; deactivate(); } else if(activate()) { /* Animate from the beginning: */ paused=false; parameter=splines.front().t[0]-Scalar(getFrameTime())*speed; if(positionSlider!=0) positionSlider->setValue(parameter); } } #endif } }
void VideoDecoder::convertAndPushPicture(const AVFrame* frame) { // Allocate a picture to hold the YUV data AVFrame* yuvFrame = av_frame_alloc(); av_frame_copy(yuvFrame, frame); yuvFrame->format = DESTINATION_FORMAT; av_image_alloc(yuvFrame->data, yuvFrame->linesize, m_status->videoCodecPars.width, m_status->videoCodecPars.height, DESTINATION_FORMAT, 1); std::unique_ptr<FFMPEGVideoFrame> videoFramePtr(new FFMPEGVideoFrame()); if (m_status->videoCodecPars.pixel_format == DESTINATION_FORMAT) { av_image_copy(yuvFrame->data, yuvFrame->linesize, (const uint8_t**) (frame->data), frame->linesize, DESTINATION_FORMAT, m_status->videoCodecPars.width, m_status->videoCodecPars.height); } else { // Convert frame to YUV sws_scale( m_swsCtx, (uint8_t const* const*) frame->data, frame->linesize, 0, m_status->videoCodecPars.height, yuvFrame->data, yuvFrame->linesize ); } videoFramePtr->id = ++m_frameId; #if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(58, 3, 102) videoFramePtr->frameTime = getFrameTime(frame->best_effort_timestamp, m_status->videoStream->time_base); #else videoFramePtr->frameTime = getFrameTime(av_frame_get_best_effort_timestamp(frame), m_status->videoStream->time_base); #endif videoFramePtr->frame = yuvFrame; videoFramePtr->ySize.height = static_cast<size_t>(m_status->videoCodecPars.height); videoFramePtr->ySize.width = static_cast<size_t>(m_status->videoCodecPars.width); videoFramePtr->ySize.stride = static_cast<size_t>(yuvFrame->linesize[0]); // 420P means that the UV channels have half the width and height videoFramePtr->uvSize.height = static_cast<size_t>(m_status->videoCodecPars.height / 2); videoFramePtr->uvSize.width = static_cast<size_t>(m_status->videoCodecPars.width / 2); videoFramePtr->uvSize.stride = static_cast<size_t>(yuvFrame->linesize[1]); pushFrame(VideoFramePtr(videoFramePtr.release())); }
void ValuatorScalingNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Update the scaling factor: */ Scalar v=currentValue; Scalar t=factory->valuatorThreshold; Scalar s=Scalar(1)-t; if(v<-t) v=(v+t)/s; else if(v>t) v=(v-t)/s; else v=Scalar(0); currentScale*=Math::pow(factory->scalingFactor,v*getFrameTime()); /* Compose the new navigation transformation: */ NavTrackerState navigation=preScale; navigation*=NavTrackerState::scale(currentScale); navigation*=postScale; /* Update Vrui's navigation transformation: */ setNavigationTransformation(navigation); } }
void SpaceNavigatorClient::update() { double frameTime = getFrameTime(); // in ms _frameTranslationFactor = _translationFactor * (frameTime / 1000.0); _frameRotationFactor = _rotationFactor * (frameTime / 800.0); // process messages from server this->_button->mainloop(); this->_analog->mainloop(); }
std::string MyDirectDrawSw::getDebugInfo() const { const int BuffSize = 256; char buff[BuffSize]; std::snprintf(buff, BuffSize, "FPS %f, frametime %f\nMode %dx%dx%d, num surfaces: %d", getFPS(), getFrameTime(), mDispMode.width, mDispMode.height, mDispMode.bpp, mSurfaces.size()); return buff; }
void ValuatorTurnNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Get the current state of the input device: */ const TrackerState& ts=getButtonDeviceTransformation(0); /* Calculate the current flying velocity: */ Vector v=Vector::zero; if(buttonState) { v=ts.transform(factory->flyDirection); v*=-factory->flyFactor*getFrameTime(); } /* Calculate the current angular velocities: */ Vector w0=factory->rotationAxis0; w0*=currentValues[0]*factory->rotationFactor*getFrameTime(); Vector w1=factory->rotationAxis1; w1*=currentValues[1]*factory->rotationFactor*getFrameTime(); /* Compose the new navigation transformation: */ Point p=ts.transform(factory->rotationCenter); NavTransform t=NavTransform::translate(v); t*=NavTransform::translateFromOriginTo(p); t*=NavTransform::rotate(NavTransform::Rotation::rotateScaledAxis(w0)); t*=NavTransform::rotate(NavTransform::Rotation::rotateScaledAxis(w1)); t*=NavTransform::translateToOriginFrom(p); t*=getNavigationTransformation(); /* Update Vrui's navigation transformation: */ setNavigationTransformation(t); /* Request another frame: */ scheduleUpdate(getApplicationTime()+1.0/125.0); } }
void FlyNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Get the current state of the input device: */ const TrackerState& ts=getDeviceTransformation(0); /* Calculate the current flying velocity: */ Vector v=ts.transform(factory->flyDirection); v*=-factory->flyFactor*getFrameTime(); /* Compose the new navigation transformation: */ NavTransform t=NavTransform::translate(v); t*=getNavigationTransformation(); /* Update Vrui's navigation transformation: */ setNavigationTransformation(t); } }
void ViewpointFileNavigationTool::frame(void) { /* Animate the navigation transformation if the tool is active: */ if(isActive()) { /* Get the next curve parameter: */ Scalar newParameter=parameter+Scalar(getFrameTime())*speed; /* Check if a pause was scheduled between the last frame and this one: */ bool passedPause=false; for(std::vector<Scalar>::const_iterator pIt=pauses.begin();pIt!=pauses.end();++pIt) if(parameter<*pIt&&*pIt<=newParameter) { passedPause=true; newParameter=*pIt; break; } /* Navigate to the new curve parameter: */ if(!navigate(newParameter)) { /* Stop animating, curve is over: */ deactivate(); } else if(passedPause) { paused=true; deactivate(); } else { /* Request another frame: */ scheduleUpdate(getApplicationTime()+1.0/125.0); } /* Update the curve parameter and the GUI: */ parameter=newParameter; if(positionSlider!=0) positionSlider->setValue(parameter); } }
void ValuatorFlyNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Get the current state of the input device: */ const TrackerState& ts=getValuatorDeviceTransformation(0); /* Calculate the current flying velocity: */ Vector v=ts.transform(factory->flyDirection); v*=-currentValue*factory->flyFactor*getFrameTime(); /* Compose the new navigation transformation: */ NavTransform t=NavTransform::translate(v); t*=getNavigationTransformation(); /* Update Vrui's navigation transformation: */ setNavigationTransformation(t); /* Request another frame: */ scheduleUpdate(getApplicationTime()+1.0/125.0); } }
void MouseDialogNavigationTool::frame(void) { /* Update the current mouse position: */ currentPos=calcScreenPos(); /* Act depending on this tool's current state: */ if(isActive()) { if(spinning) { /* Calculate incremental rotation: */ rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getFrameTime()))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); } else { switch(navigationMode) { case ROTATING: { /* Calculate the rotation position: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; /* Calculate mouse displacement vector: */ Point rotationPos=currentPos; Vector delta=rotationPos-lastRotationPos; lastRotationPos=rotationPos; /* Calculate incremental rotation: */ Vector axis=Geometry::cross(offset,delta); Scalar angle=Geometry::mag(delta)/factory->rotateFactor; if(angle!=Scalar(0)) rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateAxis(axis,angle))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); break; } case PANNING: { /* Update the navigation transformation: */ NavTrackerState t=NavTrackerState::translate(currentPos-motionStart); t*=preScale; setNavigationTransformation(t); break; } case DOLLYING: { /* Calculate the current dollying direction: */ Vector dollyingDirection; if(mouseAdapter!=0) dollyingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenDollyingDirection); else dollyingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenDollyingDirection); /* Update the navigation transformation: */ Scalar dollyDist=((currentPos-motionStart)*dollyingDirection)/factory->dollyFactor; NavTrackerState t=NavTrackerState::translate(dollyDirection*dollyDist); t*=preScale; setNavigationTransformation(t); break; } case SCALING: { /* Calculate the current scaling direction: */ Vector scalingDirection; if(mouseAdapter!=0) scalingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenScalingDirection); else scalingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenScalingDirection); /* Update the navigation transformation: */ Scalar scale=((currentPos-motionStart)*scalingDirection)/factory->scaleFactor; NavTrackerState t=preScale; t*=NavTrackerState::scale(Math::exp(scale)); t*=postScale; setNavigationTransformation(t); break; } } } } }
void MouseNavigationTool::frame(void) { /* Update the current mouse position: */ Point newCurrentPos=calcScreenPos(); if(currentPos!=newCurrentPos) { currentPos=calcScreenPos(); lastMoveTime=getApplicationTime(); } if(factory->interactWithWidgets) { /* Update the GUI interactor: */ GUIInteractor::updateRay(); GUIInteractor::move(); } /* Act depending on this tool's current state: */ switch(navigationMode) { case ROTATING: { /* Calculate the rotation position: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; /* Calculate mouse displacement vector: */ Point rotationPos=currentPos; Vector delta=rotationPos-lastRotationPos; lastRotationPos=rotationPos; /* Calculate incremental rotation: */ Vector axis=Geometry::cross(offset,delta); Scalar angle=Geometry::mag(delta)/factory->rotateFactor; if(angle!=Scalar(0)) rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateAxis(axis,angle))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); break; } case SPINNING: { /* Calculate incremental rotation: */ rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getFrameTime()))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); scheduleUpdate(getApplicationTime()+1.0/125.0); break; } case PANNING: { /* Update the navigation transformation: */ NavTrackerState t=NavTrackerState::translate(currentPos-motionStart); t*=preScale; setNavigationTransformation(t); break; } case DOLLYING: { /* Calculate the current dollying direction: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); Vector dollyingDirection=screenT.transform(factory->screenDollyingDirection); /* Update the navigation transformation: */ Scalar dollyDist=((currentPos-motionStart)*dollyingDirection)/factory->dollyFactor; NavTrackerState t=NavTrackerState::translate(dollyDirection*dollyDist); t*=preScale; setNavigationTransformation(t); break; } case SCALING: { /* Calculate the current scaling direction: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); Vector scalingDirection=screenT.transform(factory->screenScalingDirection); /* Update the navigation transformation: */ Scalar scale=((currentPos-motionStart)*scalingDirection)/factory->scaleFactor; NavTrackerState t=preScale; t*=NavTrackerState::scale(Math::exp(scale)); t*=postScale; setNavigationTransformation(t); break; } case DOLLYING_WHEEL: { /* Update the navigation transformation: */ Scalar scale=currentValue; currentWheelScale+=factory->wheelDollyFactor*scale; NavTrackerState t=NavTrackerState::translate(dollyDirection*currentWheelScale); t*=preScale; setNavigationTransformation(t); break; } case SCALING_WHEEL: { /* Update the navigation transformation: */ Scalar scale=currentValue; currentWheelScale*=Math::pow(factory->wheelScaleFactor,scale); NavTrackerState t=preScale; t*=NavTrackerState::scale(currentWheelScale); t*=postScale; setNavigationTransformation(t); break; } default: ; } }
void DesktopDeviceNavigationTool::frame(void) { int aib=axisIndexBase*factory->numValuators; /* Convert translational axes into translation vector: */ Vector translation=Vector::zero; for(int i=0;i<factory->numTranslationAxes;++i) if(factory->translationAxes[i].index>=aib&&factory->translationAxes[i].index<aib+factory->numValuators) translation+=factory->translationAxes[i].axis*getDeviceValuator(0,factory->translationAxes[i].index-aib); translation*=factory->translateFactor*getFrameTime(); /* Convert rotational axes into rotation axis vector and rotation angle: */ Vector scaledRotationAxis=Vector::zero; for(int i=0;i<factory->numRotationAxes;++i) if(factory->rotationAxes[i].index>=aib&&factory->rotationAxes[i].index<aib+factory->numValuators) scaledRotationAxis+=factory->rotationAxes[i].axis*getDeviceValuator(0,factory->rotationAxes[i].index-aib); scaledRotationAxis*=factory->rotateFactor*getFrameTime(); /* Act depending on the tool's activation state: */ if(isActive()) { /* Convert zoom axes into zoom factor: */ Vector deltaZoom=Vector::zero; for(int i=0;i<factory->numZoomAxes;++i) if(factory->zoomAxes[i].index>=aib&&factory->zoomAxes[i].index<aib+factory->numValuators) deltaZoom+=factory->zoomAxes[i].axis*getDeviceValuator(0,factory->zoomAxes[i].index-aib); deltaZoom*=factory->zoomFactor*getFrameTime(); if(translation!=Vector::zero||scaledRotationAxis!=Vector::zero||deltaZoom[2]!=Scalar(0)) { /* Apply proper navigation mode: */ if(factory->invertNavigation) { translation=-translation; scaledRotationAxis=-scaledRotationAxis; } /* Calculate an incremental transformation based on the translation and rotation: */ NavTrackerState deltaT=NavTrackerState::translateFromOriginTo(factory->navigationCenter); deltaT*=NavTrackerState::translate(translation); deltaT*=NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(scaledRotationAxis)); deltaT*=NavTrackerState::scale(Math::exp(-deltaZoom[2])); deltaT*=NavTrackerState::translateToOriginFrom(factory->navigationCenter); /* Update the accumulated transformation: */ postScale.leftMultiply(deltaT); /* Update the navigation transformation: */ setNavigationTransformation(postScale); requestUpdate(); } } else if(translation!=Vector::zero||scaledRotationAxis!=Vector::zero) { /* Calculate an incremental transformation for the virtual input device: */ ONTransform deltaT=ONTransform::translate(translation); Point pos=virtualDevice->getPosition(); deltaT*=ONTransform::translateFromOriginTo(pos); deltaT*=ONTransform::rotate(ONTransform::Rotation::rotateScaledAxis(scaledRotationAxis)); deltaT*=ONTransform::translateToOriginFrom(pos); /* Update the virtual input device's transformation: */ deltaT*=virtualDevice->getTransformation(); deltaT.renormalize(); virtualDevice->setTransformation(deltaT); requestUpdate(); } }
void MouseDialogNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData) { if(cbData->newButtonState) // Button has just been pressed { /* Deactivate spinning: */ spinning=false; /* Start navigating according to the current navigation mode: */ switch(navigationMode) { case ROTATING: if(activate()) startRotating(); break; case PANNING: if(activate()) startPanning(); break; case DOLLYING: if(activate()) startDollying(); break; case SCALING: if(activate()) startScaling(); break; } } else // Button has just been released { /* Check for spinning if currently in rotating mode: */ if(navigationMode==ROTATING) { /* Check if the input device is still moving: */ Point currentPos=calcScreenPos(); Vector delta=currentPos-lastRotationPos; if(Geometry::mag(delta)>factory->spinThreshold) { /* Calculate spinning angular velocity: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; Vector axis=Geometry::cross(offset,delta); Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*getFrameTime()); spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag()); /* Enable spinning: */ spinning=true; } else { /* Deactivate the tool: */ deactivate(); } } else { /* Deactivate the tool: */ deactivate(); } } }
uint32 VideoDecoder::FixedRateVideoTrack::getNextFrameStartTime() const { if (endOfTrack() || getCurFrame() < 0) return 0; return getFrameTime(getCurFrame() + 1).msecs(); }
void WalkNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Calculate azimuth angle change based on the current viewing direction: */ Vector viewDir=getMainViewer()->getViewDirection(); viewDir-=getUpDirection()*((viewDir*getUpDirection())/Geometry::sqr(getUpDirection())); Scalar viewDir2=Geometry::sqr(viewDir); if(viewDir2!=Scalar(0)) { /* Calculate the rotation speed: */ Scalar viewAngleCos=(viewDir*factory->centerViewDirection)/Math::sqrt(viewDir2); Scalar viewAngle; if(viewAngleCos>Scalar(1)-Math::Constants<Scalar>::epsilon) viewAngle=Scalar(0); else if(viewAngleCos<Scalar(-1)+Math::Constants<Scalar>::epsilon) viewAngle=Math::Constants<Scalar>::pi; else viewAngle=Math::acos(viewAngleCos); Scalar rotateSpeed=Scalar(0); if(viewAngle>=factory->outerAngle) rotateSpeed=factory->rotateSpeed; else if(viewAngle>factory->innerAngle) rotateSpeed=factory->rotateSpeed*(viewAngle-factory->innerAngle)/(factory->outerAngle-factory->innerAngle); Vector x=factory->centerViewDirection^getUpDirection(); if(viewDir*x<Scalar(0)) rotateSpeed=-rotateSpeed; /* Update the accumulated rotation angle: */ azimuth+=rotateSpeed*getFrameTime(); if(azimuth<-Math::Constants<Scalar>::pi) azimuth+=Scalar(2)*Math::Constants<Scalar>::pi; else if(azimuth>=Math::Constants<Scalar>::pi) azimuth-=Scalar(2)*Math::Constants<Scalar>::pi; } /* Calculate the movement direction and speed: */ Point footPos=projectToFloor(getMainViewer()->getHeadPosition()); Vector moveDir=centerPoint-footPos; Scalar moveDirLen=moveDir.mag(); Scalar speed=Scalar(0); if(moveDirLen>=factory->outerRadius) speed=factory->moveSpeed; else if(moveDirLen>factory->innerRadius) speed=factory->moveSpeed*(moveDirLen-factory->innerRadius)/(factory->outerRadius-factory->innerRadius); moveDir*=speed/moveDirLen; /* Accumulate the transformation: */ NavTransform::Rotation rot=NavTransform::Rotation::rotateAxis(getUpDirection(),azimuth); translation+=rot.inverseTransform(moveDir*getFrameTime()); /* Set the navigation transformation: */ NavTransform nav=NavTransform::identity; nav*=Vrui::NavTransform::translateFromOriginTo(centerPoint); nav*=Vrui::NavTransform::rotate(rot); nav*=Vrui::NavTransform::translateToOriginFrom(centerPoint); nav*=Vrui::NavTransform::translate(translation); nav*=preScale; setNavigationTransformation(nav); if(speed!=Scalar(0)) { /* Request another frame: */ scheduleUpdate(getApplicationTime()+1.0/125.0); } } }
Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const { return getFrameTime(getFrameCount()); }
void WalkNavigationTool::frame(void) { /* Act depending on this tool's current state: */ if(isActive()) { /* Get the current head position and viewing direction: */ Point headPos=getMainViewer()->getHeadPosition(); Vector viewDir=getMainViewer()->getViewDirection(); /* Project head position and viewing direction onto floor plane: */ headPos=factory->floorPlane.project(headPos); viewDir=factory->floorPlane.project(viewDir); viewDir.normalize(); /* Calculate the movement direction and speed: */ Vector moveDir=centerPoint-headPos; Scalar moveDirLen=moveDir.mag(); Scalar speed=Scalar(0); if(moveDirLen>=factory->outerRadius) speed=factory->moveSpeed; else if(moveDirLen>factory->innerRadius) speed=factory->moveSpeed*(moveDirLen-factory->innerRadius)/(factory->outerRadius-factory->innerRadius); moveDir*=speed/moveDirLen; /* Calculate the rotation speed: */ Scalar viewAngleCos=viewDir*factory->centerViewDirection; Scalar viewAngle; if(viewAngleCos>Scalar(1)-Math::Constants<Scalar>::epsilon) viewAngle=Scalar(0); else if(viewAngleCos<Scalar(-1)+Math::Constants<Scalar>::epsilon) viewAngle=Math::Constants<Scalar>::pi; else viewAngle=Math::acos(viewAngleCos); Scalar rotateAngle=Scalar(0); if(viewAngle>=factory->outerAngle) rotateAngle=factory->rotateSpeed; else if(viewAngle>factory->innerAngle) rotateAngle=factory->rotateSpeed*(viewAngle-factory->innerAngle)/(factory->outerAngle-factory->innerAngle); Vector x=Geometry::cross(factory->centerViewDirection,factory->floorPlane.getNormal()); if(viewDir*x<Scalar(0)) rotateAngle=-rotateAngle; /* Accumulate the transformation: */ rotation+=rotateAngle*getFrameTime(); if(rotation<-Math::Constants<Scalar>::pi) rotation+=Scalar(2)*Math::Constants<Scalar>::pi; else if(rotation>=Math::Constants<Scalar>::pi) rotation-=Scalar(2)*Math::Constants<Scalar>::pi; NavTransform::Rotation rot=NavTransform::Rotation::rotateAxis(factory->floorPlane.getNormal(),rotation); translation+=rot.inverseTransform(moveDir*getFrameTime()); /* Set the navigation transformation: */ NavTransform nav=NavTransform::identity; nav*=Vrui::NavTransform::translateFromOriginTo(centerPoint); nav*=Vrui::NavTransform::rotate(rot); nav*=Vrui::NavTransform::translateToOriginFrom(centerPoint); nav*=Vrui::NavTransform::translate(translation); nav*=preScale; setNavigationTransformation(nav); } }