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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user