Matrixd Scene::calculateInitialCameraMatrix() { ComputeBoundsVisitor cbv; accept(cbv); Vec3d vec3dSceneCorner = cbv.getBoundingBox().corner(5); //Camera positioned Vec3d vec3dSceneCenter = cbv.getBoundingBox().center(); Vec3d vec3dEye = Vec3d(vec3dSceneCenter.x(),vec3dSceneCorner.y(),vec3dSceneCorner.z()); Vec3d vec3dCenter = Vec3d(vec3dEye.x(),0.0,0.0); Vec3d vec3dDiff = vec3dCenter - vec3dEye; Vec3d vec3dPerp = Vec3d(0,0,1)^vec3dDiff; Vec3d vec3dUp = vec3dDiff^vec3dPerp; vec3dUp.normalize(); //Also set the camera Matrixd mtrxSceneCameraMatrix = Matrix::inverse(Matrix::lookAt(vec3dEye, vec3dCenter, vec3dUp)); return mtrxSceneCameraMatrix; }
BoundingSphere OcclusionQueryNode::computeBound() const { { // Need to make this routine thread-safe. Typically called by the update // Visitor, or just after the update traversal, but could be called by // an application thread or by a non-osgViewer application. OpenThreads::ScopedLock<OpenThreads::Mutex> lock( _computeBoundMutex ) ; // This is the logical place to put this code, but the method is const. Cast // away constness to compute the bounding box and modify the query geometry. osg::OcclusionQueryNode* nonConstThis = const_cast<osg::OcclusionQueryNode*>( this ); ComputeBoundsVisitor cbv; nonConstThis->accept( cbv ); BoundingBox bb = cbv.getBoundingBox(); osg::ref_ptr<Vec3Array> v = new Vec3Array; v->resize( 8 ); (*v)[0] = Vec3( bb._min.x(), bb._min.y(), bb._min.z() ); (*v)[1] = Vec3( bb._max.x(), bb._min.y(), bb._min.z() ); (*v)[2] = Vec3( bb._max.x(), bb._min.y(), bb._max.z() ); (*v)[3] = Vec3( bb._min.x(), bb._min.y(), bb._max.z() ); (*v)[4] = Vec3( bb._max.x(), bb._max.y(), bb._min.z() ); (*v)[5] = Vec3( bb._min.x(), bb._max.y(), bb._min.z() ); (*v)[6] = Vec3( bb._min.x(), bb._max.y(), bb._max.z() ); (*v)[7] = Vec3( bb._max.x(), bb._max.y(), bb._max.z() ); Geometry* geom = static_cast< Geometry* >( nonConstThis->_queryGeode->getDrawable( 0 ) ); geom->setVertexArray( v.get() ); geom = static_cast< osg::Geometry* >( nonConstThis->_debugGeode->getDrawable( 0 ) ); geom->setVertexArray( v.get() ); } return Group::computeBound(); }
static osgDB::ReaderWriter::WriteResult writeNodeImplementation( const Node& node, ostream& fout, const osgDB::ReaderWriter::Options* options ) { // get camera on the top of scene graph const Camera *camera = node.asCamera(); Vec3d eye, center, up, right; double fovy, aspectRatio, tmp; if( camera ) { // view matrix camera->getViewMatrixAsLookAt( eye, center, up ); up = Vec3d( 0.,0.,1. ); right = Vec3d( 1.,0.,0. ); //up.normalize(); //right = (center-eye) ^ up; //right.normalize(); // projection matrix camera->getProjectionMatrixAsPerspective( fovy, aspectRatio, tmp, tmp ); right *= aspectRatio; } else { // get POV-Ray camera setup from scene bounding sphere // constructed from bounding box // (bounding box computes model center more precisely than bounding sphere) ComputeBoundsVisitor cbVisitor; const_cast< Node& >( node ).accept( cbVisitor ); BoundingBox &bb = cbVisitor.getBoundingBox(); BoundingSphere bs( bb ); // set eye = bs.center() + Vec3( 0., -3.0 * bs.radius(), 0. ); center = bs.center(); up = Vec3d( 0.,1.,0. ); right = Vec3d( 4./3.,0.,0. ); } // camera fout << "camera { // following POV-Ray, x is right, y is up, and z is to the scene" << endl << " location <" << eye[0] << ", " << eye[2] << ", " << eye[1] << ">" << endl << " up <" << up[0] << ", " << up[2] << ", " << up[1] << ">" << endl << " right <" << right[0] << ", " << right[2] << ", " << right[1] << ">" << endl << " look_at <" << center[0] << ", " << center[2] << ", " << center[1] << ">" << endl << "}" << endl << endl; POVWriterNodeVisitor povWriter( fout, node.getBound() ); if( camera ) for( int i=0, c=camera->getNumChildren(); i<c; i++ ) const_cast< Camera* >( camera )->getChild( i )->accept( povWriter ); else const_cast< Node* >( &node )->accept( povWriter ); notify( NOTICE ) << "ReaderWriterPOV::writeNode() Done. (" << povWriter.getNumProducedTriangles() << " triangles written)" << endl; return osgDB::ReaderWriter::WriteResult::FILE_SAVED; }