From 5d35daa970175ff44b75f47af170238422cea5eb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Oct 2003 12:54:21 +0000 Subject: [PATCH] Udates to Drawable + IVE plugin with support for new ClusterCullingCallack. Improvement to osgbluemarble. --- examples/osgbluemarble/osgbluemarble.cpp | 151 +++++++++++------------ include/osg/Drawable | 10 +- src/osg/Drawable.cpp | 91 ++++++++++++-- src/osgPlugins/gdal/ReaderWriterGDAL.cpp | 8 +- src/osgPlugins/ive/Drawable.cpp | 147 +++++++++++----------- src/osgPlugins/ive/GNUmakefile | 1 + src/osgPlugins/ive/ReadWrite.h | 1 + 7 files changed, 240 insertions(+), 169 deletions(-) diff --git a/examples/osgbluemarble/osgbluemarble.cpp b/examples/osgbluemarble/osgbluemarble.cpp index 509a4e2a2..ff95671c1 100644 --- a/examples/osgbluemarble/osgbluemarble.cpp +++ b/examples/osgbluemarble/osgbluemarble.cpp @@ -45,7 +45,7 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x options->_sourceRatioWindow.set(x,1-(y+h),w,h); options->_destinationImageWindowMode = osgDB::ImageOptions::PIXEL_WINDOW; - options->_destinationPixelWindow.set(0,0,512,512); + options->_destinationPixelWindow.set(0,0,256,256); osgDB::Registry::instance()->setOptions(options.get()); osg::Image* image = osgDB::readImageFile(filename.c_str()); @@ -61,8 +61,8 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x geode->setStateSet( stateset ); - unsigned int numColumns = 20; - unsigned int numRows = 20; + unsigned int numColumns = 10; + unsigned int numRows = 10; unsigned int r; unsigned int c; @@ -142,108 +142,101 @@ osg::Node* createTile(const std::string& filename, bool leftHemisphere, double x geometry->setUseVertexBufferObjects(true); + + { + osg::Vec3 center = computePosition(leftHemisphere, x+w*0.5, y+h*0.5); + osg::Vec3 normal = center; + osg::Vec3 n00 = computePosition(leftHemisphere, x, y); + osg::Vec3 n10 = computePosition(leftHemisphere, x+w, y); + osg::Vec3 n11 = computePosition(leftHemisphere, x+w, y+h); + osg::Vec3 n01 = computePosition(leftHemisphere, x, y+h); + + float radius = (center-n00).length(); + radius = osg::maximum((center-n10).length(),radius); + radius = osg::maximum((center-n11).length(),radius); + radius = osg::maximum((center-n01).length(),radius); + + float min_dot = normal*n00; + min_dot = osg::minimum(normal*n10,min_dot); + min_dot = osg::minimum(normal*n11,min_dot); + min_dot = osg::minimum(normal*n01,min_dot); + + float angle = acosf(min_dot)+osg::PI*0.5f; + float deviation = (anglesetControlPoint(center); + ccc->setNormal(normal); + ccc->setRadius(radius); + ccc->setDeviation(deviation); + geometry->setCullCallback(ccc); + } + + geode->addDrawable(geometry); return geode; } -osg::Node* createTileAndRecurse(const std::string& filename, const std::string& basename, const std::string& extension, bool leftHemisphere, double x, double y, double w,double h, unsigned int numLevelsLeft) +osg::Node* createTileAndRecurse(const std::string& filename, const std::string& basename, const std::string& extension, bool leftHemisphere, unsigned int noTilesX, unsigned int noTilesY, double x, double y, double w,double h, unsigned int numLevelsLeft) { osg::Group* group = new osg::Group; + double dx = w / (double) noTilesX; + double dy = h / (double) noTilesY; + + if (numLevelsLeft>0) { - std::string basename1 = basename+"_1"; - std::string basename2 = basename+"_2"; - std::string basename3 = basename+"_3"; - std::string basename4 = basename+"_4"; - - { - osg::ref_ptr node = createTileAndRecurse(filename,basename1,extension,leftHemisphere,x,y,w*0.5,h*0.5,numLevelsLeft-1); - osgDB::writeNodeFile(*node, basename1+extension); - } - - { - osg::ref_ptr node = createTileAndRecurse(filename,basename2,extension,leftHemisphere,x+w*0.5,y,w*0.5,h*0.5,numLevelsLeft-1); - osgDB::writeNodeFile(*node, basename2+extension); - } - - { - osg::ref_ptr node = createTileAndRecurse(filename,basename3,extension,leftHemisphere,x,y+h*0.5,w*0.5,h*0.5,numLevelsLeft-1); - osgDB::writeNodeFile(*node, basename3+extension); - } - - { - osg::ref_ptr node = createTileAndRecurse(filename,basename4,extension,leftHemisphere,x+w*0.5,y+h*0.5,w*0.5,h*0.5,numLevelsLeft-1); - osgDB::writeNodeFile(*node, basename4+extension); - } - - float cut_off_distance = h*osg::PI; + float cut_off_distance = 4.0f*dy*osg::PI; float max_visible_distance = 1e7; // create current layer, and write to disk. + unsigned int numTiles = 0; + double lx = x; + for(unsigned i=0;i node = createTileAndRecurse(filename,lbasename,extension,leftHemisphere,2,2,lx,ly,dx,dy,numLevelsLeft-1); + osgDB::writeNodeFile(*node, lbasename+extension); + } + + // create PagedLOD for tile. osg::PagedLOD* pagedlod = new osg::PagedLOD; - osg::Node* tile = createTile(filename,leftHemisphere,x,y,w*0.5,h*0.5); + osg::Node* tile = createTile(filename,leftHemisphere,lx,ly,dx,dy); pagedlod->addChild(tile, cut_off_distance,max_visible_distance); pagedlod->setRange(1,0.0f,cut_off_distance); - pagedlod->setFileName(1,basename1+extension); - pagedlod->setCenter(computePosition(leftHemisphere,x+w*0.25,y+h*0.25)); + pagedlod->setFileName(1,lbasename+extension); + pagedlod->setCenter(computePosition(leftHemisphere,lx+dx*0.5,ly+dy*0.5)); group->addChild(pagedlod); + + // increment number of tiles. + ++numTiles; } - { - osg::PagedLOD* pagedlod = new osg::PagedLOD; - - osg::Node* tile = createTile(filename,leftHemisphere,x+w*0.5,y,w*0.5,h*0.5); - pagedlod->addChild(tile, cut_off_distance,max_visible_distance); - pagedlod->setRange(1,0.0f,cut_off_distance); - pagedlod->setFileName(1,basename2+extension); - pagedlod->setCenter(computePosition(leftHemisphere,x+w*0.75,y+h*0.25)); - - group->addChild(pagedlod); - } - - { - osg::PagedLOD* pagedlod = new osg::PagedLOD; - - osg::Node* tile = createTile(filename,leftHemisphere,x,y+h*0.5,w*0.5,h*0.5); - pagedlod->addChild(tile, cut_off_distance,max_visible_distance); - pagedlod->setRange(1,0.0f,cut_off_distance); - pagedlod->setFileName(1,basename3+extension); - pagedlod->setCenter(computePosition(leftHemisphere,x+w*0.25,y+h*0.75)); - - group->addChild(pagedlod); - } - - { - osg::PagedLOD* pagedlod = new osg::PagedLOD; - - osg::Node* tile = createTile(filename,leftHemisphere,x+w*0.5,y+h*0.5,w*0.5,h*0.5); - pagedlod->addChild(tile, cut_off_distance,max_visible_distance); - pagedlod->setRange(1,0.0f,cut_off_distance); - pagedlod->setFileName(1,basename4+extension); - pagedlod->setCenter(computePosition(leftHemisphere,x+w*0.75,y+h*0.75)); - - group->addChild(pagedlod); - } - } - } else { - // create current layer, and write to disk. + double lx = x; + for(unsigned i=0;iaddChild(createTile(filename,leftHemisphere,x,y,w*0.5,h*0.5)); - group->addChild(createTile(filename,leftHemisphere,x+w*0.5,y,w*0.5,h*0.5)); - group->addChild(createTile(filename,leftHemisphere,x,y+h*0.5,w*0.5,h*0.5)); - group->addChild(createTile(filename,leftHemisphere,x+w*0.5,y+h*0.5,w*0.5,h*0.5)); + double ly = y; + for(unsigned j=0;jaddChild(createTile(filename,leftHemisphere,lx,ly,dx,dy)); + } } } @@ -277,8 +270,8 @@ bool createWorld(const std::string& left_hemisphere, const std::string& right_he osg::ref_ptr group = new osg::Group; - group->addChild(createTileAndRecurse(left_hemisphere, base+"_west", extension, true, 0.0, 0.0, 1.0, 1.0, numLevels)); - group->addChild(createTileAndRecurse(right_hemisphere, base+"_east", extension, false, 0.0, 0.0, 1.0, 1.0, numLevels)); + group->addChild(createTileAndRecurse(left_hemisphere, base+"_west", extension, true, 5,5, 0.0, 0.0, 1.0, 1.0, numLevels)); + group->addChild(createTileAndRecurse(right_hemisphere, base+"_east", extension, false, 5,5, 0.0, 0.0, 1.0, 1.0, numLevels)); osg::StateSet* stateset = group->getOrCreateStateSet(); stateset->setMode(GL_CULL_FACE,osg::StateAttribute::ON); @@ -331,7 +324,7 @@ int main( int argc, char **argv ) std::string left_hemisphere("land_shallow_topo_west.tif"); std::string right_hemisphere("land_shallow_topo_east.tif"); - std::string basename("bluemarble.ive"); + std::string basename("BlueMarble/bluemarble.ive"); createWorld(left_hemisphere,right_hemisphere,basename,4); diff --git a/include/osg/Drawable b/include/osg/Drawable index cf1205f5a..3738d472f 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -731,6 +731,9 @@ class SG_EXPORT ClusterCullingCallback : public Drawable::CullCallback void setNormal(const osg::Vec3& normal) { _normal = normal; } const osg::Vec3& getNormal() const { return _normal; } + void setRadius(float radius) { _radius = radius; } + float getRadius() const { return _radius; } + void setDeviation(float deviation) { _deviation = deviation; } float getDeviation() const { return _deviation; } @@ -740,9 +743,10 @@ class SG_EXPORT ClusterCullingCallback : public Drawable::CullCallback virtual ~ClusterCullingCallback() {} - osg::Vec3 _controlPoint; - osg::Vec3 _normal; - float _deviation; + osg::Vec3 _controlPoint; + osg::Vec3 _normal; + float _radius; + float _deviation; }; diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index dfe671cc0..5ccfa6f44 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -899,6 +899,7 @@ void Drawable::Extensions::glGetOcclusionQueryuiv( GLuint id, GLenum pname, GLui // ClusterCullingCallback::ClusterCullingCallback(): + _radius(-1.0f), _deviation(-1.0f) { } @@ -919,20 +920,24 @@ ClusterCullingCallback::ClusterCullingCallback(const osg::Drawable* drawable) computeFrom(drawable); } -struct CollectNormalsFunctor +struct ComputeAveragesFunctor { - CollectNormalsFunctor(): - _x(0.0),_y(0.0),_z(0) {} + ComputeAveragesFunctor(): + _num(0), + _x(0.0),_y(0.0),_z(0), + _nx(0.0),_ny(0.0),_nz(0) {} inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3, bool) { // calc orientation of triangle. osg::Vec3 normal = (v2-v1)^(v3-v1); - normal.normalize(); - - _normals.push_back(normal); - + if (normal.normalize()!=0.0f) + { + _nx += normal.x(); + _ny += normal.y(); + _nz += normal.z(); + } _x += v1.x(); _y += v1.y(); _z += v1.z(); @@ -944,20 +949,74 @@ struct CollectNormalsFunctor _x += v3.x(); _y += v3.y(); _z += v3.z(); + + + ++_num; } - typedef std::vector NormalList; - NormalList _normals; + osg::Vec3 center() const { return osg::Vec3(_x/(double)(3*_num),_y/(double)(3*_num),_z/(double)(3*_num)); } + osg::Vec3 normal() const { Vec3 normal(_nx/(double)_num,_ny/(double)_num,_nz/(double)_num); normal.normalize(); return normal; } + + unsigned int _num; double _x,_y,_z; + double _nx,_ny,_nz; }; +struct ComputeDeviationFunctor +{ + + ComputeDeviationFunctor(): + _deviation(1.0), + _radius2(0.0) {} + + void set(const osg::Vec3& center,const osg::Vec3& normal) + { + _center = center; + _normal = normal; + } + + inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3, bool) + { + // calc orientation of triangle. + osg::Vec3 normal = (v2-v1)^(v3-v1); + if (normal.normalize()!=0.0f) + { + _deviation = osg::minimum(_normal*normal,_deviation); + } + _radius2 = osg::maximum((v1-_center).length2(),_radius2); + _radius2 = osg::maximum((v2-_center).length2(),_radius2); + _radius2 = osg::maximum((v3-_center).length2(),_radius2); + + } + osg::Vec3 _center; + osg::Vec3 _normal; + float _deviation; + float _radius2; +}; void ClusterCullingCallback::computeFrom(const osg::Drawable* drawable) { - TriangleFunctor stf; - drawable->accept(stf); + TriangleFunctor caf; + drawable->accept(caf); + + _controlPoint = caf.center(); + _normal = caf.normal(); + + TriangleFunctor cdf; + cdf.set(_controlPoint,_normal); + drawable->accept(cdf); + + if (_normal.length2()==0.0) _deviation = -1.0f; + else + { + float angle = acosf(cdf._deviation)+osg::PI*0.5f; + if (anglegetEyePoint() - _controlPoint; + + float deviation = (eye_cp * _normal)/eye_cp.length(); + + return deviation < _deviation; } diff --git a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp index 414428e46..71201cc87 100644 --- a/src/osgPlugins/gdal/ReaderWriterGDAL.cpp +++ b/src/osgPlugins/gdal/ReaderWriterGDAL.cpp @@ -50,10 +50,10 @@ class ReaderWriterGDAL : public osgDB::ReaderWriter switch(imageOptions->_sourceImageWindowMode) { case(osgDB::ImageOptions::RATIO_WINDOW): - windowX = (unsigned int)(floor((double)dataWidth * imageOptions->_sourceRatioWindow.windowX)); - windowY = (unsigned int)(floor((double)dataHeight * imageOptions->_sourceRatioWindow.windowY)); - windowWidth = (unsigned int)(ceil((double)dataWidth * (imageOptions->_sourceRatioWindow.windowX + imageOptions->_sourceRatioWindow.windowWidth)))-windowX; - windowHeight = (unsigned int)(ceil((double)dataHeight * (imageOptions->_sourceRatioWindow.windowY + imageOptions->_sourceRatioWindow.windowHeight)))-windowY; + windowX = osg::maximum((int)(floor((double)dataWidth * imageOptions->_sourceRatioWindow.windowX)),0); + windowY = osg::maximum((int)(floor((double)dataHeight * imageOptions->_sourceRatioWindow.windowY)),0); + windowWidth = osg::minimum((int)(ceil((double)dataWidth * (imageOptions->_sourceRatioWindow.windowX + imageOptions->_sourceRatioWindow.windowWidth))),dataWidth)-windowX; + windowHeight = osg::minimum((int)(ceil((double)dataHeight * (imageOptions->_sourceRatioWindow.windowY + imageOptions->_sourceRatioWindow.windowHeight))),dataHeight)-windowY; break; case(osgDB::ImageOptions::PIXEL_WINDOW): windowX = imageOptions->_sourcePixelWindow.windowX; diff --git a/src/osgPlugins/ive/Drawable.cpp b/src/osgPlugins/ive/Drawable.cpp index 7f707debb..4fdda57dc 100644 --- a/src/osgPlugins/ive/Drawable.cpp +++ b/src/osgPlugins/ive/Drawable.cpp @@ -1,100 +1,107 @@ /********************************************************************** * - * FILE: Drawable.cpp + * FILE: Drawable.cpp * - * DESCRIPTION: Read/Write osg::Drawable in binary format to disk. + * DESCRIPTION: Read/Write osg::Drawable in binary format to disk. * - * CREATED BY: Auto generated by iveGenerated - * and later modified by Rune Schmidt Jensen. + * CREATED BY: Auto generated by iveGenerated + * and later modified by Rune Schmidt Jensen. * - * HISTORY: Created 18.3.2003 + * HISTORY: Created 18.3.2003 * - * Copyright 2003 VR-C + * Copyright 2003 VR-C **********************************************************************/ #include "Exception.h" #include "Drawable.h" +#include "ClusterCullingCallback.h" #include "Object.h" #include "StateSet.h" using namespace ive; -void Drawable::write(DataOutputStream* out){ - // Write Drawable's identification. - out->writeInt(IVEDRAWABLE); - // If the osg class is inherited by any other class we should also write this to file. - osg::Object* obj = dynamic_cast(this); - if(obj){ - ((ive::Object*)(obj))->write(out); - } - else - throw Exception("Drawable::write(): Could not cast this osg::Drawable to an osg::Object."); +void Drawable::write(DataOutputStream* out) +{ + // Write Drawable's identification. + out->writeInt(IVEDRAWABLE); + // If the osg class is inherited by any other class we should also write this to file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->write(out); + } + else + throw Exception("Drawable::write(): Could not cast this osg::Drawable to an osg::Object."); - // Write Drawable's properties. - - // Write stateset if any - if (getStateSet()) - { - out->writeInt(1); //true we have a stateset - out->writeStateSet(getStateSet()); - } - else - out->writeInt(0); //false we don't have a stateset + // Write Drawable's properties. - // Write shape - if (getShape()) - { - out->writeInt(1); //true we have a shape - //static_cast(getShape())->write(out); - } - else - out->writeInt(0); //false we don't have a shape + // Write stateset if any + out->writeBool(getStateSet()!=0); + if (getStateSet()) + { + out->writeStateSet(getStateSet()); + } + + + osg::ClusterCullingCallback* ccc = dynamic_cast(getCullCallback()); + out->writeBool(ccc!=0); + if(ccc) + { + ((ive::ClusterCullingCallback*)(ccc))->write(out); + } - // Write support display list. - out->writeBool(getSupportsDisplayList()); + // Write support display list. + out->writeBool(getSupportsDisplayList()); - // Write use display list. - out->writeBool(getUseDisplayList()); + // Write use display list. + out->writeBool(getUseDisplayList()); + // Write use display list. + out->writeBool(getUseVertexBufferObjects()); } -void Drawable::read(DataInputStream* in){ - // Read Drawable's identification. - int id = in->peekInt(); - if(id == IVEDRAWABLE){ - // Code to read Drawable's properties. - id = in->readInt(); - // If the osg class is inherited by any other class we should also read this from file. - osg::Object* obj = dynamic_cast(this); - if(obj){ - ((ive::Object*)(obj))->read(in); - } - else - throw Exception("Drawable::read(): Could not cast this osg::Drawable to an osg::Object."); +void Drawable::read(DataInputStream* in) +{ + // Read Drawable's identification. + int id = in->peekInt(); + if(id == IVEDRAWABLE) + { + // Code to read Drawable's properties. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->read(in); + } + else + throw Exception("Drawable::read(): Could not cast this osg::Drawable to an osg::Object."); - // Read in drawable's properties + // Read in drawable's properties - // Read stateset if any - if(in->readInt()){ - setStateSet(in->readStateSet()); - } + // Read stateset if any + if(in->readBool()) + { + setStateSet(in->readStateSet()); + } - // Read shape if any - if(in->readInt()){ - //osg::Shape* shape = new osg::Shape(); - //static_cast(shape)->read(in); - //setShape(shape); - } + if(in->readBool()) + { + osg::ClusterCullingCallback* ccc = new osg::ClusterCullingCallback(); + ((ive::ClusterCullingCallback*)(ccc))->read(in); + setCullCallback(ccc); + } - // Read support display list - setSupportsDisplayList(in->readBool()); + // Read support display list + setSupportsDisplayList(in->readBool()); - // Read use display list - setUseDisplayList(in->readBool()); + // Read use display list + setUseDisplayList(in->readBool()); - } - else{ - throw Exception("Drawable::read(): Expected Drawable identification."); - } + // Read use display list + setUseVertexBufferObjects(in->readBool()); + + } + else{ + throw Exception("Drawable::read(): Expected Drawable identification."); + } } diff --git a/src/osgPlugins/ive/GNUmakefile b/src/osgPlugins/ive/GNUmakefile index 7d9228ffe..ebc9088a9 100644 --- a/src/osgPlugins/ive/GNUmakefile +++ b/src/osgPlugins/ive/GNUmakefile @@ -8,6 +8,7 @@ CXXFILES =\ BlendFunc.cpp\ ConvexPlanarOccluder.cpp\ ConvexPlanarPolygon.cpp\ + ClusterCullingCallback.cpp\ CullFace.cpp\ DataInputStream.cpp\ DataOutputStream.cpp\ diff --git a/src/osgPlugins/ive/ReadWrite.h b/src/osgPlugins/ive/ReadWrite.h index e95420bb5..cbd6b1fda 100644 --- a/src/osgPlugins/ive/ReadWrite.h +++ b/src/osgPlugins/ive/ReadWrite.h @@ -32,6 +32,7 @@ namespace ive { // Node callbacks #define IVENODECALLBACK 0x00000050 #define IVEANIMATIONPATHCALLBACK 0x00000051 +#define IVECLUSTERCULLINGCALLBACK 0x00000052 // State attributes. #define IVESTATEATTRIBUTE 0x00000100