From 345810ef2278e3260899819c6a1046187fd5d169 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Nov 2006 16:00:52 +0000 Subject: [PATCH] Added support for float or double osg::Plane, and the default osg::Plane to double. Performance tests on big models did not indicate any performance penalty in using doubles over floats, so the move to doubles should mainly impact precision improvements for whole earth databases. Also made improvements to osgUtil::PlaneIntersector and osgSim::ElevationSlice classes --- examples/osgintersection/osgintersection.cpp | 87 +++++++---- examples/osgtexture1D/osgtexture1D.cpp | 2 +- examples/osgtexture3D/osgtexture3D.cpp | 2 +- examples/osgvolume/osgvolume.cpp | 6 +- include/osg/Plane | 154 +++++++++++++------ src/osg/TexGen.cpp | 37 ++--- src/osgPlugins/ive/DataInputStream.cpp | 26 ++-- src/osgPlugins/ive/DataInputStream.h | 2 +- src/osgPlugins/ive/DataOutputStream.cpp | 8 +- src/osgPlugins/ive/IveVersion.h | 3 +- src/osgPlugins/osg/TexGen.cpp | 2 +- src/osgSim/ElevationSlice.cpp | 44 +++++- src/osgText/FadeText.cpp | 18 +-- src/osgUtil/IntersectionVisitor.cpp | 6 +- 14 files changed, 262 insertions(+), 135 deletions(-) diff --git a/examples/osgintersection/osgintersection.cpp b/examples/osgintersection/osgintersection.cpp index 6fc5fcdc2..498595d4c 100644 --- a/examples/osgintersection/osgintersection.cpp +++ b/examples/osgintersection/osgintersection.cpp @@ -11,6 +11,7 @@ #include #include +#include #include @@ -42,7 +43,6 @@ int main(int argc, char **argv) } std::cout<<"Intersection "<(scene.get()); osg::EllipsoidModel* em = csn ? csn->getEllipsoidModel() : 0; @@ -55,10 +55,9 @@ int main(int argc, char **argv) if (useLineOfSight) { - osg::Timer_t startTick = osg::Timer::instance()->tick(); osg::Vec3d start = bs.center() + osg::Vec3d(0.0,bs.radius(),0.0); - osg::Vec3d end = bs.center();// - osg::Vec3d(0.0, bs.radius(),0.0); + osg::Vec3d end = bs.center() - osg::Vec3d(0.0, bs.radius(),0.0); osg::Vec3d deltaRow( 0.0, 0.0, bs.radius()*0.01); osg::Vec3d deltaColumn( bs.radius()*0.01, 0.0, 0.0); unsigned int numRows = 20; @@ -66,6 +65,7 @@ int main(int argc, char **argv) osgSim::LineOfSight los; +#if 0 osgSim::HeightAboveTerrain hat; hat.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback()); @@ -81,43 +81,66 @@ int main(int argc, char **argv) } - std::cout<<"Computing LineOfSight"<tick(); - - std::cout<<"Completed in "<delta_s(startTick,endTick)<tick(); + + los.computeIntersections(scene.get()); + + osg::Timer_t endTick = osg::Timer::instance()->tick(); + + std::cout<<"Completed in "<delta_s(startTick,endTick)<tick(); + + std::cout<<"Computing HeightAboveTerrain"<tick(); + + for(unsigned int i=0; idelta_s(startTick,endTick)<tick(); - - std::cout<<"Computing HeightAboveTerrain"<tick(); + + std::cout<<"Completed in "<delta_s(startTick,endTick)<tick(); - - std::cout<<"Completed in "<delta_s(startTick,endTick)<setMode(osg::TexGen::OBJECT_LINEAR); - texgen->setPlane(osg::TexGen::S,osg::Vec4(0.0f,0.0f,zScale,-zBase)); + texgen->setPlane(osg::TexGen::S,osg::Plane(0.0f,0.0f,zScale,-zBase)); osg::Material* material = new osg::Material; diff --git a/examples/osgtexture3D/osgtexture3D.cpp b/examples/osgtexture3D/osgtexture3D.cpp index 4b975ae10..04cbfcb22 100644 --- a/examples/osgtexture3D/osgtexture3D.cpp +++ b/examples/osgtexture3D/osgtexture3D.cpp @@ -89,7 +89,7 @@ class ConstructStateCallback : public osgProducer::OsgCameraGroup::RealizeCallba // will do the blending for us. osg::TexGen* texgen = new osg::TexGen; texgen->setMode(osg::TexGen::OBJECT_LINEAR); - texgen->setPlane(osg::TexGen::R, osg::Vec4(0.0f,0.0f,0.0f,0.2f)); + texgen->setPlane(osg::TexGen::R, osg::Plane(0.0f,0.0f,0.0f,0.2f)); // create the StateSet to store the texture data osg::StateSet* stateset = new osg::StateSet; diff --git a/examples/osgvolume/osgvolume.cpp b/examples/osgvolume/osgvolume.cpp index 112473851..72f7fa6fd 100644 --- a/examples/osgvolume/osgvolume.cpp +++ b/examples/osgvolume/osgvolume.cpp @@ -933,9 +933,9 @@ osg::Node* createModel(osg::ref_ptr& image_3d, osg::ref_ptrsetTextureUnit(0); texgenNode_0->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); - texgenNode_0->getTexGen()->setPlane(osg::TexGen::S, osg::Vec4(xMultiplier,0.0f,0.0f,0.5f)); - texgenNode_0->getTexGen()->setPlane(osg::TexGen::T, osg::Vec4(0.0f,yMultiplier,0.0f,0.5f)); - texgenNode_0->getTexGen()->setPlane(osg::TexGen::R, osg::Vec4(0.0f,0.0f,zMultiplier,0.5f)); + texgenNode_0->getTexGen()->setPlane(osg::TexGen::S, osg::Plane(xMultiplier,0.0f,0.0f,0.5f)); + texgenNode_0->getTexGen()->setPlane(osg::TexGen::T, osg::Plane(0.0f,yMultiplier,0.0f,0.5f)); + texgenNode_0->getTexGen()->setPlane(osg::TexGen::R, osg::Plane(0.0f,0.0f,zMultiplier,0.5f)); if (two_pass) { diff --git a/include/osg/Plane b/include/osg/Plane index 4acaf2320..a9e17ccef 100644 --- a/include/osg/Plane +++ b/include/osg/Plane @@ -23,6 +23,8 @@ #include +#define OSG_USE_DOUBLE_PLANE 1 + namespace osg { /** A plane class. It can be used to represent an infinite plane.*/ @@ -31,91 +33,137 @@ class OSG_EXPORT Plane public: - inline Plane():_fv(0.0f,0.0f,0.0f,0.0f) { _lowerBBCorner = 0; _upperBBCorner = 0; } - inline Plane(const Plane& pl):_fv(pl._fv) { calculateUpperLowerBBCorners(); } - inline Plane(float a,float b,float c,float d):_fv(a,b,c,d) { calculateUpperLowerBBCorners(); } - inline Plane(const Vec4& vec):_fv(vec) { calculateUpperLowerBBCorners(); } - inline Plane(const Vec3& norm,float d):_fv(norm[0],norm[1],norm[2],d) { calculateUpperLowerBBCorners(); } - inline Plane(const Vec3& v1, const Vec3& v2, const Vec3& v3) { set(v1,v2,v3); } - inline Plane(const Vec3& norm, const Vec3& point) { set(norm,point); } +#ifdef OSG_USE_DOUBLE_PLANE + /** Type of Plane class.*/ + typedef double value_type; + typedef Vec3d Vec3_type; + typedef Vec4d Vec4_type; +#else + /** Type of Plane class.*/ + typedef float value_type; + typedef Vec3f Vec3_type; + typedef Vec4f Vec4_type; +#endif + + /** Number of vector components. */ + enum { num_components = 3 }; + + + inline Plane() { _fv[0]=0.0; _fv[1]=0.0; _fv[2]=0.0; _fv[3]=0.0; _lowerBBCorner = 0; _upperBBCorner = 0; } + inline Plane(const Plane& pl) { set(pl); } + inline Plane(value_type a,value_type b,value_type c,value_type d) { set(a,b,c,d); } + + inline Plane(const Vec4f& vec) { set(vec); } + inline Plane(const Vec4d& vec) { set(vec); } + + inline Plane(const Vec3_type& norm,value_type d) { set(norm,d); } + + inline Plane(const Vec3_type& v1, const Vec3_type& v2, const Vec3_type& v3) { set(v1,v2,v3); } + + inline Plane(const Vec3_type& norm, const Vec3_type& point) { set(norm,point); } inline Plane& operator = (const Plane& pl) { if (&pl==this) return *this; - _fv = pl._fv; - _lowerBBCorner = pl._lowerBBCorner; - _upperBBCorner = pl._upperBBCorner; + set(pl); return *this; } - inline void set(const Plane& pl) { _fv = pl._fv; calculateUpperLowerBBCorners(); } - inline void set(float a,float b,float c,float d) { _fv.set(a,b,c,d); calculateUpperLowerBBCorners(); } - inline void set(const Vec4& vec) { _fv = vec; calculateUpperLowerBBCorners(); } - inline void set(const Vec3& norm,float d) { _fv.set(norm[0],norm[1],norm[2],d); calculateUpperLowerBBCorners(); } - inline void set(const Vec3& v1, const Vec3& v2, const Vec3& v3) + inline void set(const Plane& pl) { _fv[0]=pl._fv[0]; _fv[1]=pl._fv[1]; _fv[2]=pl._fv[2]; _fv[3]=pl._fv[3]; calculateUpperLowerBBCorners(); } + inline void set(value_type a, value_type b, value_type c, value_type d) { _fv[0]=a; _fv[1]=b; _fv[2]=c; _fv[3]=d; calculateUpperLowerBBCorners(); } + + inline void set(const Vec4f& vec) { set(vec[0],vec[1],vec[2],vec[3]); } + inline void set(const Vec4d& vec) { set(vec[0],vec[1],vec[2],vec[3]); } + + inline void set(const Vec3_type& norm, double d) { set(norm[0],norm[1],norm[2],d); } + + inline void set(const Vec3_type& v1, const Vec3_type& v2, const Vec3_type& v3) { - osg::Vec3 norm = (v2-v1)^(v3-v2); - float length = norm.length(); + Vec3_type norm = (v2-v1)^(v3-v2); + value_type length = norm.length(); if (length>1e-6) norm/= length; - else norm.set(0.0f,0.0f,0.0f); - _fv.set(norm[0],norm[1],norm[2],-(v1*norm)); - calculateUpperLowerBBCorners(); + else norm.set(0.0,0.0,0.0); + set(norm[0],norm[1],norm[2],-(v1*norm)); } - inline void set(const Vec3& norm, const Vec3& point) + inline void set(const Vec3_type& norm, const Vec3_type& point) { - float d = -norm[0]*point[0] - norm[1]*point[1] - norm[2]*point[2]; - _fv.set(norm[0],norm[1],norm[2],d); - calculateUpperLowerBBCorners(); + value_type d = -norm[0]*point[0] - norm[1]*point[1] - norm[2]*point[2]; + set(norm[0],norm[1],norm[2],d); } /** flip/reverse the orientation of the plane.*/ inline void flip() { - _fv = -_fv; + _fv[0] = -_fv[0]; + _fv[1] = -_fv[1]; + _fv[2] = -_fv[2]; + _fv[3] = -_fv[3]; calculateUpperLowerBBCorners(); } inline void makeUnitLength() { - float length = sqrtf(_fv[0]*_fv[0] + _fv[1]*_fv[1]+ _fv[2]*_fv[2]); - _fv /= length; + value_type inv_length = 1.0 / sqrt(_fv[0]*_fv[0] + _fv[1]*_fv[1]+ _fv[2]*_fv[2]); + _fv[0] *= inv_length; + _fv[1] *= inv_length; + _fv[2] *= inv_length; + _fv[3] *= inv_length; } /** calculate the upper and lower bounding box corners to be used * in the intersect(BoundingBox&) method for speeding calculations.*/ inline void calculateUpperLowerBBCorners() { - _upperBBCorner = (_fv.x()>=0.0f?1:0) | - (_fv.y()>=0.0f?2:0) | - (_fv.z()>=0.0f?4:0); + _upperBBCorner = (_fv[0]>=0.0?1:0) | + (_fv[1]>=0.0?2:0) | + (_fv[2]>=0.0?4:0); _lowerBBCorner = (~_upperBBCorner)&7; } - inline bool valid() const { return _fv.valid(); } + inline bool valid() const { return !isNaN(); } + inline bool isNaN() const { return osg::isNaN(_fv[0]) || osg::isNaN(_fv[1]) || osg::isNaN(_fv[2]) || osg::isNaN(_fv[3]); } - inline bool operator == (const Plane& plane) const { return _fv==plane._fv; } - inline bool operator != (const Plane& plane) const { return _fv!=plane._fv; } - inline bool operator < (const Plane& plane) const { return _fvplane._fv[0]) return false; + else if (_fv[1]plane._fv[1]) return false; + else if (_fv[2]plane._fv[2]) return false; + else return (_fv[3]read(&c, CHARSIZE); @@ -387,11 +382,24 @@ osg::Vec4d DataInputStream::readVec4d(){ osg::Plane DataInputStream::readPlane(){ osg::Plane v; - v[0]=readFloat(); - v[1]=readFloat(); - v[2]=readFloat(); - v[3]=readFloat(); + if (getVersion() <= VERSION_0018) + { + v[0]=readFloat(); + v[1]=readFloat(); + v[2]=readFloat(); + v[3]=readFloat(); + } + else + { + // assume double for planes even if Plane::value_type is float + // to ensure that the .ive format does vary. + v[0]=readDouble(); + v[1]=readDouble(); + v[2]=readDouble(); + v[3]=readDouble(); + } + if (_verboseOutput) std::cout<<"read/writePlane() ["<computeLocalUpVector(_startPoint.x(), _startPoint.y(), _startPoint.z()); + osg::Vec3d start_upVector = em->computeLocalUpVector(_startPoint.x(), _startPoint.y(), _startPoint.z()); + osg::Vec3d end_upVector = em->computeLocalUpVector(_endPoint.x(), _endPoint.y(), _endPoint.z()); - double latitude, longitude, height; - em->convertXYZToLatLongHeight(_startPoint.x(), _startPoint.y(), _startPoint.z(), latitude, longitude, height); + double start_latitude, start_longitude, start_height; + em->convertXYZToLatLongHeight(_startPoint.x(), _startPoint.y(), _startPoint.z(), + start_latitude, start_longitude, start_height); - osg::notify(osg::NOTICE)<<"lat = "<getBound() ) ) return; if ( !_polytope.contains( drawable->getBound() ) ) return; + osg::notify(osg::NOTICE)<<"Succed PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"<