Implemented intial KdTree triangle intersection code, but without culling implemented

This commit is contained in:
Robert Osfield 2008-07-07 13:21:37 +00:00
parent e8487b8830
commit d05236bfb4
4 changed files with 424 additions and 16 deletions

View File

@ -72,7 +72,7 @@ class OSG_EXPORT KdTree : public osg::Shape
typedef std::multiset<LineSegmentIntersection> LineSegmentIntersections;
/** compute the intersection of a line segment and the kdtree, return true if an intersection has been found.*/
virtual bool intersect(const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections);
virtual bool intersect(const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections) const;
@ -132,8 +132,8 @@ class OSG_EXPORT KdTree : public osg::Shape
};
typedef std::vector< unsigned int > AxisStack;
typedef std::vector< KdNode > KDNodeList;
typedef std::vector< KdLeaf > KDLeafList;
typedef std::vector< KdNode > KdNodeList;
typedef std::vector< KdLeaf > KdLeafList;
/// note, leafNum is negative to distinguish from nodeNum
int addLeaf(const KdLeaf& leaf) { int num = _kdLeaves.size(); _kdLeaves.push_back(leaf); return -(num+1); }
@ -198,6 +198,7 @@ class OSG_EXPORT KdTree : public osg::Shape
int divide(BuildOptions& options, osg::BoundingBox& bb, int nodeIndex, unsigned int level);
bool intersect(const KdLeaf& leaf, const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections) const;
typedef std::vector< osg::BoundingBox > BoundingBoxList;
typedef std::vector< Triangle > TriangleList;
@ -208,8 +209,8 @@ class OSG_EXPORT KdTree : public osg::Shape
osg::BoundingBox _bb;
AxisStack _axisStack;
KDNodeList _kdNodes;
KDLeafList _kdLeaves;
KdNodeList _kdNodes;
KdLeafList _kdLeaves;
osg::ref_ptr<osg::Vec3Array> _vertices;

View File

@ -13,9 +13,10 @@
#include <osg/KdTree>
#include <osg/Geode>
#include <osg/io_utils>
#include <osg/TriangleIndexFunctor>
#include <osg/io_utils>
using namespace osg;
//#define VERBOSE_OUTPUT
@ -291,16 +292,158 @@ int KdTree::divide(BuildOptions& options, osg::BoundingBox& bb, int nodeIndex, u
getNode(nodeNum).first = leftChildIndex;
getNode(nodeNum).second = rightChildIndex;
return nodeNum;
}
}
bool KdTree::intersect(const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections)
bool KdTree::intersect(const KdLeaf& leaf, const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections) const
{
osg::notify(osg::NOTICE)<<"KdTree::intersect("<<start<<","<<end<<")"<<std::endl;
return false;
osg::Vec3 _s = start;
osg::Vec3 _d = end - start;
float _length = _d.length();
_d /= _length;
//osg::notify(osg::NOTICE)<<"KdTree::intersect("<<&leaf<<")"<<std::endl;
bool intersects = false;
int iend = leaf.first + leaf.second;
for(int i=leaf.first; i<iend; ++i)
{
const Triangle& tri = _triangles[_primitiveIndices[i]];
const osg::Vec3& v1 = (*_vertices)[tri._p1];
const osg::Vec3& v2 = (*_vertices)[tri._p2];
const osg::Vec3& v3 = (*_vertices)[tri._p3];
// osg::notify(osg::NOTICE)<<" tri("<<tri._p1<<","<<tri._p2<<","<<tri._p3<<")"<<std::endl;
if (v1==v2 || v2==v3 || v1==v3) continue;
osg::Vec3 v12 = v2-v1;
osg::Vec3 n12 = v12^_d;
float ds12 = (_s-v1)*n12;
float d312 = (v3-v1)*n12;
if (d312>=0.0f)
{
if (ds12<0.0f) continue;
if (ds12>d312) continue;
}
else // d312 < 0
{
if (ds12>0.0f) continue;
if (ds12<d312) continue;
}
osg::Vec3 v23 = v3-v2;
osg::Vec3 n23 = v23^_d;
float ds23 = (_s-v2)*n23;
float d123 = (v1-v2)*n23;
if (d123>=0.0f)
{
if (ds23<0.0f) continue;
if (ds23>d123) continue;
}
else // d123 < 0
{
if (ds23>0.0f) continue;
if (ds23<d123) continue;
}
osg::Vec3 v31 = v1-v3;
osg::Vec3 n31 = v31^_d;
float ds31 = (_s-v3)*n31;
float d231 = (v2-v3)*n31;
if (d231>=0.0f)
{
if (ds31<0.0f) continue;
if (ds31>d231) continue;
}
else // d231 < 0
{
if (ds31>0.0f) continue;
if (ds31<d231) continue;
}
float r3;
if (ds12==0.0f) r3=0.0f;
else if (d312!=0.0f) r3 = ds12/d312;
else continue; // the triangle and the line must be parallel intersection.
float r1;
if (ds23==0.0f) r1=0.0f;
else if (d123!=0.0f) r1 = ds23/d123;
else continue; // the triangle and the line must be parallel intersection.
float r2;
if (ds31==0.0f) r2=0.0f;
else if (d231!=0.0f) r2 = ds31/d231;
else continue; // the triangle and the line must be parallel intersection.
float total_r = (r1+r2+r3);
if (total_r!=1.0f)
{
if (total_r==0.0f) continue; // the triangle and the line must be parallel intersection.
float inv_total_r = 1.0f/total_r;
r1 *= inv_total_r;
r2 *= inv_total_r;
r3 *= inv_total_r;
}
osg::Vec3 in = v1*r1+v2*r2+v3*r3;
if (!in.valid())
{
osg::notify(osg::WARN)<<"Warning:: Picked up error in TriangleIntersect"<<std::endl;
osg::notify(osg::WARN)<<" ("<<v1<<",\t"<<v2<<",\t"<<v3<<")"<<std::endl;
osg::notify(osg::WARN)<<" ("<<r1<<",\t"<<r2<<",\t"<<r3<<")"<<std::endl;
continue;
}
float d = (in-_s)*_d;
if (d<0.0f) continue;
if (d>_length) continue;
osg::Vec3 normal = v12^v23;
normal.normalize();
float r = d/_length;
LineSegmentIntersection intersection;
intersection.ratio = r;
intersection.primitiveIndex = _primitiveIndices[i];
intersection.intersectionPoint = in;
intersection.intersectionNormal = normal;
intersection.indexList.push_back(tri._p1);
intersection.indexList.push_back(tri._p2);
intersection.indexList.push_back(tri._p3);
intersection.ratioList.push_back(r1);
intersection.ratioList.push_back(r2);
intersection.ratioList.push_back(r3);
intersections.insert(intersection);
osg::notify(osg::NOTICE)<<" got intersection ("<<in<<") ratio="<<r<<std::endl;
intersects = true;
}
return intersects;
}
bool KdTree::intersect(const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections) const
{
// osg::notify(osg::NOTICE)<<"KdTree::intersect("<<start<<","<<end<<")"<<std::endl;
bool intersects = false;
for(KdLeafList::const_iterator itr = _kdLeaves.begin();
itr != _kdLeaves.end();
++itr)
{
if (intersect(*itr, start, end, intersections)) intersects = true;
}
return intersects;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -233,7 +233,7 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
double i_sampleFactor = 1.0;
double j_sampleFactor = 1.0;
osg::notify(osg::NOTICE)<<"Sample ratio="<<sampleRatio<<std::endl;
// osg::notify(osg::NOTICE)<<"Sample ratio="<<sampleRatio<<std::endl;
if (sampleRatio!=1.0f)
{
@ -652,12 +652,12 @@ void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3
{
osg::Timer_t before = osg::Timer::instance()->tick();
//osg::Timer_t before = osg::Timer::instance()->tick();
//osg::notify(osg::NOTICE)<<"osgTerrain::GeometryTechnique::build kd tree"<<std::endl;
osg::ref_ptr<osg::KdTreeBuilder> builder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
buffer._geode->accept(*builder);
osg::Timer_t after = osg::Timer::instance()->tick();
osg::notify(osg::NOTICE)<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
//osg::Timer_t after = osg::Timer::instance()->tick();
//osg::notify(osg::NOTICE)<<"KdTree build time "<<osg::Timer::instance()->delta_m(before, after)<<std::endl;
}
}

View File

@ -0,0 +1,264 @@
// ***************************************************************************
//
// Generated automatically by genwrapper.
// Please DO NOT EDIT this file!
//
// ***************************************************************************
#include <osgIntrospection/ReflectionMacros>
#include <osgIntrospection/TypedMethodInfo>
#include <osgIntrospection/StaticMethodInfo>
#include <osgIntrospection/Attributes>
#include <osg/BoundingBox>
#include <osg/CopyOp>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/KdTree>
#include <osg/Object>
#include <osg/Shape>
#include <osg/Vec3>
// Must undefine IN and OUT macros defined in Windows headers
#ifdef IN
#undef IN
#endif
#ifdef OUT
#undef OUT
#endif
TYPE_NAME_ALIAS(std::multiset< osg::KdTree::LineSegmentIntersection >, osg::KdTree::LineSegmentIntersections)
TYPE_NAME_ALIAS(int, osg::KdTree::value_type)
TYPE_NAME_ALIAS(std::vector< osg::KdTree::value_type >, osg::KdTree::Indices)
TYPE_NAME_ALIAS(std::vector< unsigned int >, osg::KdTree::AxisStack)
TYPE_NAME_ALIAS(std::vector< osg::KdTree::KdNode >, osg::KdTree::KdNodeList)
TYPE_NAME_ALIAS(std::vector< osg::KdTree::KdLeaf >, osg::KdTree::KdLeafList)
TYPE_NAME_ALIAS(std::vector< osg::BoundingBox >, osg::KdTree::BoundingBoxList)
TYPE_NAME_ALIAS(std::vector< osg::KdTree::Triangle >, osg::KdTree::TriangleList)
TYPE_NAME_ALIAS(std::vector< osg::Vec3 >, osg::KdTree::CenterList)
BEGIN_OBJECT_REFLECTOR(osg::KdTree)
I_DeclaringFile("osg/KdTree");
I_BaseType(osg::Shape);
I_Constructor0(____KdTree,
"",
"");
I_ConstructorWithDefaults2(IN, const osg::KdTree &, rhs, , IN, const osg::CopyOp &, copyop, osg::CopyOp::SHALLOW_COPY,
____KdTree__C5_KdTree_R1__C5_osg_CopyOp_R1,
"",
"");
I_Method0(osg::Object *, cloneType,
Properties::VIRTUAL,
__osg_Object_P1__cloneType,
"Clone the type of an attribute, with Object* return type. ",
"Must be defined by derived classes. ");
I_Method1(osg::Object *, clone, IN, const osg::CopyOp &, copyop,
Properties::VIRTUAL,
__osg_Object_P1__clone__C5_osg_CopyOp_R1,
"Clone an attribute, with Object* return type. ",
"Must be defined by derived classes. ");
I_Method1(bool, isSameKindAs, IN, const osg::Object *, obj,
Properties::VIRTUAL,
__bool__isSameKindAs__C5_osg_Object_P1,
"return true if this and obj are of the same kind of object. ",
"");
I_Method0(const char *, libraryName,
Properties::VIRTUAL,
__C5_char_P1__libraryName,
"return the name of the attribute's library. ",
"");
I_Method0(const char *, className,
Properties::VIRTUAL,
__C5_char_P1__className,
"return the name of the attribute's class type. ",
"");
I_Method1(void, accept, IN, osg::ShapeVisitor &, sv,
Properties::VIRTUAL,
__void__accept__osg_ShapeVisitor_R1,
"accept a non const shape visitor which can be used on non const shape objects. ",
"Must be defined by derived classes. ");
I_Method1(void, accept, IN, osg::ConstShapeVisitor &, csv,
Properties::VIRTUAL,
__void__accept__osg_ConstShapeVisitor_R1,
"accept a const shape visitor which can be used on const shape objects. ",
"Must be defined by derived classes. ");
I_Method2(bool, build, IN, osg::KdTree::BuildOptions &, buildOptions, IN, osg::Geometry *, geometry,
Properties::VIRTUAL,
__bool__build__BuildOptions_R1__osg_Geometry_P1,
"Build the kdtree from the specified source geometry object. ",
"retun true on success. ");
I_Method3(bool, intersect, IN, const osg::Vec3 &, start, IN, const osg::Vec3 &, end, IN, osg::KdTree::LineSegmentIntersections &, intersections,
Properties::VIRTUAL,
__bool__intersect__C5_osg_Vec3_R1__C5_osg_Vec3_R1__LineSegmentIntersections_R1,
"compute the intersection of a line segment and the kdtree, return true if an intersection has been found. ",
"");
I_Method1(int, addLeaf, IN, const osg::KdTree::KdLeaf &, leaf,
Properties::NON_VIRTUAL,
__int__addLeaf__C5_KdLeaf_R1,
"note, leafNum is negative to distinguish from nodeNum ",
"");
I_Method2(int, replaceLeaf, IN, int, leafNum, IN, const osg::KdTree::KdLeaf &, leaf,
Properties::NON_VIRTUAL,
__int__replaceLeaf__int__C5_KdLeaf_R1,
"",
"");
I_Method1(osg::KdTree::KdLeaf &, getLeaf, IN, int, leafNum,
Properties::NON_VIRTUAL,
__KdLeaf_R1__getLeaf__int,
"note, leafNum is negative to distinguish from nodeNum ",
"");
I_Method1(int, addNode, IN, const osg::KdTree::KdNode &, node,
Properties::NON_VIRTUAL,
__int__addNode__C5_KdNode_R1,
"",
"");
I_Method1(osg::KdTree::KdNode &, getNode, IN, int, nodeNum,
Properties::NON_VIRTUAL,
__KdNode_R1__getNode__int,
"note, nodeNum is positive to distinguish from leftNum ",
"");
I_Method1(osg::BoundingBox &, getBounindingBox, IN, int, nodeNum,
Properties::NON_VIRTUAL,
__osg_BoundingBox_R1__getBounindingBox__int,
"",
"");
I_Method1(void, computeDivisions, IN, osg::KdTree::BuildOptions &, options,
Properties::NON_VIRTUAL,
__void__computeDivisions__BuildOptions_R1,
"",
"");
I_Method4(int, divide, IN, osg::KdTree::BuildOptions &, options, IN, osg::BoundingBox &, bb, IN, int, nodeIndex, IN, unsigned int, level,
Properties::NON_VIRTUAL,
__int__divide__BuildOptions_R1__osg_BoundingBox_R1__int__unsigned_int,
"",
"");
I_Method4(bool, intersect, IN, const osg::KdTree::KdLeaf &, leaf, IN, const osg::Vec3 &, start, IN, const osg::Vec3 &, end, IN, osg::KdTree::LineSegmentIntersections &, intersections,
Properties::NON_VIRTUAL,
__bool__intersect__C5_KdLeaf_R1__C5_osg_Vec3_R1__C5_osg_Vec3_R1__LineSegmentIntersections_R1,
"",
"");
I_PublicMemberProperty(osg::observer_ptr< osg::Geometry >, _geometry);
I_PublicMemberProperty(osg::BoundingBox, _bb);
I_PublicMemberProperty(osg::KdTree::AxisStack, _axisStack);
I_PublicMemberProperty(osg::KdTree::KdNodeList, _kdNodes);
I_PublicMemberProperty(osg::KdTree::KdLeafList, _kdLeaves);
I_PublicMemberProperty(osg::ref_ptr< osg::Vec3Array >, _vertices);
I_PublicMemberProperty(osg::KdTree::Indices, _primitiveIndices);
I_PublicMemberProperty(osg::KdTree::BoundingBoxList, _boundingBoxes);
I_PublicMemberProperty(osg::KdTree::TriangleList, _triangles);
I_PublicMemberProperty(osg::KdTree::CenterList, _centers);
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osg::KdTree::BuildOptions)
I_DeclaringFile("osg/KdTree");
I_Constructor0(____BuildOptions,
"",
"");
I_PublicMemberProperty(int, _numVerticesProcessed);
I_PublicMemberProperty(int, _targetNumTrianglesPerLeaf);
I_PublicMemberProperty(int, _maxNumLevels);
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osg::KdTree::KdLeaf)
I_DeclaringFile("osg/KdTree");
I_Constructor0(____KdLeaf,
"",
"");
I_Constructor2(IN, osg::KdTree::value_type, f, IN, osg::KdTree::value_type, s,
____KdLeaf__value_type__value_type,
"",
"");
I_PublicMemberProperty(osg::KdTree::value_type, first);
I_PublicMemberProperty(osg::KdTree::value_type, second);
I_PublicMemberProperty(osg::BoundingBox, bb);
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osg::KdTree::KdNode)
I_DeclaringFile("osg/KdTree");
I_Constructor0(____KdNode,
"",
"");
I_Constructor2(IN, osg::KdTree::value_type, f, IN, osg::KdTree::value_type, s,
____KdNode__value_type__value_type,
"",
"");
I_PublicMemberProperty(osg::KdTree::value_type, first);
I_PublicMemberProperty(osg::KdTree::value_type, second);
I_PublicMemberProperty(osg::BoundingBox, bb);
END_REFLECTOR
TYPE_NAME_ALIAS(std::vector< unsigned int >, osg::KdTree::LineSegmentIntersection::IndexList)
TYPE_NAME_ALIAS(std::vector< double >, osg::KdTree::LineSegmentIntersection::RatioList)
BEGIN_VALUE_REFLECTOR(osg::KdTree::LineSegmentIntersection)
I_DeclaringFile("osg/KdTree");
I_Constructor0(____LineSegmentIntersection,
"",
"");
I_PublicMemberProperty(double, ratio);
I_PublicMemberProperty(osg::Vec3d, intersectionPoint);
I_PublicMemberProperty(osg::Vec3, intersectionNormal);
I_PublicMemberProperty(osg::KdTree::LineSegmentIntersection::IndexList, indexList);
I_PublicMemberProperty(osg::KdTree::LineSegmentIntersection::RatioList, ratioList);
I_PublicMemberProperty(unsigned int, primitiveIndex);
END_REFLECTOR
BEGIN_VALUE_REFLECTOR(osg::KdTree::Triangle)
I_DeclaringFile("osg/KdTree");
I_Constructor3(IN, unsigned int, p1, IN, unsigned int, p2, IN, unsigned int, p3,
____Triangle__unsigned_int__unsigned_int__unsigned_int,
"",
"");
I_PublicMemberProperty(unsigned int, _p1);
I_PublicMemberProperty(unsigned int, _p2);
I_PublicMemberProperty(unsigned int, _p3);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osg::KdTreeBuilder)
I_DeclaringFile("osg/KdTree");
I_BaseType(osg::NodeVisitor);
I_Constructor0(____KdTreeBuilder,
"",
"");
I_Constructor1(IN, const osg::KdTreeBuilder &, rhs,
Properties::NON_EXPLICIT,
____KdTreeBuilder__C5_KdTreeBuilder_R1,
"",
"");
I_Method0(osg::KdTreeBuilder *, clone,
Properties::VIRTUAL,
__KdTreeBuilder_P1__clone,
"",
"");
I_Method1(void, apply, IN, osg::Geode &, geode,
Properties::VIRTUAL,
__void__apply__osg_Geode_R1,
"",
"");
I_PublicMemberProperty(osg::KdTree::BuildOptions, _buildOptions);
I_PublicMemberProperty(osg::ref_ptr< osg::KdTree >, _kdTreePrototype);
END_REFLECTOR
STD_SET_REFLECTOR(std::multiset< osg::KdTree::LineSegmentIntersection >)
STD_VECTOR_REFLECTOR(std::vector< double >)
STD_VECTOR_REFLECTOR(std::vector< osg::BoundingBox >)
STD_VECTOR_REFLECTOR(std::vector< osg::KdTree::KdLeaf >)
STD_VECTOR_REFLECTOR(std::vector< osg::KdTree::KdNode >)
STD_VECTOR_REFLECTOR(std::vector< osg::KdTree::Triangle >)
STD_VECTOR_REFLECTOR(std::vector< osg::KdTree::value_type >)