Hi Stuart,

Attached is a small fix for the sorting in CloudShaderGeometry.cxx.
I think the sorting problem stems from the osg idiosyncracy
to store transposed matrices...so the intuitive

        osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f);

needs to be replaced with...

        osg::Vec4f p = vm.preMult(osg::Vec4f(_cloudsprites[i]->position.osg(), 
1.0f);

The patch also optimizes the distance calculation - it evaluates the distances 
in model space instead of eye space, which reduces computation to a dot-
product instead of a matrix multiplication.

bye, 

        Manuel

Index: CloudShaderGeometry.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/scene/sky/CloudShaderGeometry.cxx,v
retrieving revision 1.2
diff -u -r1.2 CloudShaderGeometry.cxx
--- CloudShaderGeometry.cxx	6 Nov 2008 21:58:07 -0000	1.2
+++ CloudShaderGeometry.cxx	9 Nov 2008 03:34:23 -0000
@@ -34,27 +34,32 @@
 {
 void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
 {
+    if (!_cloudsprites.size()) return;
+    
     osg::State& state = *renderInfo.getState();
     osg::Matrix vm = state.getModelViewMatrix();
     
     //TODO: It isn't clear whether this is worth the perf hit ATM.
     
-    // Do a single iteration of a bubble sort. We do this in reverse
-    // so that elements closest to the camera bubble to the front than
-    // the elements further away
-    for(int i = (_cloudsprites.size() -2); i >= 0; i--)
+    // Transform the viewing direction, represented by the eye space vector (0,0,-1, 0), into model-space
+    // (here we simply take the opposite direction and reverse the ordering when sorting)
+    osg::Vec3f view_dir(vm(0, 2), vm(1, 2), vm(2, 2));      // Caveat: OpenSceneGraph matrices are transposed!
+
+    float p = view_dir*_cloudsprites[0]->position.osg();
+    // Do a single iteration of a bubble sort, sorting
+    // back to front.
+    for(int i = 0; i < _cloudsprites.size() - 1; i++)
     {
-        osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(),   1.0f);
-        osg::Vec4f q = vm * osg::Vec4f(_cloudsprites[i+1]->position.osg(), 1.0f);
-        
-        if (p.z() > q.z())
-        {
+        float q = view_dir*_cloudsprites[i+1]->position.osg();
+        if (p > q) {  
             CloudSprite c = *_cloudsprites[i];
             *_cloudsprites[i] = *_cloudsprites[i+1];
             *_cloudsprites[i+1] = c;
         }
+        else
+            p = q;
     }
-    
+
     const Extensions* extensions = getExtensions(state.getContextID(),true);
 
     for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t)
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/flightgear-devel

Reply via email to