Oh, I wasn't suggesting removing multi-threading or any of that  
stuff, sorry for the confusion! The code I attached in the email is  
downright ugly and has no place in the OSG, which is without doubt  
the best designed and written piece of software I've ever had the  
pleasure of using :)

The RefMatrix Idea sounds more promising, but could cause some  
threading problems still unless I misunderstand how OSG works. I  
think the only real option for situations like mine is just to accept  
the loss of the near/far plane tuning and use a fixed matrix.

Thanks for all your help and thought on this matter,
Alan

On 8 Dec 2007, at 10:54, Robert Osfield wrote:

> HI Alan,
>
> The OSG strives to be flexible, and probably the most flexible scene
> graph on the planet, but there are just so many different ways people
> can set up scene graphs and use that even it is even it will have
> problems keeping up.  Flexibility in one area sometimes has to balance
> flexibility in others - for instance if you drop multi-thread,
> multiple cameras, multiple window support then you make more
> assumptions and provide more flexibility in state as it is no longer
> potentially multivalued, but of course this blows out the water usage
> for many users and limits it.
>
> As for access to the projection matrix once its been modified by the
> clamping of the projection matrix.  The projection matrix is managed
> as a RefMatrix so potentially one could take a references to this
> matrix, and then later query it when you need to. Unfortunately
> osg::Uniform is set up to take a copy of a Matrix rather than a
> reference to a RefMatrix, if it did take a reference then you would be
> able to just assign the projection matrix and reuse that.  Perhaps
> this generalization could be considered for the future, or perhaps
> osg::Uniform could be extended to copy and matrix of take a reference
> to a RefMatrix.
>
> Robert.
>
> On Dec 7, 2007 9:00 PM, Alan Purvis <[EMAIL PROTECTED]> wrote:
>> Hi Robert,
>>
>> Thanks to this advice I finally appear to have solved my problem! I
>> used my cull callback to highjack the matrix clamping implementation
>> callback of all cull visitors passing through the camera node. This
>> isn't thread safe, and undoes the flexibility of making the clamp
>> function overridable with a callback, but works for my needs. I've
>> pasted the code at the bottom of this email incase the code should
>> prove useful to anyone else with similar problems.
>>
>> I know it might seem like a selfish thing to say and OSG's design
>> shouldn't be driven by the needs of individual users and programs,
>> but with the advent of shaders and freedom from the fixed pipeline
>> rendering, getting "program-side" access to the actual OpenGL state
>> used to render a scene is becoming more and important. Back when OSG
>> was strictly fixed function it didn't really matter if OSG was
>> sliding the culling planes around the place to improve visual
>> quality, nobody needed to know it was going on and it produced nicer
>> images with less z-fighting. But now that OpenGL and OSG has given
>> programmers the freedom to redefine parts of the pipeline, knowing
>> what "hidden changes" OSG is making to the OpenGL state behind the
>> scenes is becoming more important I think.
>>
>> In this program of mine for example I need to reverse the normalised
>> z-buffer values stored in a depth texture to world space coordinates.
>> With the projection matrix used to generate the image, this is
>> trivial. But when OSG changes the matrix used, the values I back-
>> project become skewed. Does it make sense to provide an additional
>> callback or something in the CullVisitor class to provide access to
>> this matrix once it is computed? It seems like this kind of problem
>> will only become more common in the future with the proliferation of
>> RTT and all the rest of it.
>>
>> Thanks,
>> Alan.
>>
>> class WriteProjectionMatrixToUniformCallback : public  
>> osg::NodeCallback
>> {
>>         private:
>>         struct ClampProjectionMatrixCallback : public
>> osg::CullSettings::ClampProjectionMatrixCallback
>>         {
>>                 private:
>>                 osg::ref_ptr<osg::Uniform> _uniform;
>>
>>                 template<class matrix_type> bool  
>> clampprojectionmatriximpl
>> (matrix_type &PROJECTION, double &ZNEAR, double &ZFAR) const
>>                 {
>>                         double epsilon = 1e-6;
>>                         double nearfarratio = 0.0005;
>>
>>                         bool valid = true;
>>                         if(ZFAR < ZNEAR -epsilon)
>>                         {
>>                                 osg::notify(osg::INFO) <<  
>> "_clampProjectionMatrix not applied,
>> invalid depth range, ZNEAR = " << ZNEAR <<"  ZFAR = "<< ZFAR <<
>> std::endl;
>>                                 valid = false;
>>                         }
>>                         else
>>                         {
>>                                 if(ZFAR < ZNEAR +epsilon)
>>                                 {
>>                                         double average = (ZNEAR  
>> +ZFAR) *0.5;
>>                                         ZNEAR = average -epsilon;
>>                                         ZFAR = average +epsilon;
>>                                 }
>>
>>                                 if(fabs(PROJECTION(0, 3)) <  
>> epsilon && fabs(PROJECTION(1, 3)) <
>> epsilon && fabs(PROJECTION(2, 3)) < epsilon)
>>                                 {
>>                                         double deltaspan = (ZFAR - 
>> ZNEAR) *0.02;
>>                                         if(deltaspan < 1.0)  
>> deltaspan = 1.0;
>>                                         double desiredznear =  
>> ZNEAR -deltaspan;
>>                                         double desiredzfar = ZFAR  
>> +deltaspan;
>>
>>                                         ZNEAR = desiredznear;
>>                                         ZFAR = desiredzfar;
>>
>>                                         PROJECTION(2, 2) =- 2.0f / 
>> (desiredzfar -desiredznear);
>>                                         PROJECTION(3, 2) =-  
>> (desiredzfar +desiredznear) /(desiredzfar -
>> desiredznear);
>>                                 }
>>                                 else
>>                                 {
>>                                         double zpushratio = 1.02;
>>                                         double zpullratio = 0.98;
>>
>>                                         double desiredznear =  
>> ZNEAR *zpullratio;
>>                                         double desiredzfar = ZFAR  
>> *zpushratio;
>>
>>                                         double minnearplane = ZFAR  
>> *nearfarratio;
>>                                         if(desiredznear <  
>> minnearplane) desiredznear = minnearplane;
>>
>>                                         ZNEAR = desiredznear;
>>                                         ZFAR = desiredzfar;
>>
>>                                         double transnearplane = (- 
>> desiredznear *PROJECTION(2, 2)
>> +PROJECTION(3, 2)) /(-desiredznear *PROJECTION(2, 3) +PROJECTION 
>> (3, 3));
>>                                         double transfarplane = (- 
>> desiredzfar *PROJECTION(2, 2)
>> +PROJECTION(3, 2)) /(-desiredzfar *PROJECTION(2, 3) +PROJECTION(3,  
>> 3));
>>
>>                                         double ratio = fabs(2.0 / 
>> (transnearplane -transfarplane));
>>                                         double center = - 
>> (transnearplane +transfarplane) /2.0;
>>
>>                                         PROJECTION.postMult 
>> (osg::Matrix(1.0f, 0.0f, 0.0f, 0.0f,
>>                                                                       
>>                                                                       
>>                               0.0f, 1.0f, 0.0f, 0.0f,
>>                                                                       
>>                                                                       
>>                               0.0f, 0.0f, ratio, 0.0f,
>>                                                                       
>>                                                                       
>>                               0.0f, 0.0f, center *ratio, 1.0f));
>>                                 }
>>                         }
>>
>>                         if(_uniform != NULL) _uniform->set 
>> (PROJECTION);
>>
>>                         /*
>>                         float n = (PROJECTION(3, 2) +PROJECTION(3,  
>> 3)) /(PROJECTION(2, 2)
>> +PROJECTION(2, 3));
>>                         float f = (PROJECTION(3, 3) -PROJECTION(3,  
>> 2)) /(PROJECTION(2, 3) -
>> PROJECTION(2, 2));
>>
>>                         std::cout << "n = " << n << ", f = " << f  
>> << "\n";
>>                         */
>>
>>                         return valid;
>>                 }
>>
>>                 public:
>>                 ClampProjectionMatrixCallback 
>> (osg::ref_ptr<osg::Uniform> UNIFORM)
>> { _uniform = UNIFORM; }
>>                 virtual ~ClampProjectionMatrixCallback(void) {}
>>
>>                 virtual bool clampProjectionMatrixImplementation 
>> (osg::Matrixf
>> &PROJECTION, double &ZNEAR, double &ZFAR) const
>>                 {
>>                         return clampprojectionmatriximpl 
>> (PROJECTION, ZNEAR, ZFAR);
>>                 }
>>                 virtual bool clampProjectionMatrixImplementation 
>> (osg::Matrixd
>> &PROJECTION, double &ZNEAR, double &ZFAR) const
>>                 {
>>                         return clampprojectionmatriximpl 
>> (PROJECTION, ZNEAR, ZFAR);
>>                 }
>>         };
>>
>>         static osg::ref_ptr<ClampProjectionMatrixCallback> _cpmc;
>>
>>         public:
>>         WriteProjectionMatrixToUniformCallback 
>> (osg::ref_ptr<osg::Uniform>
>> UNIFORM) { if(_cpmc == NULL) _cpmc = new  
>> ClampProjectionMatrixCallback
>> (UNIFORM); }
>>         virtual ~WriteProjectionMatrixToUniformCallback(void) {}
>>
>>         virtual void operator()(osg::Node* NODE, osg::NodeVisitor*  
>> NV)
>>         {
>>                 NodeCallback::traverse(NODE, NV);
>>
>>                 osgUtil::CullVisitor *cv =  
>> dynamic_cast<osgUtil::CullVisitor*>(NV);
>>                 if(cv == NULL) return;
>>
>>                 cv->setClampProjectionMatrixCallback(_cpmc.get());
>>         }
>> };
>>
>> osg::ref_ptr<WriteProjectionMatrixToUniformCallback::ClampProjectionM 
>> atr
>> ixCallback> WriteProjectionMatrixToUniformCallback::_cpmc = NULL;
>>
>>
>> On 7 Dec 2007, at 15:58, Robert Osfield wrote:
>>
>>
>>> On Dec 7, 2007 3:34 PM, Alan Purvis <[EMAIL PROTECTED]> wrote:
>>>> Does anyone have an idea what I might be doing wrong? Am I right to
>>>> call traverse before I deference the pointer to the matrix? Am I
>>>> getting a pointer to the right matrix?
>>>
>>> Reading through your you email the reason pinged into my head.  Your
>>> not doing anything wrong in terms of accessing the projection  
>>> matrix,
>>> the problem lies in the fact that the cull visitor does the clamping
>>> of the projection matrix once its traversed the whole subgraph  
>>> below a
>>> camera - which will be after your cull callback returns.  The actual
>>> clamping is dispatched within the CullVisitor;:popProjectionMatrix()
>>> method.
>>>
>>> Looking at your code you are setting a uniform with the projection
>>> matrix.   Perhaps you can dispense with this completely as OpenGL
>>> itself has the projection matrix as a built in uniform.
>>>
>>> Robert.
>>
>>> _______________________________________________
>>> osg-users mailing list
>>> [email protected]
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-
>>> openscenegraph.org
>>>
>>
>> _______________________________________________
>> osg-users mailing list
>> [email protected]
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users- 
>> openscenegraph.org
>>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users- 
> openscenegraph.org
>

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to