void CameraController::focusOnBounds(const Imath::Box3f& bounds) { using namespace Imath; V3f fwd = m_parameters->forwardUnitVector(); V3f center = bounds.center(); float distance = bounds.size().length() / (2.0f * tan(m_parameters->fovY() / 2)); m_parameters->setEyeTarget(center - fwd * distance, center); }
Imath::Box3f SceneView::framingBound() const { Imath::Box3f b = m_renderableGadget->selectionBound(); if( !b.isEmpty() ) { return b; } return View3D::framingBound(); }
Imath::Box3f MotionPrimitive::bound() const { Imath::Box3f result; for( SnapshotMap::const_iterator it=m_snapshots.begin(); it!=m_snapshots.end(); it++ ) { result.extendBy( it->second->bound() ); } return result; }
Imath::Box3f Frame::bound() const { Imath::Box3f b = IndividualContainer::bound(); if( b.isEmpty() ) { return b; } b.max += V3f( m_border, m_border, 0 ); b.min -= V3f( m_border, m_border, 0 ); return b; }
bool rayPassesNearOrThrough(const V3d& rayOrigin, const V3d& rayDir) const { const double diagRadius = 1.2*bbox.size().length()/2; // Sphere diameter is length of box diagonal const V3d o2c = bbox.center() - rayOrigin; // vector from rayOrigin to box center const double l = o2c.length(); if(l < diagRadius) return true; // rayOrigin lies within bounding sphere // rayOrigin lies outside of bounding sphere const double cosA = o2c.dot(rayDir)/l; // cosine of angle between rayDir and vector from origin to center if(cosA < DBL_MIN) return false; // rayDir points to side or behind with respect to direction from origin to center of box const double sinA = sqrt(1 - cosA*cosA); // sine of angle between rayDir and vector from origin to center return sinA/cosA < diagRadius/l; }
bool View::keyPress( GadgetPtr gadget, const KeyEvent &keyEvent ) { if( keyEvent.key == "F" ) { Imath::Box3f b = framingBound(); if( !b.isEmpty() && viewportGadget()->getCameraEditable() ) { viewportGadget()->frame( b ); return true; } } return false; }
Imath::Box3f SceneView::framingBound() const { Imath::Box3f b = m_sceneGadget->selectionBound(); if( !b.isEmpty() ) { return b; } b = View3D::framingBound(); if( m_grid->gadget()->getVisible() ) { b.extendBy( m_grid->gadget()->bound() ); } return b; }
MBoundingBox convert( const Imath::Box3f &from ) { if( from.isEmpty() ) { return MBoundingBox(); } return MBoundingBox( convert<MPoint>( from.min ), convert<MPoint>( from.max ) ); }
Imath::Box3f SkeletonPrimitive::bound() const { Imath::Box3f bbox; for (unsigned int i=0; i<m_globalMatrices->readable().size(); i++) { bbox.extendBy( m_globalMatrices->readable()[i].translation() ); } //std::cerr << bbox.min << ", " << bbox.max << std::endl; // add a little on for joint radius bbox.extendBy( bbox.max + Imath::V3f(1,1,1) ); bbox.extendBy( bbox.min - Imath::V3f(1,1,1) ); //std::cerr << bbox.min << ", " << bbox.max << std::endl; return bbox; }
void AuxiliaryNodeGadget::doRenderLayer( Layer layer, const Style *style ) const { if( layer != GraphLayer::Nodes ) { return NodeGadget::doRenderLayer( layer, style ); } Style::State state = getHighlighted() ? Style::HighlightedState : Style::NormalState; style->renderNodeFrame( Box2f( V2f( 0 ), V2f( 0 ) ), m_radius, state, m_userColor.get_ptr() ); Imath::Box3f bound = style->textBound( Style::LabelText, m_label ); Imath::V3f offset = bound.size() / 2.0; glPushMatrix(); glTranslatef( -offset.x, -offset.y, 0.0f ); style->renderText( Style::LabelText, m_label ); glPopMatrix(); }
Imath::M44f computeMeshTransform(const Imath::Box3f& bounds, const Imath::V3i& voxelResolution) { using namespace Imath; M44f meshTransform; // set mesh transform so that the mesh fits within the unit cube. This will // be changed later when we let the user manipulate the mesh transform and // the mesh/volume intersection. V3f voxelMargin = V3f(1.0f) / voxelResolution; // 1 voxel int majorAxis = bounds.majorAxis(); float s = (1.0f - 2.0 * voxelMargin[majorAxis] ) / bounds.size()[majorAxis]; V3f t = -bounds.min + voxelMargin / s; meshTransform.x[0][0] = s ; meshTransform.x[0][1] = 0 ; meshTransform.x[0][2] = 0 ; meshTransform.x[0][3] = t.x * s ; meshTransform.x[1][0] = 0 ; meshTransform.x[1][1] = s ; meshTransform.x[1][2] = 0 ; meshTransform.x[1][3] = t.y * s ; meshTransform.x[2][0] = 0 ; meshTransform.x[2][1] = 0 ; meshTransform.x[2][2] = s ; meshTransform.x[2][3] = t.z * s ; meshTransform.x[3][0] = 0 ; meshTransform.x[3][1] = 0 ; meshTransform.x[3][2] = 0 ; meshTransform.x[3][3] = 1.0f ; return meshTransform; }
void CameraController::frame( const Imath::Box3f &box, const Imath::V3f &viewDirection, const Imath::V3f &upVector ) { // make a matrix to centre the camera on the box, with the appropriate view direction M44f cameraMatrix = rotationMatrixWithUpDir( V3f( 0, 0, -1 ), viewDirection, upVector ); M44f translationMatrix; translationMatrix.translate( box.center() ); cameraMatrix *= translationMatrix; // translate the camera back until the box is completely visible M44f inverseCameraMatrix = cameraMatrix.inverse(); Box3f cBox = transform( box, inverseCameraMatrix ); Box2f screenWindow = m_data->screenWindow->readable(); if( m_data->projection->readable()=="perspective" ) { // perspective. leave the field of view and screen window as is and translate // back till the box is wholly visible. this currently assumes the screen window // is centred about the camera axis. float z0 = cBox.size().x / screenWindow.size().x; float z1 = cBox.size().y / screenWindow.size().y; m_data->centreOfInterest = std::max( z0, z1 ) / tan( M_PI * m_data->fov->readable() / 360.0 ) + cBox.max.z + m_data->clippingPlanes->readable()[0]; cameraMatrix.translate( V3f( 0.0f, 0.0f, m_data->centreOfInterest ) ); } else { // orthographic. translate to front of box and set screen window // to frame the box, maintaining the aspect ratio of the screen window. m_data->centreOfInterest = cBox.max.z + m_data->clippingPlanes->readable()[0] + 0.1; // 0.1 is a fudge factor cameraMatrix.translate( V3f( 0.0f, 0.0f, m_data->centreOfInterest ) ); float xScale = cBox.size().x / screenWindow.size().x; float yScale = cBox.size().y / screenWindow.size().y; float scale = std::max( xScale, yScale ); V2f newSize = screenWindow.size() * scale; screenWindow.min.x = cBox.center().x - newSize.x / 2.0f; screenWindow.min.y = cBox.center().y - newSize.y / 2.0f; screenWindow.max.x = cBox.center().x + newSize.x / 2.0f; screenWindow.max.y = cBox.center().y + newSize.y / 2.0f; } m_data->transform->matrix = cameraMatrix; m_data->screenWindow->writable() = screenWindow; }
void DotNodeGadget::updateLabel() { const Dot *dot = dotNode(); const Dot::LabelType labelType = (Dot::LabelType)dot->labelTypePlug()->getValue(); if( labelType == Dot::None ) { m_label.clear(); } else if( labelType == Dot::NodeName ) { m_label = dot->getName(); } else if( labelType == Dot::UpstreamNodeName ) { const Node *n = upstreamNode(); m_label = n ? n->getName() : ""; } else { m_label = dot->labelPlug()->getValue(); } Edge labelEdge = RightEdge; if( const Plug *p = dot->inPlug<Plug>() ) { if( noduleTangent( nodule( p ) ).x != 0 ) { labelEdge = TopEdge; } } const Imath::Box3f thisBound = bound(); if( labelEdge == TopEdge ) { const Imath::Box3f labelBound = style()->textBound( Style::LabelText, m_label ); m_labelPosition = V2f( -labelBound.size().x / 2.0, thisBound.max.y + 1.0 ); } else { const Imath::Box3f characterBound = style()->characterBound( Style::LabelText ); m_labelPosition = V2f( thisBound.max.x, thisBound.center().y - characterBound.size().y / 2.0 ); } requestRender(); }