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
This commit is contained in:
Robert Osfield
2006-11-28 16:00:52 +00:00
parent 5e1c5cd556
commit 345810ef22
14 changed files with 262 additions and 135 deletions

View File

@@ -11,6 +11,7 @@
#include <osgSim/LineOfSight>
#include <osgSim/HeightAboveTerrain>
#include <osgSim/ElevationSlice>
#include <iostream>
@@ -42,7 +43,6 @@ int main(int argc, char **argv)
}
std::cout<<"Intersection "<<std::endl;
osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(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"<<std::endl;
los.computeIntersections(scene.get());
osg::Timer_t endTick = osg::Timer::instance()->tick();
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
#if 1
for(unsigned int i=0; i<los.getNumLOS(); i++)
{
const osgSim::LineOfSight::Intersections& intersections = los.getIntersections(i);
for(osgSim::LineOfSight::Intersections::const_iterator itr = intersections.begin();
itr != intersections.end();
++itr)
std::cout<<"Computing LineOfSight"<<std::endl;
osg::Timer_t startTick = osg::Timer::instance()->tick();
los.computeIntersections(scene.get());
osg::Timer_t endTick = osg::Timer::instance()->tick();
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
for(unsigned int i=0; i<los.getNumLOS(); i++)
{
std::cout<<" point "<<*itr<<std::endl;
const osgSim::LineOfSight::Intersections& intersections = los.getIntersections(i);
for(osgSim::LineOfSight::Intersections::const_iterator itr = intersections.begin();
itr != intersections.end();
++itr)
{
std::cout<<" point "<<*itr<<std::endl;
}
}
}
{
// now do a second traversal to test performance of cache.
osg::Timer_t startTick = osg::Timer::instance()->tick();
std::cout<<"Computing HeightAboveTerrain"<<std::endl;
hat.computeIntersections(scene.get());
osg::Timer_t endTick = osg::Timer::instance()->tick();
for(unsigned int i=0; i<hat.getNumPoints(); i++)
{
std::cout<<" point = "<<hat.getPoint(i)<<" hat = "<<hat.getHeightAboveTerrain(i)<<std::endl;
}
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
}
#endif
// now do a second traversal to test performance of cache.
startTick = osg::Timer::instance()->tick();
std::cout<<"Computing HeightAboveTerrain"<<std::endl;
hat.computeIntersections(scene.get());
for(unsigned int i=0; i<hat.getNumPoints(); i++)
{
std::cout<<" point = "<<hat.getPoint(i)<<" hat = "<<hat.getHeightAboveTerrain(i)<<std::endl;
// now do a second traversal to test performance of cache.
osg::Timer_t startTick = osg::Timer::instance()->tick();
std::cout<<"Computing ElevationSlice"<<std::endl;
osgSim::ElevationSlice es;
es.setDatabaseCacheReadCallback(los.getDatabaseCacheReadCallback());
es.setStartPoint(bs.center()+osg::Vec3d(bs.radius(),0.0,0.0) );
es.setEndPoint(bs.center()+osg::Vec3d(0.0,bs.radius(),0.0) );
es.computeIntersections(scene.get());
osg::Timer_t endTick = osg::Timer::instance()->tick();
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
}
endTick = osg::Timer::instance()->tick();
std::cout<<"Completed in "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
}
else if (useIntersectorGroup)
{

View File

@@ -63,7 +63,7 @@ osg::StateSet* create1DTextureStateToDecorate(osg::Node* loadedModel)
osg::TexGen* texgen = new osg::TexGen;
texgen->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;

View File

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

View File

@@ -933,9 +933,9 @@ osg::Node* createModel(osg::ref_ptr<osg::Image>& image_3d, osg::ref_ptr<osg::Ima
osg::TexGenNode* texgenNode_0 = new osg::TexGenNode;
texgenNode_0->setTextureUnit(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)
{

View File

@@ -23,6 +23,8 @@
#include <vector>
#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 _fv<plane._fv; }
inline bool operator == (const Plane& plane) const { return _fv[0]==plane._fv[0] && _fv[1]==plane._fv[1] && _fv[2]==plane._fv[2] && _fv[3]==plane._fv[3]; }
inline float* ptr() { return _fv.ptr(); }
inline const float* ptr() const { return _fv.ptr(); }
inline bool operator != (const Plane& plane) const { return _fv[0]!=plane._fv[0] || _fv[1]!=plane._fv[1] || _fv[2]!=plane._fv[2] || _fv[3]!=plane._fv[3]; }
inline Vec4& asVec4() { return _fv; }
inline const Vec4& asVec4() const { return _fv; }
inline float& operator [] (unsigned int i) { return _fv[i]; }
inline float operator [] (unsigned int i) const { return _fv[i]; }
inline bool operator < (const Plane& plane) const
{
if (_fv[0]<plane._fv[0]) return true;
else if (_fv[0]>plane._fv[0]) return false;
else if (_fv[1]<plane._fv[1]) return true;
else if (_fv[1]>plane._fv[1]) return false;
else if (_fv[2]<plane._fv[2]) return true;
else if (_fv[2]>plane._fv[2]) return false;
else return (_fv[3]<plane._fv[3]);
}
inline osg::Vec3 getNormal() const { return osg::Vec3(_fv[0],_fv[1],_fv[2]); }
inline value_type* ptr() { return _fv; }
inline const value_type* ptr() const { return _fv; }
inline Vec4_type asVec4() const { return Vec4(_fv[0],_fv[1],_fv[2],_fv[3]); }
inline value_type& operator [] (unsigned int i) { return _fv[i]; }
inline value_type operator [] (unsigned int i) const { return _fv[i]; }
inline Vec3_type getNormal() const { return Vec3_type(_fv[0],_fv[1],_fv[2]); }
/** calculate the distance between a point and the plane.*/
inline float distance(const osg::Vec3& v) const
inline float distance(const osg::Vec3f& v) const
{
return _fv[0]*v.x()+
_fv[1]*v.y()+
_fv[2]*v.z()+
_fv[3];
}
inline float distance(const osg::Vec3d& v) const
{
return _fv[0]*v.x()+
_fv[1]*v.y()+
@@ -124,7 +172,15 @@ class OSG_EXPORT Plane
}
/** calculate the dot product of the plane normal and a point.*/
inline float dotProductNormal(const osg::Vec3& v) const
inline float dotProductNormal(const osg::Vec3f& v) const
{
return _fv[0]*v.x()+
_fv[1]*v.y()+
_fv[2]*v.z();
}
/** calculate the dot product of the plane normal and a point.*/
inline float dotProductNormal(const osg::Vec3d& v) const
{
return _fv[0]*v.x()+
_fv[1]*v.y()+
@@ -210,14 +266,16 @@ class OSG_EXPORT Plane
inline void transformProvidingInverse(const osg::Matrix& matrix)
{
// note pre multiplications, which effectively transposes matrix.
_fv = matrix * _fv;
Vec4_type vec(_fv[0],_fv[1],_fv[2],_fv[3]);
vec = matrix * vec;
set(vec);
makeUnitLength();
calculateUpperLowerBBCorners();
}
protected:
Vec4 _fv;
/** Vec member varaible. */
value_type _fv[4];
// variables cached to optimize calcs against bounding boxes.
unsigned int _upperBBCorner;

View File

@@ -78,25 +78,24 @@ void TexGen::setPlanesFromMatrix(const Matrixd& matrix)
void TexGen::apply(State&) const
{
if (_mode == OBJECT_LINEAR)
if (_mode == OBJECT_LINEAR || _mode == EYE_LINEAR)
{
glTexGenfv(GL_S, GL_OBJECT_PLANE, _plane_s.ptr());
glTexGenfv(GL_T, GL_OBJECT_PLANE, _plane_t.ptr());
glTexGenfv(GL_R, GL_OBJECT_PLANE, _plane_r.ptr());
glTexGenfv(GL_Q, GL_OBJECT_PLANE, _plane_q.ptr());
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, _mode );
glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, _mode );
}
else if (_mode == EYE_LINEAR)
{
glTexGenfv(GL_S, GL_EYE_PLANE, _plane_s.ptr());
glTexGenfv(GL_T, GL_EYE_PLANE, _plane_t.ptr());
glTexGenfv(GL_R, GL_EYE_PLANE, _plane_r.ptr());
glTexGenfv(GL_Q, GL_EYE_PLANE, _plane_q.ptr());
GLenum glmode = _mode == OBJECT_LINEAR ? GL_OBJECT_PLANE : GL_EYE_PLANE;
if (sizeof(_plane_s[0])==sizeof(GLfloat))
{
glTexGenfv(GL_S, glmode, (const GLfloat*)_plane_s.ptr());
glTexGenfv(GL_T, glmode, (const GLfloat*)_plane_t.ptr());
glTexGenfv(GL_R, glmode, (const GLfloat*)_plane_r.ptr());
glTexGenfv(GL_Q, glmode, (const GLfloat*)_plane_q.ptr());
}
else
{
glTexGendv(GL_S, glmode, (const GLdouble*)_plane_s.ptr());
glTexGendv(GL_T, glmode, (const GLdouble*)_plane_t.ptr());
glTexGendv(GL_R, glmode, (const GLdouble*)_plane_r.ptr());
glTexGendv(GL_Q, glmode, (const GLdouble*)_plane_q.ptr());
}
glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, _mode );
glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, _mode );
@@ -120,8 +119,6 @@ void TexGen::apply(State&) const
}
else // SPHERE_MAP
{
// We ignore the planes if we are not in OBJECT_ or EYE_LINEAR mode.
// Also don't set the mode of GL_R & GL_Q as these will generate
// GL_INVALID_ENUM (See OpenGL Refrence Guide, glTexGEn.)

View File

@@ -157,11 +157,6 @@ bool DataInputStream::readBool(){
return c!=0;
}
unsigned int DataInputStream::getVersion()
{
return( _version );
}
char DataInputStream::readChar(){
char c;
_istream->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() ["<<v<<"]"<<std::endl;
return v;

View File

@@ -40,7 +40,7 @@ public:
void setOptions(const osgDB::ReaderWriter::Options* options);
const osgDB::ReaderWriter::Options* getOptions() const { return _options.get(); }
unsigned int getVersion();
inline unsigned int getVersion() const { return _version; }
bool readBool();
char readChar();
unsigned char readUChar();

View File

@@ -272,10 +272,10 @@ void DataOutputStream::writeVec4d(const osg::Vec4d& v){
void DataOutputStream::writePlane(const osg::Plane& v)
{
writeFloat(v[0]);
writeFloat(v[1]);
writeFloat(v[2]);
writeFloat(v[3]);
writeDouble(v[0]);
writeDouble(v[1]);
writeDouble(v[2]);
writeDouble(v[3]);
if (_verboseOutput) std::cout<<"read/writePlane() ["<<v<<"]"<<std::endl;
}

View File

@@ -27,8 +27,9 @@
#define VERSION_0016 16
#define VERSION_0017 17
#define VERSION_0018 18
#define VERSION_0019 19
#define VERSION VERSION_0018
#define VERSION VERSION_0019
/* The BYTE_SEX tag is used to check the endian
of the IVE file being read in. The IVE format

View File

@@ -44,7 +44,7 @@ bool TexGen_readLocalData(Object& obj, Input& fr)
iteratorAdvanced = true;
}
Vec4 plane;
osg::Plane plane;
if (fr[0].matchWord("plane_s"))
{
if (fr[1].getFloat(plane[0]) && fr[2].getFloat(plane[1]) &&

View File

@@ -35,18 +35,54 @@ void ElevationSlice::computeIntersections(osg::Node* scene)
if (em)
{
osg::Vec3d upVector = em->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 = "<<latitude<<" longitude = "<<longitude<<" height = "<<height<<std::endl;
osg::notify(osg::NOTICE)<<"start_lat = "<<start_latitude<<" start_longitude = "<<start_longitude<<" start_height = "<<start_height<<std::endl;
double end_latitude, end_longitude, end_height;
em->convertXYZToLatLongHeight(_endPoint.x(), _endPoint.y(), _endPoint.z(),
end_latitude, end_longitude, end_height);
osg::notify(osg::NOTICE)<<"end_lat = "<<end_latitude<<" end_longitude = "<<end_longitude<<" end_height = "<<end_height<<std::endl;
// set up the main intersection plane
osg::Vec3d planeNormal = (_endPoint - _startPoint) ^ start_upVector;
planeNormal.normalize();
plane.set( planeNormal, _startPoint );
// set up the start cut off plane
osg::Vec3d startPlaneNormal = start_upVector ^ planeNormal;
startPlaneNormal.normalize();
boundingPolytope.add( osg::Plane(startPlaneNormal, _startPoint) );
// set up the end cut off plane
osg::Vec3d endPlaneNormal = planeNormal ^ end_upVector;
endPlaneNormal.normalize();
boundingPolytope.add( osg::Plane(endPlaneNormal, _endPoint) );
}
else
{
osg::Vec3d upVector (0.0, 0.0, 1.0);
// set up the main intersection plane
osg::Vec3d planeNormal = (_endPoint - _startPoint) ^ upVector;
planeNormal.normalize();
plane.set( planeNormal, _startPoint );
// set up the start cut off plane
osg::Vec3d startPlaneNormal = upVector ^ planeNormal;
startPlaneNormal.normalize();
boundingPolytope.add( osg::Plane(startPlaneNormal, _startPoint) );
// set up the end cut off plane
osg::Vec3d endPlaneNormal = planeNormal ^ upVector;
endPlaneNormal.normalize();
boundingPolytope.add( osg::Plane(endPlaneNormal, _endPoint) );
}
osg::ref_ptr<osgUtil::PlaneIntersector> intersector = new osgUtil::PlaneIntersector(plane, boundingPolytope);

View File

@@ -69,21 +69,21 @@ struct FadeTextPolytopeData : public FadeTextData, public osg::Polytope
void buildPolytope()
{
osg::Vec3 edge01 = _vertices[1] - _vertices[0];
osg::Vec3 edge12 = _vertices[2] - _vertices[1];
osg::Vec3 edge23 = _vertices[3] - _vertices[2];
osg::Vec3 edge30 = _vertices[0] - _vertices[3];
osg::Vec3d edge01 = _vertices[1] - _vertices[0];
osg::Vec3d edge12 = _vertices[2] - _vertices[1];
osg::Vec3d edge23 = _vertices[3] - _vertices[2];
osg::Vec3d edge30 = _vertices[0] - _vertices[3];
osg::Vec3 normalFrontFace = edge01 ^ edge12;
osg::Vec3d normalFrontFace = edge01 ^ edge12;
bool needToFlip = normalFrontFace.z()>0.0f;
normalFrontFace.normalize();
add(osg::Plane(normalFrontFace, _vertices[0]));
add(osg::Plane( osg::Vec3(0.0f,0.0f,0.0f), _vertices[0], _vertices[1]));
add(osg::Plane( osg::Vec3(0.0f,0.0f,0.0f), _vertices[1], _vertices[2]));
add(osg::Plane( osg::Vec3(0.0f,0.0f,0.0f), _vertices[2], _vertices[3]));
add(osg::Plane( osg::Vec3(0.0f,0.0f,0.0f), _vertices[3], _vertices[0]));
add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[0], _vertices[1]));
add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[1], _vertices[2]));
add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[2], _vertices[3]));
add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[3], _vertices[0]));
#if 0
osg::notify(osg::NOTICE)<<" normalFrontFace = "<<normalFrontFace<<std::endl;

View File

@@ -696,7 +696,7 @@ Intersector* PlaneIntersector::clone(osgUtil::IntersectionVisitor& iv)
bool PlaneIntersector::enter(const osg::Node& node)
{
return !node.isCullingActive() ||
( _plane.intersect(node.getBound()) && _polytope.contains(node.getBound()) );
( _plane.intersect(node.getBound())==0 && _polytope.contains(node.getBound()) );
}
@@ -708,9 +708,13 @@ void PlaneIntersector::leave()
void PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)
{
osg::notify(osg::NOTICE)<<"PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"<<std::endl;
if ( !_plane.intersect( drawable->getBound() ) ) return;
if ( !_polytope.contains( drawable->getBound() ) ) return;
osg::notify(osg::NOTICE)<<"Succed PlaneIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable)"<<std::endl;
Intersection hit;
hit.nodePath = iv.getNodePath();
hit.drawable = drawable;