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.
This commit is contained in:
fredb
2008-11-30 23:06:18 +00:00
parent ae5297e6d7
commit 2803154213
6 changed files with 27 additions and 25 deletions

View File

@@ -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;

View File

@@ -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() {

View 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;
}

View 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());

View 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(); }

View 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