Hello Johannes,
On 10/10/2013 04:23 AM, Johannes wrote:
On 09.10.2013 17:14, Carsten Neumann wrote:
> hmm, I'm a bit unclear on this part and the related problem c) below.
> Which class do the enter/leave callbacks belong to, your
> CustomIntersectAction? What kind of housekeeping do you propose?
Let me first explain an extension of the given IntersectAction that
perhaps might work:
1. Add to the class a linear container (list, vector, stack) for nodes
(_trackContainer) with the following semantics:
On traversal of the scene graph the current VisitSubTree core carrying
node hierarchy is tracked. So this container might contain zero or more
nodes of the scene graph branch at any time.
2. Add a hit state of the very same container type to the
IntersectAction class (_hitContainer). This state is updated on
successful hit only, i.e. if the current hit replaces the last one. In
that case the container node hierarchy of 1. is copied to the hit state
container.
On finishing of the IntersectAction apply call _hitContainer does
contain zero or more VisitSubTree carrying nodes of the scene graph
branch which corresponds to the evaluated hit.
Of course one could track all visited nodes of the branch but I see no
value in doing that.
oh, it just seemed simpler to do and avoid having to worry about it
again if something similar comes up in the future ;)
2. The IntersectAction class should of course contain an interface for
evaluating of _hitContainer.
3. It should provide an interface for push and pop to the _trackContainer.
4. Provide an additional intersectLeave method to the VisitSubTree core.
hmm, VisitSubTree just registers a callback with the IntersectAction
when the it is being left, no?
5. The VisitSubTree core intersectEnter and intersectLeave methods would
work with the IntersectAction _trackContainer interface. So at any time
of the traversal the container would reflect to current VisitSubTree
carrying node hierarchy.
6. Now at evaluating of the intersection the user is able to work
through the _hitContainer to transition into the correct scene graph
branch.
Ok that is the grande scheme I have in mind.
ok, sounds good to me, it's pretty close to what I was thinking of.
In case that I can't modify the IntersectAction I would like to derive
from it instead. Writing a standalone IntersectAction2 is IMHO not
feasible because one would have to provide all of the intersectEnter
like callbacks. I have actually written a specialized selection action
which is doing right that. But I have had to write handlers for all of
the interesting core classes which naturally does not scale well.
If I work by deriving I still would have to provide intersectEnter and
intersectLeave callbacks for the VisitSubTree core. That is, because I
have an extra task to do (see 5. above).
These two callback would be implemented in the derived class. Here is
the first weak point of the current design: Since the current
VisitSubTree intersectEnter method is protected I'm unable to delegate
to this handler. I would have to reimplement the functionality of the
core class handler. :-(
ok, that is inelegant, on the other hand it is a six line callback.
The second problem is that I would have additionally to reimplement the
setHit method virtually. :-(
Delegation to the base class setHit would be possible if this method
would provide status information about its evaluation, i.e if a
replacement of the current hit has happened.
well, that should not break any existing code, so we could make that change.
Anyway, I'm attaching a quick attempt at a patch that tracks the whole
path from root to hit object and makes it available as IA::getHitPath().
Cheers,
Carsten
diff --git a/Source/System/Action/IntersectAction/OSGIntersectAction.cpp b/Source/System/Action/IntersectAction/OSGIntersectAction.cpp
index 1f56266..35ee8bb 100644
--- a/Source/System/Action/IntersectAction/OSGIntersectAction.cpp
+++ b/Source/System/Action/IntersectAction/OSGIntersectAction.cpp
@@ -225,8 +225,10 @@ IntersectAction::IntersectAction(void) :
_hit (false),
_enterT ( -1),
_leaveT ( -1),
+ _path ( ),
_hitT ( -1),
_hitObject ( ),
+ _hitPath ( ),
_hitTriangle ( -1),
_hitNormal ( ),
_hitLine ( -1),
@@ -240,6 +242,7 @@ IntersectAction::IntersectAction(void) :
_leaveFunctors = *_defaultLeaveFunctors;
_nodeEnterCB = boost::bind(&IntersectAction::onEnterNode, this, _1, _2);
+ _nodeLeaveCB = boost::bind(&IntersectAction::onLeaveNode, this, _1, _2);
}
@@ -252,8 +255,10 @@ IntersectAction::IntersectAction(const IntersectAction& source) :
_hit (source._hit ),
_enterT (source._enterT ),
_leaveT (source._leaveT ),
+ _path (source._path ),
_hitT (source._hitT ),
_hitObject (source._hitObject ),
+ _hitPath (source._hitPath ),
_hitTriangle (source._hitTriangle ),
_hitNormal (source._hitNormal ),
_hitLine (source._hitLine ),
@@ -261,6 +266,7 @@ IntersectAction::IntersectAction(const IntersectAction& source) :
_resetStatistics(source._resetStatistics)
{
_nodeEnterCB = boost::bind(&IntersectAction::onEnterNode, this, _1, _2);
+ _nodeLeaveCB = boost::bind(&IntersectAction::onLeaveNode, this, _1, _2);
}
@@ -333,12 +339,6 @@ void IntersectAction::setTestLineWidth(Real32 width)
_lineTestWidth = width;
}
-Int32 IntersectAction::getHitLine() const
-{
- return _hitLine;
-}
-
-
Action::ResultE IntersectAction::setEnterLeave(Real32 enter, Real32 leave)
{
if(leave < 0 || enter > _maxdist ||
@@ -366,9 +366,10 @@ void IntersectAction::setHit( Real32 t,
{
if(t < 0 || t > _hitT || t > _maxdist)
return;
-
+
_hitT = t;
_hitObject = obj;
+ _hitPath = _path;
_hitTriangle = triIndex;
_hitNormal = normal;
_hitLine = lineIndex;
@@ -391,6 +392,13 @@ Action::ResultE IntersectAction::start(void)
_hitTriangle = -1;
_hitLine = -1;
_hit = false;
+ _hitPath.clear();
+ _path.clear();
+
+ // reserve some memory for a scene depth of 20
+ // TODO: is this a sensible number?
+ _hitPath.reserve(20);
+ _path.reserve(20);
if(_statistics == NULL)
_statistics = new StatCollector;
@@ -466,6 +474,8 @@ Action::ResultE IntersectAction::onEnterNode(Node* node, Action* action)
ResultE result = Continue;
+ _path.push_back(node);
+
_statistics->getElem(statNNodes)->inc();
IntersectProxyAttachment* ipa = dynamic_cast<IntersectProxyAttachment*>(
@@ -478,3 +488,14 @@ Action::ResultE IntersectAction::onEnterNode(Node* node, Action* action)
return result;
}
+
+Action::ResultE IntersectAction::onLeaveNode(Node* node, Action* action)
+{
+ OSG_ASSERT(this == action && node == _actNode);
+
+ ResultE result = Continue;
+
+ _path.pop_back();
+
+ return result;
+}
diff --git a/Source/System/Action/IntersectAction/OSGIntersectAction.h b/Source/System/Action/IntersectAction/OSGIntersectAction.h
index 2b3f1d1..3eabacb 100644
--- a/Source/System/Action/IntersectAction/OSGIntersectAction.h
+++ b/Source/System/Action/IntersectAction/OSGIntersectAction.h
@@ -85,6 +85,8 @@ class OSG_SYSTEM_DLLMAPPING IntersectAction : public Action
static StatElemDesc<StatIntElem > statNNodes;
static StatElemDesc<StatIntElem > statNTriangles;
+ typedef std::vector<Node*> NodeStore;
+
//-----------------------------------------------------------------------
// class functions
//-----------------------------------------------------------------------
@@ -130,26 +132,20 @@ class OSG_SYSTEM_DLLMAPPING IntersectAction : public Action
// get input data
- const Line &getLine ( void ) const;
- Real32 getMaxDist ( void ) const;
- bool getTestLines ( void ) const;
- Real32 getTestLineWidth ( void ) const;
-
-
- // get result data
- bool didHit ( void ) const;
-
- Real32 getHitT ( void ) const;
-
- Pnt3f getHitPoint ( void ) const;
-
- const Vec3f &getHitNormal ( void ) const;
-
- Node *getHitObject ( void ) const;
-
- Int32 getHitTriangle( void ) const;
+ const Line &getLine ( void ) const;
+ Real32 getMaxDist ( void ) const;
+ bool getTestLines ( void ) const;
+ Real32 getTestLineWidth( void ) const;
- Int32 getHitLine ( void ) const;
+ // get result data
+ bool didHit (void) const;
+ Real32 getHitT (void) const;
+ Pnt3f getHitPoint (void) const;
+ const Vec3f &getHitNormal (void) const;
+ Node *getHitObject (void) const;
+ const NodeStore &getHitPath (void) const;
+ Int32 getHitTriangle(void) const;
+ Int32 getHitLine (void) const;
/*------------------------- access ------------------------------*/
@@ -229,6 +225,7 @@ class OSG_SYSTEM_DLLMAPPING IntersectAction : public Action
virtual FunctorStore *getDefaultLeaveFunctors(void);
ResultE onEnterNode(Node* node, Action* action);
+ ResultE onLeaveNode(Node* node, Action* action);
private:
@@ -279,26 +276,28 @@ class OSG_SYSTEM_DLLMAPPING IntersectAction : public Action
// Results (also intermediate)
// hit at all (either bv or face)
- bool _hit;
+ bool _hit;
// enter leave distance for bounding volume
- Real32 _enterT;
- Real32 _leaveT;
-
+ Real32 _enterT;
+ Real32 _leaveT;
+ NodeStore _path;
+
// Hit distance
- Real32 _hitT;
+ Real32 _hitT;
// Hit object
- Node *_hitObject;
+ Node *_hitObject;
+ NodeStore _hitPath;
// Index of the hit triangle ( from TriangleIterator::getIndex() )
- Int32 _hitTriangle;
+ Int32 _hitTriangle;
// Normal of the hit triangle
- Vec3f _hitNormal;
+ Vec3f _hitNormal;
// Index of the hit line ( from LineInterator::getIndex() )
- Int32 _hitLine;
-
+ Int32 _hitLine;
+
StatCollectorRefPtr _statistics;
bool _resetStatistics;
diff --git a/Source/System/Action/IntersectAction/OSGIntersectAction.inl b/Source/System/Action/IntersectAction/OSGIntersectAction.inl
index 7c2a9a3..b5dd16a 100644
--- a/Source/System/Action/IntersectAction/OSGIntersectAction.inl
+++ b/Source/System/Action/IntersectAction/OSGIntersectAction.inl
@@ -163,6 +163,12 @@ Node *IntersectAction::getHitObject(void) const
return _hitObject;
}
+inline
+const IntersectAction::NodeStore& IntersectAction::getHitPath(void) const
+{
+ return _hitPath;
+}
+
inline
Int32 IntersectAction::getHitTriangle(void) const
{
@@ -172,6 +178,12 @@ Int32 IntersectAction::getHitTriangle(void) const
return _hitTriangle;
}
+inline
+Int32 IntersectAction::getHitLine() const
+{
+ return _hitLine;
+}
+
/*---------------------------- properties ---------------------------------*/
/*-------------------------- your_category---------------------------------*/
------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60134071&iu=/4140/ostg.clktrk
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users