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.
This commit is contained in:
Robert Osfield
2002-02-05 21:54:46 +00:00
parent 7293af59ed
commit a703130aa0
18 changed files with 255 additions and 343 deletions

View File

@@ -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

View File

@@ -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 <osg/Group>
#include <osg/Matrix>
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> _calcTransformCallback;
};
}
#endif

View File

@@ -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<const name *>(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.

View File

@@ -6,6 +6,7 @@
#define OSG_NODEVISITOR 1
#include <osg/Node>
#include <osg/Matrix>
#include <osg/FrameStamp>
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;
};

View File

@@ -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;

View File

@@ -6,6 +6,7 @@
#define OSGUTIL_STATISTICS 1
#include <osg/Referenced>
#include <osg/Drawable>
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;
}
}

View File

@@ -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> _computeTransformCallback;
ref_ptr<Matrix> _matrix;
mutable bool _localToWorldDirty;
mutable ref_ptr<Matrix> _localToWorld;
mutable bool _worldToLocalDirty;
mutable ref_ptr<Matrix> _worldToLocal;
};
}

View File

@@ -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.

View File

@@ -1,25 +0,0 @@
#include <osg/AutoTransform>
using namespace osg;
AutoTransform::AutoTransform()
{
}
AutoTransform::AutoTransform(const AutoTransform& transform,const CopyOp& copyop):
Group(transform,copyop),
_calcTransformCallback(dynamic_cast<CalcTransformCallback*>(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;
}

View File

@@ -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\

View File

@@ -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();
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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._radius<len_ydash) _bsphere._radius = len_ydash;
if (_bsphere._radius<len_zdash) _bsphere._radius = len_zdash;
return true;
}
void Transform::computeLocalToWorld() const
{
if (_localToWorldDirty)
// note, NULL pointer for NodeVisitor, so compute's need
// to handle this case gracefully, normally this should not be a problem.
Matrix l2w;
if (getLocalToWorldMatrix(l2w,NULL))
{
if (_mode==VIEW)
{
_localToWorld->invert(*_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<len_ydash) _bsphere._radius = len_ydash;
if (_bsphere._radius<len_zdash) _bsphere._radius = len_zdash;
return true;
}
else
{
_bsphere.init();
return false;
}
}

View File

@@ -453,19 +453,19 @@ void Viewer::showStats(const unsigned int /*viewport*/)
char clin[72]; // buffer to print
glColor4fv((GLfloat * )&app_color);
sprintf(clin,"App %.1f ms.", timeApp);
sprintf(clin,"App %.2f ms.", timeApp);
displaytext((int)(.15f*tmax),(int)(0.98f*vh),clin);
glColor4fv((GLfloat * )&cull_color);
sprintf(clin,"Cull %.1f ms.", timeCull);
sprintf(clin,"Cull %.2f ms.", timeCull);
displaytext((int)(.35*tmax),(int)(0.98f*vh),clin);
glColor4fv((GLfloat * )&draw_color);
sprintf(clin,"Draw %.1f ms.", timeDraw);
sprintf(clin,"Draw %.2f ms.", timeDraw);
displaytext((int)(.55*tmax),(int)(0.98f*vh),clin);
glColor4fv((GLfloat * )&frame_color);
sprintf(clin,"Frame %.1f ms.", timeFrame);
sprintf(clin,"Frame %.2f ms.", timeFrame);
displaytext((int)(.75*tmax),(int)(0.98f*vh),clin);
/* osg::notify(osg::NOTICE) << "Time of App "<<timeApp<<"ms "<< std::endl;
@@ -1483,7 +1483,7 @@ int writePrims( const int ypos, osg::Statistics& stats)
npix+=12;
strcpy(clin,"Vertices: ");
for (i=0; i<=osg::Statistics::POLYGON; i++) {
if (stats.primtypes[i]) {
if (stats.primverts[i]) {
sprintf(ctmp,"%5d", stats.primverts[i]);
strcat(clin, ctmp);
}

View File

@@ -54,15 +54,15 @@ class PrintVisitor : public NodeVisitor
moveOut();
}
virtual void apply(Geode& node) { apply((Node&)node); }
virtual void apply(Billboard& node) { apply((Geode&)node); }
virtual void apply(LightSource& node){ apply((Node&)node); }
virtual void apply(Geode& node) { apply((Node&)node); }
virtual void apply(Billboard& node) { apply((Geode&)node); }
virtual void apply(LightSource& node) { apply((Node&)node); }
virtual void apply(Group& node) { apply((Node&)node); }
virtual void apply(Transform& 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(Group& node) { apply((Node&)node); }
virtual void apply(Transform& 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); }
protected:
@@ -479,7 +479,7 @@ void CullVisitor::setCamera(const Camera& camera)
}
void CullVisitor::pushCullViewState(const Matrix* matrix)
void CullVisitor::pushCullViewState(Matrix* matrix)
{
osg::ref_ptr<CullViewState> 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<osg::Matrix> 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);

View File

@@ -505,7 +505,10 @@ void IntersectVisitor::apply(Transform& node)
{
if (!enterNode(node)) return;
pushMatrix(node.getLocalToWorldMatrix());
osg::ref_ptr<Matrix> matrix = new Matrix;
node.getLocalToWorldMatrix(*matrix,this);
pushMatrix(*matrix);
traverse(node);

View File

@@ -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;