fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Action / IntersectAction / OSGIntersectAction.cpp
blob35ee8bb8033297da898c191950b53928394cf064
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include "OSGConfig.h"
48 #include "OSGLog.h"
49 #include "OSGFieldContainer.h"
50 #include "OSGNode.h"
51 #include "OSGNodeCore.h"
52 #include "OSGAction.h"
53 #include "OSGIntersectAction.h"
54 #include "OSGIntersectProxyAttachment.h"
56 #include <boost/bind.hpp>
58 OSG_USING_NAMESPACE
61 /***************************************************************************\
62 * Description *
63 \***************************************************************************/
65 /*! \class OSG::IntersectAction
66 \ingroup GrpSystemAction
68 The intersect action class.
72 /***************************************************************************\
73 * Types *
74 \***************************************************************************/
76 /***************************************************************************\
77 * Class variables *
78 \***************************************************************************/
80 StatElemDesc<StatTimeElem> IntersectAction::statTravTime(
81 "IA-Time",
82 "time needed for intersect");
84 StatElemDesc<StatIntElem > IntersectAction::statNNodes(
85 "IA-NNodes",
86 "number of nodes visited");
88 StatElemDesc<StatIntElem > IntersectAction::statNTriangles(
89 "IA-NTrianles",
90 "number of triangles tested");
92 IntersectAction *IntersectAction::_prototype = NULL;
94 Action::FunctorStore *IntersectAction::_defaultEnterFunctors = NULL;
95 Action::FunctorStore *IntersectAction::_defaultLeaveFunctors = NULL;
97 /***************************************************************************\
98 * Class methods *
99 \***************************************************************************/
101 bool IntersectAction::terminateEnter(void)
103 FDEBUG_GV(("Terminate IntersectAction Enter\n"));
105 delete _defaultEnterFunctors;
107 _defaultEnterFunctors = NULL;
109 return true;
112 bool IntersectAction::terminateLeave(void)
114 FDEBUG_GV(("Terminate IntersectAction Leave\n"));
116 delete _defaultLeaveFunctors;
118 _defaultLeaveFunctors = NULL;
120 return true;
123 /*-------------------------------------------------------------------------*\
124 - public -
125 \*-------------------------------------------------------------------------*/
127 void IntersectAction::registerEnterDefault(const FieldContainerType &type,
128 const Action::Functor &func)
130 if(! _defaultEnterFunctors)
132 _defaultEnterFunctors = new FunctorStore;
134 addPostFactoryExitFunction(&IntersectAction::terminateEnter);
137 while(type.getId() >= _defaultEnterFunctors->size())
139 _defaultEnterFunctors->push_back(
140 &IntersectAction::_defaultEnterFunction);
143 (*_defaultEnterFunctors)[type.getId()] = func;
146 void IntersectAction::registerLeaveDefault(const FieldContainerType &type,
147 const Action::Functor &func)
149 if(! _defaultLeaveFunctors)
151 _defaultLeaveFunctors = new FunctorStore;
153 addPostFactoryExitFunction(&IntersectAction::terminateLeave);
156 while(type.getId() >= _defaultLeaveFunctors->size())
158 _defaultLeaveFunctors->push_back(
159 &IntersectAction::_defaultLeaveFunction);
162 (*_defaultLeaveFunctors)[type.getId()] = func;
165 void IntersectAction::setPrototype(IntersectAction *proto)
167 _prototype = proto;
170 IntersectAction *IntersectAction::getPrototype(void)
172 return _prototype;
175 StatCollector *IntersectAction::getStatCollector(void) const
177 return _statistics;
180 void IntersectAction::setStatCollector(StatCollector *sc)
182 _statistics = sc;
185 bool IntersectAction::getResetStatistics(void) const
187 return _resetStatistics;
190 void IntersectAction::setResetStatistics(bool value)
192 _resetStatistics = value;
195 /*-------------------------------------------------------------------------*\
196 - protected -
197 \*-------------------------------------------------------------------------*/
200 /*-------------------------------------------------------------------------*\
201 - private -
202 \*-------------------------------------------------------------------------*/
206 /***************************************************************************\
207 * Instance methods *
208 \***************************************************************************/
210 /*-------------------------------------------------------------------------*\
211 - public -
212 \*-------------------------------------------------------------------------*/
214 /*------------- constructors & destructors --------------------------------*/
216 /** \brief Constructor
219 IntersectAction::IntersectAction(void) :
220 Inherited ( ),
221 _line ( ),
222 _testLines (false),
223 _lineTestWidth ( 0.0),
224 _maxdist ( ),
225 _hit (false),
226 _enterT ( -1),
227 _leaveT ( -1),
228 _path ( ),
229 _hitT ( -1),
230 _hitObject ( ),
231 _hitPath ( ),
232 _hitTriangle ( -1),
233 _hitNormal ( ),
234 _hitLine ( -1),
235 _statistics (NULL ),
236 _resetStatistics(true )
238 if(_defaultEnterFunctors)
239 _enterFunctors = *_defaultEnterFunctors;
241 if(_defaultLeaveFunctors)
242 _leaveFunctors = *_defaultLeaveFunctors;
244 _nodeEnterCB = boost::bind(&IntersectAction::onEnterNode, this, _1, _2);
245 _nodeLeaveCB = boost::bind(&IntersectAction::onLeaveNode, this, _1, _2);
249 IntersectAction::IntersectAction(const IntersectAction& source) :
250 Inherited (source ),
251 _line (source._line ),
252 _testLines (source._testLines ),
253 _lineTestWidth (source._lineTestWidth ),
254 _maxdist (source._maxdist ),
255 _hit (source._hit ),
256 _enterT (source._enterT ),
257 _leaveT (source._leaveT ),
258 _path (source._path ),
259 _hitT (source._hitT ),
260 _hitObject (source._hitObject ),
261 _hitPath (source._hitPath ),
262 _hitTriangle (source._hitTriangle ),
263 _hitNormal (source._hitNormal ),
264 _hitLine (source._hitLine ),
265 _statistics (source._statistics ),
266 _resetStatistics(source._resetStatistics)
268 _nodeEnterCB = boost::bind(&IntersectAction::onEnterNode, this, _1, _2);
269 _nodeLeaveCB = boost::bind(&IntersectAction::onLeaveNode, this, _1, _2);
273 /** \brief create a new action
276 IntersectAction::ObjTransitPtr IntersectAction::create(void)
278 ObjTransitPtr act(NULL);
280 if(_prototype)
282 act = new IntersectAction(*_prototype);
284 else
286 act = new IntersectAction();
289 return act;
293 /** \brief create a new action
296 IntersectAction::ObjTransitPtr IntersectAction::create(const Line &line,
297 const Real32 maxdist)
299 ObjTransitPtr act(NULL);
301 if(_prototype)
303 act = new IntersectAction(*_prototype);
305 else
307 act = new IntersectAction();
310 act->setLine(line, maxdist);
312 return act;
315 /** \brief Destructor
318 IntersectAction::~IntersectAction(void)
322 /*---------------------------- application --------------------------------*/
324 /*---------------------------- properties ---------------------------------*/
326 void IntersectAction::setLine(const Line &line, const Real32 maxdist)
328 _line = line;
329 _maxdist = maxdist;
332 void IntersectAction::setTestLines( bool value )
334 _testLines = value;
337 void IntersectAction::setTestLineWidth(Real32 width)
339 _lineTestWidth = width;
342 Action::ResultE IntersectAction::setEnterLeave(Real32 enter, Real32 leave)
344 if(leave < 0 || enter > _maxdist ||
345 ( _hit && enter > _hitT ))
347 return Action::Skip;
350 return Action::Continue;
353 /** Attempt to set the new hit for the intersection.
354 * The hit is only set if this hit would be closer then the existing hit position.
355 * @param t The distance along the ray that the hit occurred.
356 * @param obj The Node object that was hit.
357 * @param triIndex The index of the triangle in the geometry hit.
358 * @param normal The normal at the hit location.
359 * @param lineIndex The index of the line in the geometry hit.
361 void IntersectAction::setHit( Real32 t,
362 Node *obj,
363 Int32 triIndex,
364 const Vec3f &normal,
365 Int32 lineIndex)
367 if(t < 0 || t > _hitT || t > _maxdist)
368 return;
370 _hitT = t;
371 _hitObject = obj;
372 _hitPath = _path;
373 _hitTriangle = triIndex;
374 _hitNormal = normal;
375 _hitLine = lineIndex;
376 _hit = true;
379 void IntersectAction::scale(Real32 s)
381 _hitT *= s;
382 _maxdist *= s;
385 /*-------------------------- your_category---------------------------------*/
388 Action::ResultE IntersectAction::start(void)
390 _hitT = Inf;
391 _hitObject = NULL;
392 _hitTriangle = -1;
393 _hitLine = -1;
394 _hit = false;
395 _hitPath.clear();
396 _path.clear();
398 // reserve some memory for a scene depth of 20
399 // TODO: is this a sensible number?
400 _hitPath.reserve(20);
401 _path.reserve(20);
403 if(_statistics == NULL)
404 _statistics = new StatCollector;
406 if(_resetStatistics == true)
407 _statistics->reset();
409 _statistics->getElem(statTravTime)->start();
411 return Continue;
414 Action::ResultE IntersectAction::stop(ResultE res)
416 _statistics->getElem(statTravTime)->stop();
418 return res;
422 /*-------------------------- assignment -----------------------------------*/
424 /*-------------------------- comparison -----------------------------------*/
426 /** \brief assignment
429 bool IntersectAction::operator < (const IntersectAction &other) const
431 return this < &other;
434 /** \brief equal
437 bool IntersectAction::operator == (
438 const IntersectAction &OSG_CHECK_ARG(other)) const
440 return false;
443 /** \brief unequal
446 bool IntersectAction::operator != (const IntersectAction &other) const
448 return ! (*this == other);
452 /*-------------------------------------------------------------------------*\
453 - protected -
454 \*-------------------------------------------------------------------------*/
457 Action::FunctorStore *IntersectAction::getDefaultEnterFunctors(void)
459 return _defaultEnterFunctors;
462 Action::FunctorStore *IntersectAction::getDefaultLeaveFunctors(void)
464 return _defaultLeaveFunctors;
467 /*-------------------------------------------------------------------------*\
468 - private -
469 \*-------------------------------------------------------------------------*/
471 Action::ResultE IntersectAction::onEnterNode(Node* node, Action* action)
473 OSG_ASSERT(this == action && node == _actNode);
475 ResultE result = Continue;
477 _path.push_back(node);
479 _statistics->getElem(statNNodes)->inc();
481 IntersectProxyAttachment* ipa = dynamic_cast<IntersectProxyAttachment*>(
482 node->findAttachment(IntersectProxyAttachment::getClassType()));
484 if(ipa != NULL)
486 result = ipa->intersectEnter(node, this);
489 return result;
492 Action::ResultE IntersectAction::onLeaveNode(Node* node, Action* action)
494 OSG_ASSERT(this == action && node == _actNode);
496 ResultE result = Continue;
498 _path.pop_back();
500 return result;