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; }
/// 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; }