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)"<