From a703130aa0aa3b318a191384dba14ea151f4a47a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 5 Feb 2002 21:54:46 +0000 Subject: [PATCH] Have taken a few more steps towards support for view dependant transformations by adding a ComputeTransformCallback to osg::Transform, and have now removed the recently added AutoTransform since it is nolonger required. Have also updated CullVisitor to account for the new ways for tracking transformation matrices in the scene. --- VisualStudio/osg/osg.dsp | 8 -- include/osg/AutoTransform | 83 ------------- include/osg/Node | 2 +- include/osg/NodeVisitor | 42 ++++++- include/osg/PositionAttitudeTransform | 8 +- include/osg/Statistics | 17 ++- include/osg/Transform | 110 ++++++++++++----- include/osgUtil/CullVisitor | 2 +- src/osg/AutoTransform.cpp | 25 ---- src/osg/Makefile | 2 - src/osg/Node.cpp | 7 +- src/osg/NodeVisitor.cpp | 10 ++ src/osg/PositionAttitudeTransform.cpp | 49 ++++---- src/osg/Transform.cpp | 168 +++++++------------------- src/osgGLUT/Viewer.cpp | 10 +- src/osgUtil/CullVisitor.cpp | 45 +++---- src/osgUtil/IntersectVisitor.cpp | 5 +- src/osgUtil/RenderBin.cpp | 5 + 18 files changed, 255 insertions(+), 343 deletions(-) delete mode 100644 include/osg/AutoTransform delete mode 100644 src/osg/AutoTransform.cpp diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 061509959..5290d9d4e 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -97,10 +97,6 @@ SOURCE=..\..\src\osg\AlphaFunc.cpp # End Source File # Begin Source File -SOURCE=..\..\src\osg\AutoTransform.cpp -# End Source File -# Begin Source File - SOURCE=..\..\src\osg\Billboard.cpp # End Source File # Begin Source File @@ -329,10 +325,6 @@ SOURCE=..\..\Include\Osg\AlphaFunc # End Source File # Begin Source File -SOURCE=..\..\Include\Osg\AutoTransform -# End Source File -# Begin Source File - SOURCE=..\..\Include\Osg\Billboard # End Source File # Begin Source File diff --git a/include/osg/AutoTransform b/include/osg/AutoTransform deleted file mode 100644 index c1de6f29a..000000000 --- a/include/osg/AutoTransform +++ /dev/null @@ -1,83 +0,0 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. - -#ifndef OSG_AUTOTRANSFORM -#define OSG_AUTOTRANSFORM 1 - -#include -#include - -namespace osg { - -/** AutoTransform - is group which all children - * are transformed by a matrix which is automatically - * calculated during the cull traversal. The routine to - * do the matrix transform is specified by the user allow - * them customize its behavior to their own requirements. -*/ -class SG_EXPORT AutoTransform : public Group -{ - public : - - class CalcTransformCallback : public osg::Referenced - { - - public: - - /** Get the transformation matrix which moves from local coords to world coords.*/ - virtual const Matrix getLocalToWorldMatrix(const osg::Matrix& modelview) const = 0; - - /** Get the transformation matrix which moves from world coords to local coords.*/ - virtual const Matrix getWorldToLocalMatrix(const osg::Matrix& modelview) const = 0; - - protected: - - virtual ~CalcTransformCallback() {} - - - - }; - - AutoTransform(); - - /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ - AutoTransform(const AutoTransform&,const CopyOp& copyop=CopyOp::SHALLOW_COPY); - - AutoTransform(const Matrix& matix); - - META_Node(AutoTransform); - - /** Get the transformation matrix which moves from local coords to world coords.*/ - inline const Matrix getLocalToWorldMatrix(const osg::Matrix& modelview) const - { - if (_calcTransformCallback.valid()) - return _calcTransformCallback->getLocalToWorldMatrix(modelview); - else return osg::Matrix::identity(); - } - - - /** Get the transformation matrix which moves from world coords to local coords.*/ - inline const Matrix getWorldToLocalMatrix(const osg::Matrix& modelview) const - { - if (_calcTransformCallback.valid()) - return _calcTransformCallback->getLocalToWorldMatrix(modelview); - else return osg::Matrix::identity(); - } - - - protected : - - virtual ~AutoTransform(); - - /** Override's Group's computeBound. - * There is no need to override in subclasses from osg::AutoTransform since this computeBound() uses - * the underlying matrix (calling computeMatrix if required.) */ - virtual const bool computeBound() const; - - ref_ptr _calcTransformCallback; -}; - -} - -#endif diff --git a/include/osg/Node b/include/osg/Node index 7e403158b..e93de7100 100644 --- a/include/osg/Node +++ b/include/osg/Node @@ -27,7 +27,7 @@ class Group; virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new name (*this,copyop); } \ virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast(obj)!=NULL; } \ virtual const char* className() const { return #name; } \ - virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) nv.apply(*this); } \ + virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } } \ /** Base class for all internal nodes in the scene graph. diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index d2314320e..ae66023d2 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -6,6 +6,7 @@ #define OSG_NODEVISITOR 1 #include +#include #include namespace osg { @@ -15,7 +16,6 @@ class Billboard; class LightSource; class Group; class Transform; -class AutoTransform; class LOD; class Switch; class Impostor; @@ -120,18 +120,48 @@ class SG_EXPORT NodeVisitor : public Referenced void setTraversalVisitor(NodeVisitor* nv); /** Get the traversal visitor, returns NULL if none is attached.*/ - NodeVisitor* getTraversalVisitor() { return _traversalVisitor.get(); } + inline NodeVisitor* getTraversalVisitor() { return _traversalVisitor.get(); } - /** Inline method for handling traversal of a nodes. + /** Method for handling traversal of a nodes. If you intend to use the visitor for actively traversing the scene graph then make sure the accept() methods call this method unless they handle traversal directly.*/ - void traverse(Node& node) + inline void traverse(Node& node) { if (_traversalVisitor.valid()) node.accept(*_traversalVisitor); else if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this); else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this); } + + /** Method called by osg::Node::accept() method before + * a call the NodeVisitor::apply(..). The back of the list will, + * therefore, be the current node being visited inside the apply(..), + * and the rest of the list will be the parental sequence of nodes + * from the top most node applied down the graph to the current node. + * Note, the user does not typically call pushNodeOnPath() as it + * will be called automatically by the Node::accept() method.*/ + inline void pushOntoNodePath(Node* node) { _nodePath.push_back(node); } + + /** Method callby osg::Node::accept() method after + * a call the NodeVisitor::apply(..). + * Note, the user does not typically call pushNodeOnPath() as it + * will be called automatically by the Node::accept() method.*/ + inline void popFromNodePath() { _nodePath.pop_back(); } + + /** Get the non const NodePath from the top most node applied down + * to the current Node being visited.*/ + NodePath& getNodePath() { return _nodePath; } + + /** Get the const NodePath from the top most node applied down + * to the current Node being visited.*/ + const NodePath& getNodePath() const { return _nodePath; } + + /** Get the Local To World Matrix from the NodePath for specified Transform::Mode.*/ + const bool getLocalToWorldMatrix(Matrix& matrix, MatrixMode mode); + + /** Get the World To Local Matrix from the NodePath for specified Transform::Mode.*/ + const bool getWorldToLocalMatrix(Matrix& matrix, MatrixMode mode); + virtual void apply(Node& node) { traverse(node);} @@ -141,12 +171,12 @@ class SG_EXPORT NodeVisitor : public Referenced virtual void apply(Group& node) { apply((Node&)node); } virtual void apply(Transform& node) { apply((Group&)node); } - virtual void apply(AutoTransform& node) { apply((Group&)node); } virtual void apply(Switch& node) { apply((Group&)node); } virtual void apply(LOD& node) { apply((Group&)node); } virtual void apply(Impostor& node) { apply((LOD&)node); } virtual void apply(EarthSky& node) { apply((Group&)node); } + protected: int _traversalNumber; @@ -158,6 +188,8 @@ class SG_EXPORT NodeVisitor : public Referenced TraversalMode _traversalMode; Node::NodeMask _traversalMask; Node::NodeMask _nodeMaskOverride; + + NodePath _nodePath; }; diff --git a/include/osg/PositionAttitudeTransform b/include/osg/PositionAttitudeTransform index cee2cec1e..a4610fb30 100644 --- a/include/osg/PositionAttitudeTransform +++ b/include/osg/PositionAttitudeTransform @@ -28,20 +28,20 @@ class SG_EXPORT PositionAttitudeTransform : public Transform META_Node(PositionAttitudeTransform); - void setPosition(const Vec3& pos) { _position = pos; _localToWorldDirty = _worldToLocalDirty = true; } + void setPosition(const Vec3& pos) { _position = pos; } const Vec3& getPosition() const { return _position; } - void setAttitude(const Quat& quat) { _attitude = quat; _localToWorldDirty = _worldToLocalDirty = true; } + void setAttitude(const Quat& quat) { _attitude = quat; } const Quat& getAttitude() const { return _attitude; } protected : - virtual void computeLocalToWorld() const; + virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const; - virtual void computeWorldToLocal() const; + virtual const bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const; Vec3 _position; Quat _attitude; diff --git a/include/osg/Statistics b/include/osg/Statistics index e8fb3bcd3..ffc8d712e 100644 --- a/include/osg/Statistics +++ b/include/osg/Statistics @@ -6,6 +6,7 @@ #define OSGUTIL_STATISTICS 1 #include +#include namespace osg { @@ -22,11 +23,12 @@ namespace osg { * each trifan or tristrip = (length-2) triangles and so on. */ -class SG_EXPORT Statistics : public osg::Referenced +class SG_EXPORT Statistics : public osg::Referenced, public osg::Drawable::AttributeFunctor { public: - Statistics() + Statistics(): + osg::Drawable::AttributeFunctor(osg::Drawable::COORDS) { reset(); }; @@ -70,6 +72,15 @@ class SG_EXPORT Statistics : public osg::Referenced void setType(statsType t) {stattype=t;} + virtual bool apply(osg::Drawable::AttributeBitMask abm,osg::Vec3* begin,osg::Vec3* end) + { + if (abm == osg::Drawable::COORDS) + { + primverts[0] += (end-begin); + return true; + } + } + void addNumPrims(const int typ, const int nprimlen, const int numprimtype, const int primvert) { if (typ>NO_TYPE && typ<=POLYGON) { @@ -79,7 +90,7 @@ class SG_EXPORT Statistics : public osg::Referenced numprimtypes[typ]+=numprimtype; primlens[0]+=nprimlen; primlens[typ]+=nprimlen; - primverts[0]+=primvert; + //primverts[0]+=primvert; primverts[typ]+=primvert; } } diff --git a/include/osg/Transform b/include/osg/Transform index f7143dccd..c83231663 100644 --- a/include/osg/Transform +++ b/include/osg/Transform @@ -10,10 +10,13 @@ namespace osg { -/** Transform - is group which all children - * are transformed by the the Transform's osg::Matrix. Typical uses +/** Transform - is group which all children are transformed by the the Transform's osg::Matrix. + * Typical uses * of the Transform is for positioning objects within a scene or * producing trackball functionality or for animation. + * The Transform node can be customized via the ComputeTransfromCallback which can be + * attached to the node, this might be used to convert internal representations of the transformation + * into generic osg::Matrix'c which are used during scene grpah traversal, such as CullTraversal and IntersectionTraversal. * Note, if the transformation matrix scales the subgraph then the * normals of the underlying geometry will need to be renormalized to * be unit vectors once more. One can done transparently through OpenGL's @@ -27,6 +30,7 @@ class SG_EXPORT Transform : public Group { public : + Transform(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ @@ -56,37 +60,78 @@ class SG_EXPORT Transform : public Group inline const Type getType() const { return _type; } + /** Set the matrix mode which tells traversers them how to treat this Transform - as Projection, View or Model transformation.*/ + inline void setMatrixMode(MatrixMode mode) { _mode = mode; } + + /** Get the transform mode.*/ + inline const MatrixMode getMatrixMode() const { return _mode; } + - enum Mode + /** Callback attached to an Transform to specifiy how to compute the modelview or projection transformation + * for the transform below the Transform node.*/ + class ComputeTransformCallback : public osg::Referenced { - VIEW, - MODEL + + public: + + /** Get the transformation matrix which moves from local coords to world coords.*/ + virtual const bool computeLocalToWorldMatrix(Matrix& matrix,const Transform* transform, NodeVisitor* nv) const = 0; + + /** Get the transformation matrix which moves from world coords to local coords.*/ + virtual const bool computeWorldToLocalMatrix(Matrix& matrix,const Transform* transform, NodeVisitor* nv) const = 0; + + protected: + + virtual ~ComputeTransformCallback() {} + }; - inline void setMode(Mode mode) { _mode = mode; } + + /** Set the ComputerTransfromCallback which allows users to attach custom computation of the local transformation as + * seen by cull traversers and alike.*/ + void setComputeTransformCallback(ComputeTransformCallback* ctc) { _computeTransformCallback=ctc; } - inline const Mode getMode() const { return _mode; } + /** Get the non const ComputerTransfromCallback.*/ + ComputeTransformCallback* getComputeTransformCallback() { return _computeTransformCallback.get(); } + + /** Get the const ComputerTransfromCallback.*/ + const ComputeTransformCallback* getComputeTransformCallback() const { return _computeTransformCallback.get(); } + + + + /** Get the transformation matrix which moves from local coords to world coords. + * Return true if Matrix passed in has been modified and */ + inline const bool getLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const + { + if (_computeTransformCallback.valid()) + return _computeTransformCallback->computeLocalToWorldMatrix(matrix,this,nv); + else + return computeLocalToWorldMatrix(matrix,nv); + } - /** Get the transformation matrix which moves from local coords to world coords.*/ - inline const Matrix& getLocalToWorldMatrix() const { if (_localToWorldDirty) computeLocalToWorld(); return *_localToWorld; } - - /** Get the transformation matrix which moves from world coords to local coords.*/ - inline const Matrix& getWorldToLocalMatrix() const { if (_worldToLocalDirty) computeWorldToLocal(); return *_worldToLocal; } - + /** Get the transformation matrix which moves from world coords to local coords. + * Return true if Matrix passed in has been modified and */ + inline const bool getWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const + { + if (_computeTransformCallback.valid()) + return _computeTransformCallback->computeWorldToLocalMatrix(matrix,this,nv); + else + return computeWorldToLocalMatrix(matrix,nv); + } /** Set the transform's matrix.*/ - void setMatrix(const Matrix& mat); + void setMatrix(const Matrix& mat) { (*_matrix) = mat; dirtyBound(); } /** Get the transform's matrix. */ - inline const Matrix& getMatrix() const { if (_mode==MODEL) return *_localToWorld; else return *_worldToLocal; } + inline const Matrix& getMatrix() const { return *_matrix; } /** preMult transform.*/ - void preMult(const Matrix& mat); + void preMult(const Matrix& mat) { _matrix->preMult(mat); dirtyBound(); } /** postMult transform.*/ - void postMult(const Matrix& mat); + void postMult(const Matrix& mat) { _matrix->postMult(mat); dirtyBound(); } protected : @@ -98,23 +143,26 @@ class SG_EXPORT Transform : public Group * the underlying matrix (calling computeMatrix if required.) */ virtual const bool computeBound() const; - /** If you subclass from osg::Transform you must override computeLocalToWorld() to provide your own mechanism for - * setting up the 4x4 matrix. An example of a subclass might a PositionAttitudeTransfrom which is its own - * Vec3 and Quat to calculate the matrix.*/ - virtual void computeLocalToWorld() const; + virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const + { + matrix = *_matrix; + return true; + } - /** If you subclass from osg::Transform it must also override computeWorldToLocal() to provide your own mechanism for - * setting up the 4x4 matrix.*/ - virtual void computeWorldToLocal() const; + virtual const bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const + { + matrix.invert(*_matrix); + return true; + } - Type _type; - Mode _mode; + + Type _type; + MatrixMode _mode; + ref_ptr _computeTransformCallback; + + ref_ptr _matrix; - mutable bool _localToWorldDirty; - mutable ref_ptr _localToWorld; - - mutable bool _worldToLocalDirty; - mutable ref_ptr _worldToLocal; + }; } diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 4730ef661..d535d75cb 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -126,7 +126,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor /** Get the viewport. */ osg::Viewport* getViewport() { return _viewport.get(); } - void pushCullViewState(const osg::Matrix* matrix=NULL); + void pushCullViewState(osg::Matrix* matrix=NULL); void popCullViewState(); /** Push state set on the current state group. diff --git a/src/osg/AutoTransform.cpp b/src/osg/AutoTransform.cpp deleted file mode 100644 index 838828092..000000000 --- a/src/osg/AutoTransform.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - -using namespace osg; - -AutoTransform::AutoTransform() -{ -} - -AutoTransform::AutoTransform(const AutoTransform& transform,const CopyOp& copyop): - Group(transform,copyop), - _calcTransformCallback(dynamic_cast(copyop(transform._calcTransformCallback.get()))) -{ -} - - -AutoTransform::~AutoTransform() -{ -} - -const bool AutoTransform::computeBound() const -{ - // can't calc the bound of a automatically transform object, - // it position isn't know until cull time. - return false; -} diff --git a/src/osg/Makefile b/src/osg/Makefile index dedbe21d4..cf2674180 100644 --- a/src/osg/Makefile +++ b/src/osg/Makefile @@ -3,7 +3,6 @@ include $(OSGHOME)/Make/makedefs C++FILES = \ AlphaFunc.cpp\ - AutoTransform.cpp\ Billboard.cpp\ BoundingBox.cpp\ BoundingSphere.cpp\ @@ -68,7 +67,6 @@ TARGET_LIB_FILES = lib$(TARGET_BASENAME).$(SO_EXT) TARGET_INCLUDE_FILES = \ osg/Notify\ osg/AlphaFunc\ - osg/AutoTransform\ osg/Billboard\ osg/BoundingBox\ osg/BoundingSphere\ diff --git a/src/osg/Node.cpp b/src/osg/Node.cpp index 40f35740a..4b044de4b 100644 --- a/src/osg/Node.cpp +++ b/src/osg/Node.cpp @@ -44,7 +44,12 @@ Node::~Node() void Node::accept(NodeVisitor& nv) { - if (nv.validNodeMask(*this)) nv.apply(*this); + if (nv.validNodeMask(*this)) + { + nv.pushOntoNodePath(this); + nv.apply(*this); + nv.popFromNodePath(); + } } diff --git a/src/osg/NodeVisitor.cpp b/src/osg/NodeVisitor.cpp index 3f9832bb1..8fd92d492 100644 --- a/src/osg/NodeVisitor.cpp +++ b/src/osg/NodeVisitor.cpp @@ -43,3 +43,13 @@ void NodeVisitor::setTraversalVisitor(NodeVisitor* nv) if (_traversalVisitor.valid()) _traversalMode = TRAVERSE_VISITOR; else _traversalMode = TRAVERSE_NONE; } + +const bool getLocalToWorldMatrix(Matrix& matrix, MatrixMode mode) +{ + return false; +} + +const bool getWorldToLocalMatrix(Matrix& matrix, MatrixMode mode) +{ + return false; +} diff --git a/src/osg/PositionAttitudeTransform.cpp b/src/osg/PositionAttitudeTransform.cpp index 7e11819a4..d8cc8833b 100644 --- a/src/osg/PositionAttitudeTransform.cpp +++ b/src/osg/PositionAttitudeTransform.cpp @@ -6,38 +6,35 @@ PositionAttitudeTransform::PositionAttitudeTransform() { } -void PositionAttitudeTransform::computeLocalToWorld() const +const bool PositionAttitudeTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const { - if (_localToWorldDirty) + if (_mode==MODEL || _mode==MODELVIEW) { - if (_mode==MODEL) - { - _localToWorld->makeRotate(_attitude); - _localToWorld->setTrans(_position); - } - else - { - _localToWorld->makeTranslate(-_position); - _localToWorld->postMult(osg::Matrix::rotate(_attitude.inverse())); - } - _localToWorldDirty = false; + matrix.makeRotate(_attitude); + matrix.setTrans(_position); + return true; + } + else // _mode==VIEW + { + matrix.makeTranslate(-_position); + matrix.postMult(osg::Matrix::rotate(_attitude.inverse())); + return true; } } -void PositionAttitudeTransform::computeWorldToLocal() const + +const bool PositionAttitudeTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const { - if (_worldToLocalDirty) + if (_mode==MODEL || _mode==MODELVIEW) { - if (_mode==MODEL) - { - _worldToLocal->makeTranslate(-_position); - _worldToLocal->postMult(osg::Matrix::rotate(_attitude.inverse())); - } - else - { - _worldToLocal->makeRotate(_attitude); - _worldToLocal->setTrans(_position); - } - _worldToLocalDirty = false; + matrix.makeTranslate(-_position); + matrix.postMult(osg::Matrix::rotate(_attitude.inverse())); + return true; + } + else // _mode==VIEW + { + matrix.makeRotate(_attitude); + matrix.setTrans(_position); + return true; } } diff --git a/src/osg/Transform.cpp b/src/osg/Transform.cpp index 63e1ac62c..94c0217fd 100644 --- a/src/osg/Transform.cpp +++ b/src/osg/Transform.cpp @@ -6,24 +6,16 @@ Transform::Transform() { _type = DYNAMIC; _mode = MODEL; - - _localToWorld = new Matrix; - _localToWorld->makeIdentity(); - _localToWorldDirty = false; - _worldToLocal = new Matrix; - _worldToLocal->makeIdentity(); - _worldToLocalDirty = false; + _matrix = new Matrix; } Transform::Transform(const Transform& transform,const CopyOp& copyop): Group(transform,copyop), _type(transform._type), _mode(transform._mode), - _localToWorldDirty(transform._localToWorldDirty), - _localToWorld(transform._localToWorld), - _worldToLocalDirty(transform._worldToLocalDirty), - _worldToLocal(transform._localToWorld) + _computeTransformCallback(_computeTransformCallback), + _matrix(new Matrix(*transform._matrix)) { } @@ -32,11 +24,7 @@ Transform::Transform(const Matrix& mat ) _type = DYNAMIC; _mode = MODEL; - _localToWorld = new Matrix(mat); - _localToWorldDirty = false; - - _worldToLocal = new Matrix; - _worldToLocalDirty = true; + _matrix = new Matrix(mat); } @@ -44,118 +32,48 @@ Transform::~Transform() { } -void Transform::setMatrix(const Matrix& mat ) -{ - if (_mode==MODEL) - { - (*_localToWorld) = mat; - _localToWorldDirty = false; - _worldToLocalDirty = true; - } - else - { - (*_worldToLocal) = mat; - _worldToLocalDirty = false; - _localToWorldDirty = true; - } - - dirtyBound(); -} - -/** preMult transform.*/ -void Transform::preMult( const Matrix& mat ) -{ - if (_mode==MODEL) - { - _localToWorld->preMult(mat); - _localToWorldDirty = false; - _worldToLocalDirty = true; - } - else - { - _worldToLocal->preMult(mat); - _worldToLocalDirty = false; - _localToWorldDirty = true; - } - - dirtyBound(); -} - -/** postMult transform.*/ -void Transform::postMult( const Matrix& mat ) -{ - if (_mode==MODEL) - { - _localToWorld->postMult(mat); - _localToWorldDirty = false; - _worldToLocalDirty = true; - } - else - { - _worldToLocal->postMult(mat); - _worldToLocalDirty = false; - _localToWorldDirty = true; - } - - dirtyBound(); -} - const bool Transform::computeBound() const { if (!Group::computeBound()) return false; - - if (_localToWorldDirty) computeLocalToWorld(); - - Vec3 xdash = _bsphere._center; - xdash.x() += _bsphere._radius; - xdash = xdash*(*_localToWorld); - - Vec3 ydash = _bsphere._center; - ydash.y() += _bsphere._radius; - ydash = ydash*(*_localToWorld); - - Vec3 zdash = _bsphere._center; - zdash.y() += _bsphere._radius; - zdash = zdash*(*_localToWorld); - - _bsphere._center = _bsphere._center*(*_localToWorld); - - xdash -= _bsphere._center; - float len_xdash = xdash.length(); - - ydash -= _bsphere._center; - float len_ydash = ydash.length(); - - zdash -= _bsphere._center; - float len_zdash = zdash.length(); - - _bsphere._radius = len_xdash; - if (_bsphere._radiusinvert(*_worldToLocal); - } - _localToWorldDirty = false; - } -} - -void Transform::computeWorldToLocal() const -{ - if (_worldToLocalDirty) - { - if (_mode==MODEL) - { - _worldToLocal->invert(*_localToWorld); - } - _worldToLocalDirty = false; + + Vec3 xdash = _bsphere._center; + xdash.x() += _bsphere._radius; + xdash = xdash*l2w; + + Vec3 ydash = _bsphere._center; + ydash.y() += _bsphere._radius; + ydash = ydash*l2w; + + Vec3 zdash = _bsphere._center; + zdash.y() += _bsphere._radius; + zdash = zdash*l2w; + + _bsphere._center = _bsphere._center*l2w; + + xdash -= _bsphere._center; + float len_xdash = xdash.length(); + + ydash -= _bsphere._center; + float len_ydash = ydash.length(); + + zdash -= _bsphere._center; + float len_zdash = zdash.length(); + + _bsphere._radius = len_xdash; + if (_bsphere._radius nvs = new CullViewState; @@ -487,20 +487,18 @@ void CullVisitor::pushCullViewState(const Matrix* matrix) Matrix* inverse_world = NULL; if (matrix) - { + { if (_cvs.valid() && _cvs->_matrix.valid()) { - nvs->_matrix = new Matrix; - nvs->_matrix->mult(*matrix,*(_cvs->_matrix)); - } - else - { - nvs->_matrix = new Matrix(*matrix); + matrix->postMult(*(_cvs->_matrix)); } - inverse_world = new Matrix; - inverse_world->invert(*(nvs->_matrix)); - nvs->_inverse = inverse_world; + nvs->_matrix = matrix; + + inverse_world = createOrReuseMatrix(); + inverse_world->invert(*(matrix)); + nvs->_inverse = inverse_world; + } else { @@ -1034,7 +1032,6 @@ void CullVisitor::apply(Group& node) _cullingModeStack.pop_back(); } - void CullVisitor::apply(Transform& node) { // return if object's bounding sphere is culled. @@ -1051,7 +1048,12 @@ void CullVisitor::apply(Transform& node) StateSet* node_state = node.getStateSet(); if (node_state) pushStateSet(node_state); - pushCullViewState(&node.getLocalToWorldMatrix()); + ref_ptr matrix = createOrReuseMatrix(); + matrix->makeIdentity(); + node.getLocalToWorldMatrix(*matrix,this); + pushCullViewState(matrix.get()); + +// pushCullViewState(&node.getMatrix()); traverse(node); @@ -1064,7 +1066,6 @@ void CullVisitor::apply(Transform& node) _cullingModeStack.pop_back(); } - void CullVisitor::apply(Switch& node) { apply((Group&)node); diff --git a/src/osgUtil/IntersectVisitor.cpp b/src/osgUtil/IntersectVisitor.cpp index 0fa261ee6..9960cbf31 100644 --- a/src/osgUtil/IntersectVisitor.cpp +++ b/src/osgUtil/IntersectVisitor.cpp @@ -505,7 +505,10 @@ void IntersectVisitor::apply(Transform& node) { if (!enterNode(node)) return; - pushMatrix(node.getLocalToWorldMatrix()); + osg::ref_ptr matrix = new Matrix; + node.getLocalToWorldMatrix(*matrix,this); + + pushMatrix(*matrix); traverse(node); diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index ac0932f87..d688b2f7b 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -185,7 +185,12 @@ bool RenderBin::getStats(osg::Statistics* primStats) primStats->addOpaque(); // number of geosets if (rl->_matrix.get()) primStats->addMatrix(); // number of matrices if (dw) { // then tot up the types 1-14 + // commenting out as having intrusive stats in base classes is + // undersirable. dw->getStats(*primStats); // use sub-class to find the stats for each drawable + + // use an AttributeOption to get the stats we require. + dw->applyAttributeOperation(*primStats); } } somestats=true;