]> git.mxchange.org Git - simgear.git/commitdiff
Stuart:
authorfredb <fredb>
Sun, 30 Nov 2008 23:06:18 +0000 (23:06 +0000)
committerfredb <fredb>
Sun, 30 Nov 2008 23:06:18 +0000 (23:06 +0000)
Attached is another clouds patch. This does the following:
1) Puts the 3D clouds in a cloud rendering bin, to reduce the transparent edge problem. Viewing 3d clouds against a 2D layer _above_ it now blends correctly. There is still a problem when viewing a layer below the 3d clouds, and I'm not sure if/how I'll manage to solve that. Thanks to Tim for pointing me at the correct code (again).
2) Performance improvement by calculating the Bounding box when the cloud is generated rather than ever time it is requested.

simgear/scene/sky/CloudShaderGeometry.cxx
simgear/scene/sky/CloudShaderGeometry.hxx
simgear/scene/sky/cloud.cxx
simgear/scene/sky/cloudfield.cxx
simgear/scene/sky/cloudfield.hxx
simgear/scene/sky/newcloud.cxx

index a556afb0d1ac70cd7636e07244709c3a7e479099..92d73f961c7466f92242426aa9445867416257bd 100755 (executable)
@@ -104,21 +104,6 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
     }
 }
     
-BoundingBox CloudShaderGeometry::computeBound() const
-{
-    BoundingBox geom_box = _geometry->getBound();
-    BoundingBox bb;
-    for(CloudSpriteList::const_iterator itr = _cloudsprites.begin();
-        itr != _cloudsprites.end();
-        ++itr) {
-         bb.expandBy(geom_box.corner(0)*(*itr)->width +
-                 osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() ));
-         bb.expandBy(geom_box.corner(7)*(*itr)->height +
-                 osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() ));
-    }
-    return bb;
-}
-
 bool CloudShaderGeometry_readLocalData(Object& obj, Input& fr)
 {
     bool iteratorAdvanced = false;
index 2401e9626f4905cbaedfae2f012ccda233bfe2c4..af0bc36d3ff62b2da284a5de283bf6ad3e81f8ad 100755 (executable)
@@ -55,11 +55,15 @@ class CloudShaderGeometry : public osg::Drawable
             skip_info = new SkipInfo();
         }
 
-        CloudShaderGeometry(int vx, int vy) :
+        CloudShaderGeometry(int vx, int vy, float width, float height) :
             varieties_x(vx), varieties_y(vy)
         { 
             setUseDisplayList(false); 
             skip_info = new SkipInfo();
+            float x = width/2.0f;
+            float z = height/2.0f;
+            _bbox.expandBy(-x, -x, -z);
+            _bbox.expandBy(x, x, z);
         }
         
         /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
@@ -106,8 +110,10 @@ class CloudShaderGeometry : public osg::Drawable
         typedef std::vector<osg::Vec4> PositionSizeList;
         
         virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
-        virtual osg::BoundingBox computeBound() const;
-    
+        virtual osg::BoundingBox computeBound() const
+        {
+            return _bbox;
+        }
         
         void setGeometry(osg::Drawable* geometry)
         {
@@ -136,6 +142,9 @@ class CloudShaderGeometry : public osg::Drawable
         int varieties_x;
         int varieties_y;
         
+        // Bounding box extents.
+        osg::BoundingBox _bbox;
+        
     protected:
     
         virtual ~CloudShaderGeometry() {
index 4a9bf2e12b6343f1a064ea7a14975d9269846ee4..84e4f5f8cdc024f3b9079b11d6f3b4916111e5a2 100644 (file)
@@ -719,7 +719,7 @@ bool SGCloudLayer::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
         last_lat = lat;
     }
 
-    layer3D->reposition( p, up, lon, lat, dt);
+    layer3D->reposition( p, up, lon, lat, dt, layer_asl);
     return true;
 }
 
index 7fd7ce98f91595b1f0e77f50609a7714895bf762..4cbefd7dd39d1a517abd87035368d4271a6ee39c 100644 (file)
@@ -40,6 +40,7 @@
 using std::vector;
 
 #include <simgear/environment/visual_enviro.hxx>
+#include <simgear/scene/util/RenderConstants.hxx>
 #include "sky.hxx"
 #include "newcloud.hxx"
 #include "cloudfield.hxx"
@@ -56,6 +57,8 @@ using std::vector;
 #  endif
 #endif
 
+using namespace simgear;
+
 
 #if defined (__CYGWIN__)
 #include <ieeefp.h>
@@ -72,7 +75,7 @@ void SGCloudField::set_density(float density) {
 
 // reposition the cloud layer at the specified origin and orientation
 bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon, double lat,
-                              double dt )
+                              double dt, int asl )
 {
     osg::Matrix T, LON, LAT;
     
@@ -129,6 +132,9 @@ bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
 
         field_transform->setMatrix( LAT*LON*T );
     }
+    
+    field_root->getStateSet()->setRenderBinDetails(asl, "RenderBin");
+
     return true;
 }
 
@@ -145,6 +151,8 @@ SGCloudField::SGCloudField() :
     cld_pos = SGGeoc();
     field_root->addChild(field_transform.get());
     field_root->setName("3D Cloud field root");
+    osg::StateSet *rootSet = field_root->getOrCreateStateSet();
+    rootSet->setRenderBinDetails(CLOUDS_BIN, "DepthSortedBin");
     
     osg::ref_ptr<osg::Group> quad_root = new osg::Group();
     osg::ref_ptr<osg::LOD> quad[BRANCH_SIZE][BRANCH_SIZE];
@@ -257,7 +265,7 @@ void SGCloudField::addCloud( SGVec3f& pos, SGNewCloud *cloud) {
         int y = (int) floor((pos.y() + fieldSize/2.0) * QUADTREE_SIZE / fieldSize);
         if (y >= QUADTREE_SIZE) y = (QUADTREE_SIZE - 1);
         if (y < 0) y = 0;
-
+        
         osg::ref_ptr<osg::PositionAttitudeTransform> transform = new osg::PositionAttitudeTransform;
 
         transform->setPosition(pos.osg());
index 50207aac455a127d0c75ff3aff001ddc89834c34..8cac812f862ad7b223814ef39184d74bc51cbfc5 100644 (file)
@@ -93,12 +93,11 @@ public:
         * @param up the local up vector
         * @param lon specifies a rotation about the Z axis
         * @param lat specifies a rotation about the new Y axis
-        * @param spin specifies a rotation about the new Z axis
-        *        (and orients the sunrise/set effects)
         * @param dt the time elapsed since the last call
+        * @param asl altitude of the layer
         */
         bool reposition( const SGVec3f& p, const SGVec3f& up,
-                        double lon, double lat, double dt = 0.0 );
+                        double lon, double lat, double dt, int asl);
 
         osg::Group* getNode() { return field_root.get(); }
 
index 1ee3c5b3305ced0f75d18d4a7e479b5de27a3b86..9e01cc57749b65ca25d3110cf44f7cf86ed5ebdc 100644 (file)
@@ -295,7 +295,8 @@ static float Rnd(float n) {
 
 osg::ref_ptr<Geode> SGNewCloud::genCloud() {
     Geode* geode = new Geode;
-    CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y);
+    
+    CloudShaderGeometry* sg = new CloudShaderGeometry(num_textures_x, num_textures_y, max_width, max_height);
     
     // Determine how big this specific cloud instance is. Note that we subtract
     // the sprite size because the width/height is used to define the limits of