Re: [osg-users] LineSegmentIntersector does not work with Billboards

2008-08-14 Thread Robert Osfield
Hi Judd,

I have done some work on osgUtil::IntersectionVisitor to add proper
support for Billboards.  Could you try out the attached
IntersectionVisitor header/source files and let me know how you get
on.  This builds against OSG-2.6/OSG-SVN, but might also compile
against 2.4.

In my own testing 'osgpick lz.osg' now works fine, whereas before this
fix it failed to pick the billboarded trees.

Robert.


IntersectionVisitor
Description: Binary data
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/


#include osgUtil/IntersectionVisitor
#include osgUtil/LineSegmentIntersector

#include osg/PagedLOD
#include osg/Transform
#include osg/Projection
#include osg/Camera
#include osg/Geode
#include osg/Billboard
#include osg/Geometry
#include osg/Notify
#include osg/io_utils

using namespace osgUtil;


///
//
//  IntersectorGroup
//

IntersectorGroup::IntersectorGroup()
{
}

void IntersectorGroup::addIntersector(Intersector* intersector)
{
_intersectors.push_back(intersector);
}

void IntersectorGroup::clear()
{
_intersectors.clear();
}

Intersector* IntersectorGroup::clone(osgUtil::IntersectionVisitor iv)
{
IntersectorGroup* ig = new IntersectorGroup;

// now copy across all intersectors that arn't disabled.
for(Intersectors::iterator itr = _intersectors.begin();
itr != _intersectors.end();
++itr)
{
if (!(*itr)-disabled())
{
ig-addIntersector( (*itr)-clone(iv) );
}
}

return ig;
}

bool IntersectorGroup::enter(const osg::Node node)
{
if (disabled()) return false;

bool foundIntersections = false;

for(Intersectors::iterator itr = _intersectors.begin();
itr != _intersectors.end();
++itr)
{
if ((*itr)-disabled()) (*itr)-incrementDisabledCount();
else if ((*itr)-enter(node)) foundIntersections = true;
else (*itr)-incrementDisabledCount();
}

if (!foundIntersections) 
{
// need to call leave to clean up the DisabledCount's.
leave();
return false;
}

// we have found at least one suitable intersector, so return true
return true;
}

void IntersectorGroup::leave()
{
for(Intersectors::iterator itr = _intersectors.begin();
itr != _intersectors.end();
++itr)
{
if ((*itr)-disabled()) (*itr)-decrementDisabledCount();
}
}

void IntersectorGroup::intersect(osgUtil::IntersectionVisitor iv, osg::Drawable* drawable)
{
if (disabled()) return;

unsigned int numTested = 0;
for(Intersectors::iterator itr = _intersectors.begin();
itr != _intersectors.end();
++itr)
{
if (!(*itr)-disabled())
{
(*itr)-intersect(iv, drawable);

++numTested;
}
}

// osg::notify(osg::NOTICE)Number testing numTestedstd::endl;

}

void IntersectorGroup::reset()
{
Intersector::reset();

for(Intersectors::iterator itr = _intersectors.begin();
itr != _intersectors.end();
++itr)
{
(*itr)-reset();
}
}

bool IntersectorGroup::containsIntersections()
{
for(Intersectors::iterator itr = _intersectors.begin();
itr != _intersectors.end();
++itr)
{
if ((*itr)-containsIntersections()) return true;
}
return false;
}


///
//
//  IntersectionVisitor
//

IntersectionVisitor::IntersectionVisitor(Intersector* intersector, ReadCallback* readCallback)
{
// override the default node visitor mode.
setTraversalMode(osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);

_useKdTreesWhenAvailable = true;
_dummyTraversal = false;

_lodSelectionMode = USE_HIGHEST_LEVEL_OF_DETAIL;
_eyePointDirty = true;

LineSegmentIntersector* ls = dynamic_castLineSegmentIntersector*(intersector);
if (ls) 
{
setReferenceEyePoint(ls-getStart());
setReferenceEyePointCoordinateFrame(ls-getCoordinateFrame());
}
else
{
setReferenceEyePoint(osg::Vec3(0.0f,0.0f,0.0f));
setReferenceEyePointCoordinateFrame(Intersector::VIEW);
}

setIntersector(intersector);

setReadCallback(readCallback);

Re: [osg-users] LineSegmentIntersector does not work with Billboards

2008-08-14 Thread Judd Tracy

It seems to work just fine in my application.  Thanks for the support.

Judd

Robert Osfield wrote:

Hi Judd,

I have done some work on osgUtil::IntersectionVisitor to add proper
support for Billboards.  Could you try out the attached
IntersectionVisitor header/source files and let me know how you get
on.  This builds against OSG-2.6/OSG-SVN, but might also compile
against 2.4.

In my own testing 'osgpick lz.osg' now works fine, whereas before this
fix it failed to pick the billboarded trees.

Robert.
  


___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] LineSegmentIntersector does not work with Billboards

2008-08-14 Thread Judd Tracy

Robert

I have added a method called set (did not know what to call it) that 
allows you to set the start and end points for the LinSegmentIntersector 
using the CooridnateFrame and the x, y values like one of the 
constructors does.  It just makes it easier to reset the start and end 
points without having to know which values to use depending on the 
CoordinateFrame.


Judd

Robert Osfield wrote:

Hi Judd,

I have done some work on osgUtil::IntersectionVisitor to add proper
support for Billboards.  Could you try out the attached
IntersectionVisitor header/source files and let me know how you get
on.  This builds against OSG-2.6/OSG-SVN, but might also compile
against 2.4.

In my own testing 'osgpick lz.osg' now works fine, whereas before this
fix it failed to pick the billboarded trees.

Robert.
  


/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/


#include osgUtil/LineSegmentIntersector

#include osg/Geometry
#include osg/Notify
#include osg/io_utils
#include osg/TriangleFunctor

using namespace osgUtil;

namespace LineSegmentIntersectorUtils
{

struct TriangleIntersection
{
TriangleIntersection(unsigned int index, const osg::Vec3 normal, float 
r1, const osg::Vec3* v1, float r2, const osg::Vec3* v2, float r3, const 
osg::Vec3* v3):
_index(index),
_normal(normal),
_r1(r1),
_v1(v1),
_r2(r2),
_v2(v2),
_r3(r3),
_v3(v3) {}

unsigned int_index;
const osg::Vec3 _normal;
float   _r1;
const osg::Vec3*_v1;
float   _r2;
const osg::Vec3*_v2;
float   _r3;
const osg::Vec3*_v3;
};

typedef std::multimapfloat,TriangleIntersection TriangleIntersections;

struct TriangleIntersector
{
osg::Vec3   _s;
osg::Vec3   _d;
float   _length;

int _index;
float   _ratio;
bool_hit;

TriangleIntersections _intersections;

TriangleIntersector()
{
_length = 0.0f;
_index = 0;
_ratio = 0.0f;
_hit = false;
}

void set(const osg::Vec3d start, osg::Vec3d end, float ratio=FLT_MAX)
{
_hit=false;
_index = 0;
_ratio = ratio;

_s = start;
_d = end - start;
_length = _d.length();
_d /= _length;
}

inline void operator () (const osg::Vec3 v1,const osg::Vec3 v2,const 
osg::Vec3 v3, bool treatVertexDataAsTemporary)
{
++_index;

if (v1==v2 || v2==v3 || v1==v3) return;

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 (ds120.0f) return;
if (ds12d312) return;
}
else // d312  0
{
if (ds120.0f) return;
if (ds12d312) return;
}

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 (ds230.0f) return;
if (ds23d123) return;
}
else // d123  0
{
if (ds230.0f) return;
if (ds23d123) return;
}

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 (ds310.0f) return;
if (ds31d231) return;
}
else // d231  0
{
if (ds310.0f) return;
if (ds31d231) return;
}


float r3;
if (ds12==0.0f) r3=0.0f;
else if (d312!=0.0f) r3 = ds12/d312;
else return; // 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 return; // the triangle and the line 

Re: [osg-users] LineSegmentIntersector does not work with Billboards

2008-08-14 Thread Robert Osfield
Hi Judd,

Could you post your ammendments to osg-submissions.

Cheers,
Robert.

On Thu, Aug 14, 2008 at 5:11 PM, Judd Tracy [EMAIL PROTECTED] wrote:
 Robert

 I have added a method called set (did not know what to call it) that allows
 you to set the start and end points for the LinSegmentIntersector using the
 CooridnateFrame and the x, y values like one of the constructors does.  It
 just makes it easier to reset the start and end points without having to
 know which values to use depending on the CoordinateFrame.

 Judd

 Robert Osfield wrote:

 Hi Judd,

 I have done some work on osgUtil::IntersectionVisitor to add proper
 support for Billboards.  Could you try out the attached
 IntersectionVisitor header/source files and let me know how you get
 on.  This builds against OSG-2.6/OSG-SVN, but might also compile
 against 2.4.

 In my own testing 'osgpick lz.osg' now works fine, whereas before this
 fix it failed to pick the billboarded trees.

 Robert.



 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  *
  * This library is open source and may be redistributed and/or modified
 under
  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  * (at your option) any later version.  The full license is in LICENSE file
  * included with this distribution, and on the openscenegraph.org website.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * OpenSceneGraph Public License for more details.
 */


 #include osgUtil/LineSegmentIntersector

 #include osg/Geometry
 #include osg/Notify
 #include osg/io_utils
 #include osg/TriangleFunctor

 using namespace osgUtil;

 namespace LineSegmentIntersectorUtils
 {

struct TriangleIntersection
{
TriangleIntersection(unsigned int index, const osg::Vec3 normal,
 float r1, const osg::Vec3* v1, float r2, const osg::Vec3* v2, float r3,
 const osg::Vec3* v3):
_index(index),
_normal(normal),
_r1(r1),
_v1(v1),
_r2(r2),
_v2(v2),
_r3(r3),
_v3(v3) {}

unsigned int_index;
const osg::Vec3 _normal;
float   _r1;
const osg::Vec3*_v1;
float   _r2;
const osg::Vec3*_v2;
float   _r3;
const osg::Vec3*_v3;
};

typedef std::multimapfloat,TriangleIntersection TriangleIntersections;

struct TriangleIntersector
{
osg::Vec3   _s;
osg::Vec3   _d;
float   _length;

int _index;
float   _ratio;
bool_hit;

TriangleIntersections _intersections;

TriangleIntersector()
{
_length = 0.0f;
_index = 0;
_ratio = 0.0f;
_hit = false;
}

void set(const osg::Vec3d start, osg::Vec3d end, float
 ratio=FLT_MAX)
{
_hit=false;
_index = 0;
_ratio = ratio;

_s = start;
_d = end - start;
_length = _d.length();
_d /= _length;
}

inline void operator () (const osg::Vec3 v1,const osg::Vec3
 v2,const osg::Vec3 v3, bool treatVertexDataAsTemporary)
{
++_index;

if (v1==v2 || v2==v3 || v1==v3) return;

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 (ds120.0f) return;
if (ds12d312) return;
}
else // d312  0
{
if (ds120.0f) return;
if (ds12d312) return;
}

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 (ds230.0f) return;
if (ds23d123) return;
}
else // d123  0
{
if (ds230.0f) return;
if (ds23d123) return;
}

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 (ds310.0f) return;
if (ds31d231) return;
}
else // d231  0
{
if (ds310.0f) return;
if (ds31d231) return;
}


float r3;
if (ds12==0.0f) r3=0.0f;
else if (d312!=0.0f) r3 = ds12/d312;
else return; // the triangle and the line must be parallel
 intersection.

float r1;
  

Re: [osg-users] LineSegmentIntersector does not work with Billboards

2008-08-12 Thread Robert Osfield
Hi Judd,

I've just tried

  osgpick lz.osg

And zooming into the trees and attempting picking is showing no
intersections results where I'd expect.  Reviewing the relevent code
in IntersectionVisitor.cpp suggests that there is no special code for
handling the local model transforms that are required for billboards,
the so the answer is looks to be that even 2.6 hasn't had this problem
addressed. The relevant code is:

void IntersectionVisitor::apply(osg::Billboard billboard)
{
if (!enter(billboard)) return;

for(unsigned int i=0; ibillboard.getNumDrawables(); ++i)
{
intersect( billboard.getDrawable(i) );
}

leave();
}

Looking at the old IntersectVisitor.cpp code shows that it does have
some proper matrix code in there, which could probably copied across
into the IntersectionVisitor:



Robert.
void IntersectVisitor::apply(Billboard node)
{
if (!enterNode(node)) return;

// IntersectVisitor doesn't have getEyeLocal(), can we use
NodeVisitor::getEyePoint()?
const Vec3 eye_local = getEyePoint();

for(unsigned int i = 0; i  node.getNumDrawables(); i++ )
{
const Vec3 pos = node.getPosition(i);
osg::ref_ptrRefMatrix billboard_matrix = new RefMatrix;
node.computeMatrix(*billboard_matrix,eye_local,pos);

pushMatrix(billboard_matrix.get(), osg::Transform::RELATIVE_RF);

intersect(*node.getDrawable(i));

popMatrix();

}

leaveNode();
}

Try merging this code in. If it works out just post the changes to
osg-submissions.  Although it won't be in 2.6.0, this fix could
probably make it into later 2.6.x maintenance releases.

Robert.


On Mon, Aug 11, 2008 at 4:03 PM, Judd Tracy [EMAIL PROTECTED] wrote:
 The LineSegementIntersector in osg 2.4 does not work properly with
 Billboards.  Is there a fix in the SVN or that anyone else might have
 submitted that exists for this.  I have searched the SVN and as far as I can
 tell it has not been addressed.  Any help would be appreciated.

 Judd
 ___
 osg-users mailing list
 osg-users@lists.openscenegraph.org
 http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org