Lilinx,

This is the class I use. I put the skybox (or sphere, in my case) below it,
and make sure that the forced range of z will include all of it. e.g. with a
cube of size [-1.0, 1.0] in x,y,z, the default znear =0.5, zfar = 2.0 is OK.

As you can see, it could use some optimisation in a number of places.

Hope it helps,

David

On 02/05/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:

Robert, David
    Thanks.
The way I adopted was using two cameras to do this. The first renderes
only the sky box. The second renderes other models.
It's ugly but I could not find a better way the past week.
Your advice was a great help to me.  could you post the sample code to my
email([EMAIL PROTECTED]) or osg-users mailing?
   Best regards,

lilinx




_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

#include "ExtentsCamera.h"

#include <osgUtil/CullVisitor>

CExtentsCamera::CExtentsCamera() : osg::CameraNode()
{
	// Turn culling off (possibly duplicated statements)
	this->setCullingActive(false);
	this->setCullingMode(osg::CullSettings::NO_CULLING);

	// We will compute the near/far planes ourselves
	this->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

	// Reset our store of the projection matrix
	_matrix.identity();

	// Default near/far ranges (to bracket a viewer centred sphere with radius 1)
	_zNear = 0.5;	// Forcing the near plane to be 0.5m
	_zFar  = 2.0;	// Forcing the far plane to be 2m


}

void CExtentsCamera::traverse(osg::NodeVisitor &nv)
{
	// If the scene hasn't been defined (i.e. we have no children at all) then don't do anything
	// NB : This may be an unnecessary test (not sure).
    unsigned int numChildren = _children.size();
    if(numChildren == 0) return;

    // If the visitor is not a cull visitor, then we are not interested
	// in intercepting it, so pass it directly onto the scene.
    osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
    if(!cv) 
    { 
		CameraNode::traverse(nv);
		return; 
    }

	// Get a reference to the Cull Visitor's projection matrix
	osg::RefMatrix& projection = cv->getProjectionMatrix();

	// For the purposes of minimising the work we need to do,
	// compare our copy of the projection matrix with the current one. If they
	// are the same then we don't need to do anything.
	// NB 1 : No speed trials have been done to determine whether this "early out" is worth it
	// NB 2 : Direct comparison of float matrices is not really a good idea
	if(projection==_matrix)
	{
		CameraNode::traverse(nv);
		return; 
    }

	// The projection matrix has changed, one way or another (e.g. first pass, or through
	// changing the window size
	double n,f,l,r,t,b;	// near, far, left, right, top, bottom
	projection.getFrustum(l,r,b,t,n,f);
	
	//double a = (r-l)/(t-b);
	

	// NB : This might be possible to simplify and hence optimise (haven't yet checked)
    double trans_near = (-_zNear*projection(2,2) + projection(3,2)) /
                        (-_zNear*projection(2,3) + projection(3,3));
    double trans_far =  ( -_zFar*projection(2,2) + projection(3,2)) /
                        ( -_zFar*projection(2,3) + projection(3,3));
    double ratio = fabs(2.0/(trans_near - trans_far));
    double center = -0.5*(trans_near + trans_far);

	// Set the projection matrix
    projection.postMult(osg::Matrixd(	1.0, 0.0, 0.0,			0.0,
										0.0, 1.0, 0.0,			0.0,
										0.0, 0.0, ratio,		0.0,
										0.0, 0.0, center*ratio, 1.0));
	
	// Take a copy of the projection matrix
	_matrix = projection;

	CameraNode::traverse(nv);
}

void CExtentsCamera::SetZRange(float zNear, float zFar)
{
	// NB : Should probably check that zNear!=zFar otherwise we'll get div0 in the
	// traverse loop
	_zNear = zNear;
	_zFar = zFar;
}
#ifndef EXTENTS_CAMERA_H
#define EXTENTS_CAMERA_H

#include <osg/CameraNode>

class CExtentsCamera : public osg::CameraNode
{

    public:
                CExtentsCamera();
                virtual void traverse(osg::NodeVisitor &nv); 

                // Sets the forcing range for the near and far planes
                void SetZRange(float zNear, float zFar);
    protected:
                osg::Matrix _matrix;
                float           _zNear;
                float           _zFar;
 
};

#endif
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to