From 28031542130063b039b180716d32b852179b0acb Mon Sep 17 00:00:00 2001 From: fredb Date: Sun, 30 Nov 2008 23:06:18 +0000 Subject: [PATCH] Stuart: 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 | 15 --------------- simgear/scene/sky/CloudShaderGeometry.hxx | 15 ++++++++++++--- simgear/scene/sky/cloud.cxx | 2 +- simgear/scene/sky/cloudfield.cxx | 12 ++++++++++-- simgear/scene/sky/cloudfield.hxx | 5 ++--- simgear/scene/sky/newcloud.cxx | 3 ++- 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/simgear/scene/sky/CloudShaderGeometry.cxx b/simgear/scene/sky/CloudShaderGeometry.cxx index a556afb0..92d73f96 100755 --- a/simgear/scene/sky/CloudShaderGeometry.cxx +++ b/simgear/scene/sky/CloudShaderGeometry.cxx @@ -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; diff --git a/simgear/scene/sky/CloudShaderGeometry.hxx b/simgear/scene/sky/CloudShaderGeometry.hxx index 2401e962..af0bc36d 100755 --- a/simgear/scene/sky/CloudShaderGeometry.hxx +++ b/simgear/scene/sky/CloudShaderGeometry.hxx @@ -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 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() { diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx index 4a9bf2e1..84e4f5f8 100644 --- a/simgear/scene/sky/cloud.cxx +++ b/simgear/scene/sky/cloud.cxx @@ -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; } diff --git a/simgear/scene/sky/cloudfield.cxx b/simgear/scene/sky/cloudfield.cxx index 7fd7ce98..4cbefd7d 100644 --- a/simgear/scene/sky/cloudfield.cxx +++ b/simgear/scene/sky/cloudfield.cxx @@ -40,6 +40,7 @@ using std::vector; #include +#include #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 @@ -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 quad_root = new osg::Group(); osg::ref_ptr 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 transform = new osg::PositionAttitudeTransform; transform->setPosition(pos.osg()); diff --git a/simgear/scene/sky/cloudfield.hxx b/simgear/scene/sky/cloudfield.hxx index 50207aac..8cac812f 100644 --- a/simgear/scene/sky/cloudfield.hxx +++ b/simgear/scene/sky/cloudfield.hxx @@ -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(); } diff --git a/simgear/scene/sky/newcloud.cxx b/simgear/scene/sky/newcloud.cxx index 1ee3c5b3..9e01cc57 100644 --- a/simgear/scene/sky/newcloud.cxx +++ b/simgear/scene/sky/newcloud.cxx @@ -295,7 +295,8 @@ static float Rnd(float n) { osg::ref_ptr 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 -- 2.39.5