Esempio n. 1
0
// Doc in parent
void
SoVRMLCone::computeBBox(SoAction * COIN_UNUSED_ARG(action),
                        SbBox3f & box,
                        SbVec3f & center)
{
  float r = this->bottomRadius.getValue();
  float h = this->height.getValue();

  // Allow negative values.
  if (h < 0.0f) h = -h;
  if (r < 0.0f) r = -r;

  float half_height = h * 0.5f;

  // The SIDES are present, so just find the middle point and enclose
  // everything.
  if (this->side.getValue()) {
    center.setValue(0.0f, 0.0f, 0.0f);
    box.setBounds(SbVec3f(-r, -half_height, -r), SbVec3f(r, half_height, r));
  }
  // ..no SIDES, but we've still got the bottom (NB: OIV misses this case).
  else if (this->bottom.getValue()) {
    center.setValue(0.0f, -half_height, 0.0f);
    box.setBounds(SbVec3f(-r, -half_height, -r), SbVec3f(r, -half_height, r));
  }
  // ..no parts present. My confidence is shot -- I feel very small.
  else {
    center.setValue(0.0f, 0.0f, 0.0f);
    box.setBounds(SbVec3f(0.0f, 0.0f, 0.0f), SbVec3f(0.0f, 0.0f, 0.0f));
  }
}
// This is a helper function for debugging purposes: it sets up an
// SoCoordinate3 + SoIndexedLineSet pair of nodes exposing the
// geometry of the SbBox3f input argument.
static void
make_scene_graph(const SbBox3f & box, SoCoordinate3 *& coord3, SoIndexedLineSet *& ils)
{
  const SbVec3f & vmin = box.getMin();
  const SbVec3f & vmax = box.getMax();

  const SbVec3f corners[] = {
    // back face
    SbVec3f(vmin[0], vmin[1], vmin[2]),
    SbVec3f(vmax[0], vmin[1], vmin[2]),
    SbVec3f(vmax[0], vmax[1], vmin[2]),
    SbVec3f(vmin[0], vmax[1], vmin[2]),

    // front face
    SbVec3f(vmin[0], vmin[1], vmax[2]),
    SbVec3f(vmax[0], vmin[1], vmax[2]),
    SbVec3f(vmax[0], vmax[1], vmax[2]),
    SbVec3f(vmin[0], vmax[1], vmax[2])
  };

  const int32_t indices[] = {
    0, 1, 2, 3, 0, -1, // back face
    4, 5, 6, 7, 4, -1, // front face
    0, 4, -1, 1, 5, -1, 2, 6, -1, 3, 7, -1 // "crossover" lines
  };

  coord3 = new SoCoordinate3;
  coord3->point.setValues(0, sizeof(corners) / sizeof(corners[0]), corners);

  ils = new SoIndexedLineSet;
  ils->coordIndex.setValues(0, sizeof(indices) / sizeof(indices[0]), indices);
}
Esempio n. 3
0
// doc in super
void
SoOrthoSlice::computeBBox(SoAction * action, SbBox3f & box, SbVec3f & center)
{
  SoState * state = action->getState();
  if (!PRIVATE(this)->confirmValidInContext(state)) { return; }

  const CvrVoxelBlockElement * vbelem = CvrVoxelBlockElement::getInstance(state);
  if (vbelem == NULL) return;

  SbBox3f vdbox = vbelem->getUnitDimensionsBox();
  SbVec3f bmin, bmax;
  vdbox.getBounds(bmin, bmax);

  const SbVec3s & dimensions = vbelem->getVoxelCubeDimensions();

  const int axisidx = (int)axis.getValue();
  const int slice = this->sliceNumber.getValue();
  const float depth = (float)fabs(bmax[axisidx] - bmin[axisidx]);

  bmin[axisidx] = bmax[axisidx] =
    (bmin[axisidx] + (depth / dimensions[axisidx]) * slice);

  vdbox.setBounds(bmin, bmax);

  box.extendBy(vdbox);
  center = vdbox.getCenter();
}
Esempio n. 4
0
void
SoCylinder::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center)
//
////////////////////////////////////////////////////////////////////////
{
    int		curParts = (parts.isIgnored() ? ALL : parts.getValue());

    if (curParts == 0)		// No parts at all!
	box.setBounds(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);

    else {
	float	r, h;
	SbVec3f	min, max;

	getSize(r, h);

	if (HAS_PART(curParts, SIDES | TOP))
	    max.setValue( r,  h,  r);
	else
	    max.setValue( r, -h,  r);

	if (HAS_PART(curParts, SIDES | BOTTOM))
	    min.setValue(-r, -h, -r);
	else
	    min.setValue(-r,  h, -r);

	box.setBounds(min, max);
    }

    center.setValue(0.0, 0.0, 0.0);
}
Esempio n. 5
0
/**
 * Sets the bounding box of the mesh to \a box and its center to \a center.
 */
void SoPolygon::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
{
    SoState*  state = action->getState();
    const SoCoordinateElement * coords = SoCoordinateElement::getInstance(state);
    if (!coords) return;
    const SbVec3f * points = coords->getArrayPtr3();
    if (!points) return;
    float maxX=-FLT_MAX, minX=FLT_MAX,
          maxY=-FLT_MAX, minY=FLT_MAX,
          maxZ=-FLT_MAX, minZ=FLT_MAX;
    int32_t len = coords->getNum();
    int32_t beg = startIndex.getValue();
    int32_t cnt = numVertices.getValue();
    int32_t end = beg + cnt;
    if (end <= len) {
        for (int32_t i=beg; i<end; i++) {
            maxX = std::max<float>(maxX,points[i][0]);
            minX = std::min<float>(minX,points[i][0]);
            maxY = std::max<float>(maxY,points[i][1]);
            minY = std::min<float>(minY,points[i][1]);
            maxZ = std::max<float>(maxZ,points[i][2]);
            minZ = std::min<float>(minZ,points[i][2]);
        }

        box.setBounds(minX,minY,minZ,maxX,maxY,maxZ);
        center.setValue(0.5f*(minX+maxX),0.5f*(minY+maxY),0.5f*(minZ+maxZ));
    }
    else {
        box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
        center.setValue(0.0f,0.0f,0.0f);
    }
}
SbBox3f ViewProviderDatum::getRelevantBoundBox () const {
    std::vector<App::DocumentObject *> objs;

    // Probe body first
    PartDesign::Body* body = PartDesign::Body::findBodyOf ( this->getObject() );
    if (body) {
        objs = body->getFullModel ();
    } else {
        // Probe if we belongs to some group
        App::DocumentObjectGroup* group =  App::DocumentObjectGroup::getGroupOfObject ( this->getObject () );

        if(group) {
            objs = group->getObjects ();
        } else {
            // Fallback to whole document
            objs = this->getObject ()->getDocument ()->getObjects ();
        }
    }

    Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(this->getActiveView())->getViewer();
    SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion());
    SbBox3f bbox = getRelevantBoundBox (bboxAction, objs);

    if ( bbox.getVolume () < Precision::Confusion() ) {
        bbox.extendBy ( defaultBoundBox () );
    }

    return bbox;
}
// Expand SbXfBox3f in all directions with an epsilon value.
static SbXfBox3f
expand_SbXfBox3f(const SbXfBox3f & box, float epsilon)
{
  assert(epsilon > 0.0f);

  // FIXME: quality check the calculation for the epsilon-extended
  // bbox. It needs to be correct _and_ not adding on too much
  // fat. 20030331 mortene.

  // This invokes the copy constructor (and not the SbXfBox3f(SbBox3f)
  // constructor), so the transformation matrix is also copied.
  SbXfBox3f extbox(box);

  SbVec3f epsilonvec(epsilon, epsilon, epsilon);
  // Move epsilon to object space.
  box.getTransform().multDirMatrix(epsilonvec, epsilonvec);
  const float localepsilon = epsilonvec.length(); // yes, it's a bit large...
  epsilonvec = SbVec3f(localepsilon, localepsilon, localepsilon);

  // Get superclass-pointer, so we can modify the box corners
  // directly.
  SbBox3f * extboxp = static_cast<SbBox3f *>(&extbox);

  extboxp->getMin() -= epsilonvec;
  extboxp->getMax() += epsilonvec;

  return extbox;
}
Esempio n. 8
0
void
SbSphere::circumscribe(const SbBox3f &box)
//
//////////////////////////////////////////////////////////////////////////////
{
    center = 0.5 * (box.getMin() + box.getMax());
    radius = (box.getMax() - center).length();
}
Esempio n. 9
0
void
SoNurbsSurface::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
//
////////////////////////////////////////////////////////////////////////
{
    const SoCoordinateElement   *ce =
            SoCoordinateElement::getInstance(action->getState());
    int32_t			nCoords, numSurfCoords;
    int				j, curCoord;
    SbVec3f			tmpCoord;

    //
    // Loop through coordinates, keeping max bounding box and sum of coords
    // If the coordinates are rational, divide the first three values by
    // the fourth value before extending the bounding box.
    //
    numSurfCoords = numUControlPoints.getValue() *
                    numVControlPoints.getValue();
    nCoords = ce->getNum();

    // Check for a degenerate surface
    if ((numSurfCoords == 0) || (nCoords == 0))
        return;

    curCoord = 0;
    center.setValue(0.0, 0.0, 0.0);
    if (ce->is3D()) {
        for (j = 0; j < numSurfCoords; j++) {
            //
            // Wrap around if necessary
            //
            if (curCoord >= nCoords)
	        curCoord = 0;
            const SbVec3f &coord = ce->get3(curCoord);
            box.extendBy(coord);
            center += coord;
            curCoord++;
        }
    }
    else {
        for (j = 0; j < numSurfCoords; j++) {
            //
            // Wrap around if necessary
            //
            if (curCoord >= nCoords)
	        curCoord = 0;
            const SbVec4f &coord = ce->get4(curCoord);
            coord.getReal (tmpCoord);
            box.extendBy (tmpCoord);
            center += tmpCoord;
            curCoord++;
        }
    }

    center /= (float) numSurfCoords;
}
Esempio n. 10
0
void IvDragger::_GetBounds(SoSeparator *subtree, AABB& ab)
{
    SoGetBoundingBoxAction bbox(_viewer.lock()->GetViewer()->getViewportRegion());
    bbox.apply(subtree);
    SbBox3f box = bbox.getBoundingBox();
    RaveVector<float> vmin, vmax;
    box.getBounds(vmin.x,vmin.y,vmin.z,vmax.x,vmax.y,vmax.z);
    ab.pos = 0.5*(vmin+vmax);
    ab.extents = 0.5*(vmax-vmin);
}
Esempio n. 11
0
void ShapeBezierSurface::computeBBox(SoAction*, SbBox3f& box, SbVec3f& /*center*/ )
{
	box.makeEmpty();
	for (int i = 0; i < m_surfacesVector.size(); i++)
	{
		BBox pBox =  m_surfacesVector[i]->GetComputeBBox();
		SbVec3f pMin( pBox.pMin[0], pBox.pMin[1], pBox.pMin[2] );
		box.extendBy( pMin );
		SbVec3f pMax( pBox.pMax[0], pBox.pMax[1], pBox.pMax[2] );
		box.extendBy( pMax );
	}
}
Esempio n. 12
0
void SoVtkAssembly::getBoundingBox(SoGetBoundingBoxAction *action)
{
	SbBox3f	bbox;
	SbVec3f	center;

	if (mAssembly)
	{
		const double *bounds = mAssembly->GetBounds();
		SbBox3f bbox(bounds[0], bounds[2], bounds[4], bounds[1], bounds[3], bounds[5]);
		action->extendBy(bbox);
		action->setCenter(bbox.getCenter(), FALSE);
	}
}
Esempio n. 13
0
void 
SoXipMarkerSet::computeBBox( SoAction* action, SbBox3f& box, SbVec3f& center )
{
	const SoCoordinateElement* ce = (const SoCoordinateElement *) SoCoordinateElement::getInstance( action->getState() );

	if( ce )
	{
		for( int i = 0; i < ce->getNum(); ++ i )
			box.extendBy( ce->get3(i) );
	}

	center = box.getCenter();
}
Esempio n. 14
0
// set scale
void
InvAnnoManager::setSize(const SbBox3f &bb)
{
    float dx = fabs(bb.getMin()[0] - bb.getMax()[0]);
    float dy = fabs(bb.getMin()[1] - bb.getMax()[1]);
    float dz = fabs(bb.getMin()[2] - bb.getMax()[2]);

    float hsc = max(dx, dy);
    hsc = max(hsc, dz);

    hsc *= 0.2;

    scale_ = hsc;
}
Esempio n. 15
0
/**
 * Sets the bounding box of the probe to \a box and its center to \a center.
 */
void SoRegPoint::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
{
    root->doAction(action);
    if (action->getTypeId().isDerivedFrom(SoGetBoundingBoxAction::getClassTypeId()))
        static_cast<SoGetBoundingBoxAction*>(action)->resetCenter();

    SbVec3f p1 = base.getValue();
    SbVec3f p2 = p1 + normal.getValue() * length.getValue();

    box.extendBy(p1);
    box.extendBy(p2);

    center = box.getCenter();
}
    void rotateCamera(const SbRotation &rot)
    {
        SoCamera * camera = viewer->getCamera();

        // get center of rotation
        const float radius = camera->focalDistance.getValue();

        SbVec3f forward;
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);

        const SbVec3f center = camera->position.getValue() + radius * forward;

        // apply new rotation to the camera
        camera->orientation = rot * camera->orientation.getValue();

        // reposition camera to look at pt of interest
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);
        camera->position = center - radius * forward;

        headlightRot->rotation = camera->orientation.getValue();

        // Adjust clipping planes
        SoGetBoundingBoxAction clipbox_action(getViewportRegion());
        clipbox_action.apply(viewer->getSceneRoot());

        SbBox3f bbox = clipbox_action.getBoundingBox();

        if (bbox.isEmpty())
            return;

        SbSphere bSphere;
        bSphere.circumscribe(bbox);

        float denumerator = forward.length();
        float numerator = (bSphere.getCenter() - camera->position.getValue()).dot(forward);
        float distToCenter = (forward * (numerator / denumerator)).length();

        float farplane = distToCenter + bSphere.getRadius();

        // if scene is behind the camera, don't change the planes
        if (farplane < 0) return;

        float nearplane = distToCenter - bSphere.getRadius();

        if (nearplane < (0.001 * farplane)) nearplane = 0.001 * farplane;

        camera->nearDistance = nearplane;
        camera->farDistance = farplane;
    }
Esempio n. 17
0
// compute object space ray and test for intersection
static SbBool
ray_intersect(SoRayPickAction * action, const SbBox3f & box)
{
  if (box.isEmpty()) return FALSE;
  action->setObjectSpace();
  return action->intersect(box, TRUE);
}
Esempio n. 18
0
// set scale
void
InvPlaneMover::setSize(const SbBox3f &bb)
{
    float dx = fabs(bb.getMin()[0] - bb.getMax()[0]);
    float dy = fabs(bb.getMin()[1] - bb.getMax()[1]);
    float dz = fabs(bb.getMin()[2] - bb.getMax()[2]);

    float hsc = qMax(dx, dy);
    hsc = qMax(hsc, dz);

    hsc *= 0.3f;

    SbVec3f s(hsc, hsc, hsc);

    scale_->scaleFactor.setValue(s);
}
Esempio n. 19
0
void
SoXipMenuBase::GLRender( SoGLRenderAction* action )
{
	if( on.getValue() == FALSE )
		return ;

	// Compute the 3D position of the menu, given the mouse 2D position
	saveViewInformation( action );

	mMenuOffset->translation.setValue( mPlaneProj->project( position.getValue() ) );

	SoGetBoundingBoxAction bba( action->getViewportRegion() );
	bba.apply( mMenuSeparator );

	SbBox3f bbox = bba.getBoundingBox();
	bbox.transform( mModelMatrix );

	float viewportAR = mViewport.getViewportAspectRatio();
	SbVec3f screenOffset(0, 0, 0);
	if( viewportAR < 1. )
	{
		screenOffset[0] = bbox.getMax()[0] - 1.;
		screenOffset[1] = bbox.getMax()[1] - 1. / viewportAR;
	}
	else
	{
		screenOffset[0] = bbox.getMax()[0] - viewportAR;
		screenOffset[1] = bbox.getMax()[1] - 1;
	}

	if( screenOffset[0] < 0 )
		screenOffset[0] = 0;
	if( screenOffset[1] < 0 )
		screenOffset[1] = 0;

	SbVec3f worldOffset;
	mModelMatrix.inverse().multVecMatrix( screenOffset, worldOffset );

	mMenuOffset->translation.setValue( mMenuOffset->translation.getValue() - worldOffset );

	glPushAttrib( GL_ENABLE_BIT );
	glDisable( GL_DEPTH_TEST );

	SoXipKit::GLRender( action );

	glPopAttrib();
}
Esempio n. 20
0
void SoWidgetShape::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
{
    // ignore if node is empty
    if (this->image.isNull()) return;

    SbVec3f v0, v1, v2, v3;
    // this will cause a cache dependency on the view volume,
    // model matrix and viewport.
    this->getQuad(action->getState(), v0, v1, v2, v3);

    box.makeEmpty();
    box.extendBy(v0);
    box.extendBy(v1);
    box.extendBy(v2);
    box.extendBy(v3);
    center = box.getCenter();
}
Esempio n. 21
0
// Render 3D box.
//
// FIXME: should make bbox debug rendering part of SoSeparator /
// SoGroup. 20030305 mortene.
void
SoOrthoSliceP::renderBox(SoGLRenderAction * action, SbBox3f box)
{
  SbVec3f bmin, bmax;
  box.getBounds(bmin, bmax);

  glPushAttrib(GL_ALL_ATTRIB_BITS);

  glDisable(GL_TEXTURE_2D);
  glDisable(GL_LIGHTING);
  glColor4ub(0xff, 0xff, 0xff, 0xff);
  glLineStipple(1, 0xffff);
  glLineWidth(2);

  glBegin(GL_LINES);

  glVertex3f(bmin[0], bmin[1], bmin[2]);
  glVertex3f(bmin[0], bmin[1], bmax[2]);

  glVertex3f(bmax[0], bmin[1], bmin[2]);
  glVertex3f(bmax[0], bmin[1], bmax[2]);

  glVertex3f(bmax[0], bmax[1], bmin[2]);
  glVertex3f(bmax[0], bmax[1], bmax[2]);

  glVertex3f(bmin[0], bmax[1], bmin[2]);
  glVertex3f(bmin[0], bmax[1], bmax[2]);


  glVertex3f(bmin[0], bmin[1], bmin[2]);
  glVertex3f(bmax[0], bmin[1], bmin[2]);

  glVertex3f(bmin[0], bmin[1], bmax[2]);
  glVertex3f(bmax[0], bmin[1], bmax[2]);

  glVertex3f(bmin[0], bmax[1], bmax[2]);
  glVertex3f(bmax[0], bmax[1], bmax[2]);

  glVertex3f(bmin[0], bmax[1], bmin[2]);
  glVertex3f(bmax[0], bmax[1], bmin[2]);


  glVertex3f(bmin[0], bmin[1], bmin[2]);
  glVertex3f(bmin[0], bmax[1], bmin[2]);

  glVertex3f(bmin[0], bmin[1], bmax[2]);
  glVertex3f(bmin[0], bmax[1], bmax[2]);

  glVertex3f(bmax[0], bmin[1], bmax[2]);
  glVertex3f(bmax[0], bmax[1], bmax[2]);

  glVertex3f(bmax[0], bmin[1], bmin[2]);
  glVertex3f(bmax[0], bmax[1], bmin[2]);

  glEnd();

  glPopAttrib();
}
Esempio n. 22
0
SbBool
SoXipPolygon::isConsistent() const
{
	// check if the contour size is greater than the minimum size.
	const SbVec3f* pointPtr = point.getValues(0);

	SbBox3f bbox;
	for( int i = 0; i < point.getNum(); ++ i )
		bbox.extendBy( pointPtr[i] );

	SbVec3f bbSize;
	bbox.getSize(bbSize[0], bbSize[1], bbSize[2]);

	float screenScale = mViewVolume.getHeight() / mViewport.getViewportSizePixels()[1];
	float bbLengthPix = bbSize.length() / screenScale;

	return ( bbLengthPix >= (2 * CLOSING_MIN_PIXEL_DISTANCE) );
}
Esempio n. 23
0
// Doc in superclass.
void
SoOrthographicCamera::viewBoundingBox(const SbBox3f & box,
                                      float aspect, float slack)
{
#if COIN_DEBUG
  if (box.isEmpty()) {
    SoDebugError::postWarning("SoOrthographicCamera::viewBoundingBox",
                              "bounding box empty");
    return;
  }
#endif // COIN_DEBUG

  // Get the radius of the bounding sphere.
  SbSphere bs;
  bs.circumscribe(box);
  float radius = bs.getRadius();

  // We want to move the camera in such a way that it is pointing
  // straight at the center of the scene bounding box -- but without
  // modifiying the rotation value (so we can't use SoCamera::pointAt()),
  // and positioned at the edge of the bounding sphere.
  SbVec3f cameradirection;
  this->orientation.getValue().multVec(SbVec3f(0, 0, -1), cameradirection);
  this->position.setValue(box.getCenter() + cameradirection * -radius);

  // Set up the clipping planes tangent to the bounding sphere of the scene.
  this->nearDistance = radius * ( -slack + 1);
  this->farDistance = radius * ( slack + 1);

  // The focal distance is simply the distance from the camera to the
  // scene midpoint. This field is not used in rendering, its just
  // provided to make it easier for the user to do calculations based
  // on the distance between the camera and the scene.
  this->focalDistance = radius;

  // Make sure that everything will still be inside the viewing volume
  // even if the aspect ratio "favorizes" width over height, and take the
  // slack factor into account.
  if (aspect < 1.0f)
    this->height = 2 * radius / aspect;
  else
    this->height = 2 * radius;
}
void ShapeParabolicRectangle::computeBBox( SoAction*, SbBox3f& box, SbVec3f& /*center*/ )
{
	BBox bBox = GetBBox();
	// These points define the min and max extents of the box.
	SbVec3f min, max;

	min.setValue( bBox.pMin.x, bBox.pMin.y, bBox.pMin.z );
	max.setValue( bBox.pMax.x, bBox.pMax.y, bBox.pMax.z );;

	// Set the box to bound the two extreme points.
	box.setBounds(min, max);
}
Esempio n. 25
0
// doc from parent
void
SmTextureText2::computeBBox(SoAction * action, SbBox3f & box, SbVec3f & center)
{
  SoState * state = action->getState();

  // never cull this node. We do quick culling in the render method
  SoCacheElement::invalidate(state);

  // this boundingbox will _not_ be 100% correct. We just supply an
  // estimate to avoid using lots of processing for calculating the
  // boundingbox.  FIXME: make it configurable if the bbox should be
  // accurate or not
  const SbVec3f * positions;
  const int numpositions = this->getPositions(state, positions);
  const SbVec3f & offset = this->offset.getValue();

  for (int i = 0; i < numpositions; i++) {
    box.extendBy(positions[i] + offset);
  }
  center = box.getCenter();
}
Esempio n. 26
0
void Command::adjustCameraPosition()
{
    Gui::Document* doc = Gui::Application::Instance->activeDocument();
    if (doc) {
        Gui::View3DInventor* view = static_cast<Gui::View3DInventor*>(doc->getActiveView());
        Gui::View3DInventorViewer* viewer = view->getViewer();
        SoCamera* camera = viewer->getSoRenderManager()->getCamera();
        if (!camera || !camera->isOfType(SoOrthographicCamera::getClassTypeId()))
            return;

        // get scene bounding box
        SoGetBoundingBoxAction action(viewer->getSoRenderManager()->getViewportRegion());
        action.apply(viewer->getSceneGraph());
        SbBox3f box = action.getBoundingBox();
        if (box.isEmpty()) return;

        // get cirumscribing sphere and check if camera is inside
        SbVec3f cam_pos = camera->position.getValue();
        SbVec3f box_cnt = box.getCenter();
        SbSphere bs;
        bs.circumscribe(box);
        float radius = bs.getRadius();
        float distance_to_midpoint = (box_cnt-cam_pos).length();
        if (radius >= distance_to_midpoint) {
            // Move the camera to the edge of the bounding sphere, while still
            // pointing at the scene.
            SbVec3f direction = cam_pos - box_cnt;
            (void) direction.normalize(); // we know this is not a null vector
            camera->position.setValue(box_cnt + direction * radius);

            // New distance to mid point
            distance_to_midpoint =
                (camera->position.getValue() - box.getCenter()).length();
            camera->nearDistance = distance_to_midpoint - radius;
            camera->farDistance = distance_to_midpoint + radius;
            camera->focalDistance = distance_to_midpoint;
        }
    }
}
  const SbOctTree * getOctTree(void) {
    if (this->octtree == NULL) {
      const SbOctTreeFuncs funcs = {
        NULL /* ptinsidefunc */,
        PrimitiveData::insideboxfunc,
        NULL /* insidespherefunc */,
        NULL /* insideplanesfunc */
      };

      SbBox3f b = this->getBoundingBox();
      // Add a 1% slack to the bounding box, to avoid problems in
      // SbOctTree due to floating point inaccuracies (see assert() in
      // SbOctTree::addItem()).
      //
      // This may be just a temporary hack -- see the FIXME at the
      // same place as mentioned above.
      SbMatrix m;
      m.setTransform(SbVec3f(0, 0, 0), // translation
                     SbRotation::identity(), // rotation
                     SbVec3f(1.01f, 1.01f, 1.01f), // scalefactor
                     SbRotation::identity(), // scaleorientation
                     SbVec3f(b.getCenter())); // center
      b.transform(m);

      this->octtree = new SbOctTree(b, funcs);

      if (ida_debug()) {
        SoDebugError::postInfo("PrimitiveData::getOctTree",
                               "made new octtree for PrimitiveData %p", this);
      }

      for (unsigned int k = 0; k < this->numTriangles(); k++) {
        SbTri3f * t = this->getTriangle(k);
        this->octtree->addItem(t);
      }
    }
    return this->octtree;
  }
SoCallbackAction::Response
SoIntersectionDetectionAction::PImpl::shape(SoCallbackAction * action, SoShape * shape)
{
  SbBox3f bbox;
  SbVec3f center;

  const SoBoundingBoxCache * bboxcache = shape->getBoundingBoxCache();
  if (bboxcache && bboxcache->isValid(action->getState())) {
    bbox = bboxcache->getProjectedBox();
    if (bboxcache->isCenterSet()) center = bboxcache->getCenter();
    else center = bbox.getCenter();
  }
  else {
    shape->computeBBox(action, bbox, center);
  }
  ShapeData * data = new ShapeData;
  data->path = new SoPath(*(action->getCurPath()));
  data->path->ref();
  data->xfbbox = bbox;
  data->xfbbox.setTransform(action->getModelMatrix());
  this->shapedata.append(data);
  return SoCallbackAction::CONTINUE;
}
Esempio n. 29
0
// Doc in parent
void
SoVRMLCylinder::computeBBox(SoAction * COIN_UNUSED_ARG(action),
                            SbBox3f & box,
                            SbVec3f & center)
{
  float r = this->radius.getValue();
  float h = this->height.getValue();

  // Allow negative values.
  if (r < 0.0f) r = -r;
  if (h < 0.0f) h = -h;

  // Either the SIDES are present, or we've at least got both the TOP
  // and BOTTOM caps -- so just find the middle point and enclose
  // everything.
  if (this->side.getValue() ||
      (this->bottom.getValue() &&
       this->top.getValue())) {
    center.setValue(0.0f, 0.0f, 0.0f);
    box.setBounds(SbVec3f(-r, -h/2.0f, -r), SbVec3f(r, h/2.0f, r));
  }
  // ..not a "full" cylinder, but we've got the BOTTOM cap.
  else if (this->bottom.getValue()) {
    center.setValue(0.0f, -h/2.0f, 0.0f);
    box.setBounds(SbVec3f(-r, -h/2.0f, -r), SbVec3f(r, -h/2.0f, r));
  }
  // ..not a "full" cylinder, but we've got the TOP cap.
  else if (this->top.getValue()) {
    center.setValue(0.0f, h/2.0f, 0.0f);
    box.setBounds(SbVec3f(-r, h/2.0f, -r), SbVec3f(r, h/2.0f, r));
  }
  // ..no parts present. My confidence is shot -- I feel very small.
  else {
    center.setValue(0.0f, 0.0f, 0.0f);
    box.setBounds(SbVec3f(0.0f, 0.0f, 0.0f), SbVec3f(0.0f, 0.0f, 0.0f));
  }
}
    /// Override original method since it seems to adjust the clipping planes in a weird manner.
    /// Maybe using a screen-space projection or whatever.
    virtual void adjustCameraClippingPlanes()
    {
        SoCamera * camera = getCamera();
        if (!camera)
            return;

        SoGetBoundingBoxAction clipbox_action(getViewportRegion());
        clipbox_action.apply(getSceneRoot());

        SbBox3f bbox = clipbox_action.getBoundingBox();

        if (bbox.isEmpty())
            return;

        SbSphere bSphere;
        bSphere.circumscribe(bbox);

        SbVec3f forward;
        camera->orientation.getValue().multVec(SbVec3f(0,0,-1), forward);

        float denumerator = forward.length();
        float numerator = (bSphere.getCenter() - camera->position.getValue()).dot(forward);
        float distToCenter = (forward * (numerator / denumerator)).length();

        float farplane = distToCenter + bSphere.getRadius();

        // if scene is behind the camera, don't change the planes
        if (farplane < 0) return;

        float nearplane = distToCenter - bSphere.getRadius();

        if (nearplane < (0.001 * farplane)) nearplane = 0.001 * farplane;

        camera->nearDistance = nearplane;
        camera->farDistance = farplane;
    }