From cab49a93072ec8c396d36f6d7981bb263c5041e2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 4 Aug 2002 20:34:48 +0000 Subject: [PATCH] From Ruben Lopez, updates to VRML/IV loader. From Ben Discoe, corrections to comments in osg::Transform From Alberto Barbati, Lazy evaluation of inverse matrix in osg::MatrixTransfrom --- AUTHORS | 3 + include/osg/MatrixTransform | 40 ++++++------ include/osg/Transform | 102 +++++++++++++++++-------------- src/osgGLUT/Viewer.cpp | 3 + src/osgPlugins/iv/main.cpp | 7 ++- src/osgPlugins/iv/osgvisitor.cpp | 4 +- src/osgPlugins/iv/scanner.cpp | 5 ++ src/osgPlugins/iv/scanner.l | 5 ++ 8 files changed, 101 insertions(+), 68 deletions(-) diff --git a/AUTHORS b/AUTHORS index a810bc082..dbc9b524d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -122,6 +122,9 @@ Ruben Lopez Pavel Moloshtan - Support for LWO2 format in the light wave loader. +Alberto Barbati + - lazy evaluation of the inverse in the MatrixTransform. + Indirect Contributors --------------------- diff --git a/include/osg/MatrixTransform b/include/osg/MatrixTransform index a0e94b16c..52b951a68 100644 --- a/include/osg/MatrixTransform +++ b/include/osg/MatrixTransform @@ -28,17 +28,28 @@ class SG_EXPORT MatrixTransform : public Transform META_Node(osg, MatrixTransform); /** Set the transform's matrix.*/ - void setMatrix(const Matrix& mat) { (*_matrix) = mat; _inverseDirty=true; computeInverse(); dirtyBound(); } + void setMatrix(const Matrix& mat) { (*_matrix) = mat; _inverseDirty=true; dirtyBound(); } - /** Get the transform's matrix. */ + /** Get the matrix. */ inline const Matrix& getMatrix() const { return *_matrix; } - /** preMult transform.*/ - void preMult(const Matrix& mat) { _matrix->preMult(mat); _inverseDirty=true; computeInverse(); dirtyBound(); } + /** pre multiply the transforms matrix.*/ + void preMult(const Matrix& mat) { _matrix->preMult(mat); _inverseDirty=true; dirtyBound(); } - /** postMult transform.*/ - void postMult(const Matrix& mat) { _matrix->postMult(mat); _inverseDirty=true; computeInverse(); dirtyBound(); } + /** post multiply the transforms matrix.*/ + void postMult(const Matrix& mat) { _matrix->postMult(mat); _inverseDirty=true; dirtyBound(); } + /** Get the inverse matrix. */ + inline const Matrix& getInverseMatrix() const + { + if (_inverseDirty) + { + _inverse->invert(*_matrix); + _inverseDirty = false; + } + return *_inverse; + } + virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const { if (_referenceFrame==RELATIVE_TO_PARENTS) @@ -54,13 +65,15 @@ class SG_EXPORT MatrixTransform : public Transform virtual const bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const { + const Matrix& inverse = getInverseMatrix(); + if (_referenceFrame==RELATIVE_TO_PARENTS) { - matrix.postMult(*_inverse); + matrix.postMult(inverse); } else // absolute { - matrix = *_inverse; + matrix = inverse; } return true; } @@ -69,18 +82,9 @@ class SG_EXPORT MatrixTransform : public Transform virtual ~MatrixTransform(); - inline void computeInverse() const - { - if (_inverseDirty) - { - _inverse->invert(*_matrix); - _inverseDirty = false; - } - } - ref_ptr _matrix; mutable ref_ptr _inverse; - mutable bool _inverseDirty; + mutable bool _inverseDirty; }; diff --git a/include/osg/Transform b/include/osg/Transform index de5b4f9c8..06f3d12b8 100644 --- a/include/osg/Transform +++ b/include/osg/Transform @@ -10,28 +10,34 @@ namespace osg { -/** Transform - is group node which all children are transformed by 4x4 matrix - * and is used for positioning objects within a scene, producing trackball functionality or for animation. - * Transform itself does not provide set/get functions, only the interface for - * defining what the 4x4 transformation is, sublcalsses, such as MatrixTransform - * and PositionAttitudeTransform support the use of a osg::Matrix or a osg::Vec3/osg::Quat - * resprectively. 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's 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 - * use of either GL_NORMALIZE and GL_SCALE_NORMALIZE modes. Further - * background reading see the glNormalize documentation in the OpenGL Reference - * Guide (the blue book). To enable it in the OSG, you simple need to - * attach a local osg::StateSet to the osg::Transform, and set the appropriate - * mode to on via stateset->setMode(GL_NORMALIZE,osg::StateAttribute::ON);. +/** A Transform is a group node for which all children are transformed by + * a 4x4 matrix. It is often used for positioning objects within a scene, + * producing trackball functionality or for animation. + * + * Transform itself does not provide set/get functions, only the interface + * for defining what the 4x4 transformation is. Subclasses, such as + * MatrixTransform and PositionAttitudeTransform support the use of an + * osg::Matrix or a osg::Vec3/osg::Quat resprectively. + * The Transform node can be customized via the ComputeTransfromCallback + * which can be attached to the node. This might be used to convert from + * internal representations of the transformation into generic osg::Matrix + * objects 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. This can be done transparently through OpenGL's + * use of either GL_NORMALIZE and GL_SCALE_NORMALIZE modes. For further + * background reading see the glNormalize documentation in the OpenGL + * Reference Guide (the blue book). To enable it in the OSG, you simply + * need to attach a local osg::StateSet to the osg::Transform, and set + * the appropriate mode to ON via + * stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON); */ class SG_EXPORT Transform : public Group { public : - Transform(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ @@ -48,32 +54,39 @@ class SG_EXPORT Transform : public Group RELATIVE_TO_ABSOLUTE }; - /** Set the transform's ReferenceFrame, either to be realtive to its parent reference frame, - * or relative to an absolute coordinate frame. RELATIVE_TO_PARENTS is the default. - * Note, setting the RefrenceFrame to be RELATIVE_TO_ABSOLUTE will also set the CullingActive flag on the - * transform, and hence all its parents, to false, therby disabling culling of it and all its - * parents. This is neccessary to prevent inappropriate culling, but may impact of cull times - * if the absolute transform is deep in the scene graph, it is therefore recommend to only use - * abolsoute Transforms at the top of the scene, for such things as headlight LightSource's or - * Head up displays.*/ + /** Set the transform's ReferenceFrame, either to be relative to its + * parent reference frame, or relative to an absolute coordinate + * frame. RELATIVE_TO_PARENTS is the default. + * Note: setting the ReferenceFrame to be RELATIVE_TO_ABSOLUTE will + * also set the CullingActive flag on the transform, and hence all + * of its parents, to false, thereby disabling culling of it and + * all its parents. This is neccessary to prevent inappropriate + * culling, but may impact cull times if the absolute transform is + * deep in the scene graph. It is therefore recommend to only use + * absolute Transforms at the top of the scene, for such things as + * headlight LightSources or Heads up displays. */ void setReferenceFrame(ReferenceFrame rf); const ReferenceFrame getReferenceFrame() const { return _referenceFrame; } - /** Callback attached to an Transform to specifiy how to compute the modelview transformation - * for the transform below the Transform node.*/ + /** Callback attached to an Transform to specify how to compute the + * modelview transformation for the transform below the Transform + * node. */ struct ComputeTransformCallback : public osg::Referenced { - /** Get the transformation matrix which moves from local coords to world coords.*/ + /** 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.*/ + /** 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; }; - /** Set the ComputerTransfromCallback which allows users to attach custom computation of the local transformation as - * seen by cull traversers and alike.*/ + /** Set the ComputerTransfromCallback which allows users to attach + * custom computation of the local transformation as seen by cull + * traversers and the like. */ void setComputeTransformCallback(ComputeTransformCallback* ctc) { _computeTransformCallback=ctc; dirtyBound(); } /** Get the non const ComputerTransfromCallback.*/ @@ -83,9 +96,9 @@ class SG_EXPORT Transform : public Group 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 updated. */ + /** Get the transformation matrix which moves from local coords to + * world coords. + * Returns true if the Matrix passed in has been updated. */ inline const bool getLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const { if (_computeTransformCallback.valid()) @@ -94,9 +107,9 @@ class SG_EXPORT Transform : public Group return computeLocalToWorldMatrix(matrix,nv); } - - /** Get the transformation matrix which moves from world coords to local coords. - * Return true if Matrix passed in has been updated. */ + /** Get the transformation matrix which moves from world coords to + * local coords. + * Return true if the Matrix passed in has been updated. */ inline const bool getWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const { if (_computeTransformCallback.valid()) @@ -105,7 +118,6 @@ class SG_EXPORT Transform : public Group return computeWorldToLocalMatrix(matrix,nv); } - #ifndef USE_DEPRECATED_API virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const @@ -142,10 +154,10 @@ class SG_EXPORT Transform : public Group /** Get the transform's matrix. */ inline const Matrix& getMatrix() const { return *_deprecated_matrix; } - /** preMult transform.*/ + /** preMult transform. */ void preMult(const Matrix& mat) { _deprecated_matrix->preMult(mat); _deprecated_inverseDirty=true; computeInverse(); dirtyBound(); } - /** postMult transform.*/ + /** postMult transform. */ void postMult(const Matrix& mat) { _deprecated_matrix->postMult(mat); _deprecated_inverseDirty=true; computeInverse(); dirtyBound(); } virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const @@ -175,19 +187,17 @@ class SG_EXPORT Transform : public Group } #endif - protected : virtual ~Transform(); - /** Override's Group's computeBound. - * There is no need to override in subclasses from osg::Transform since this computeBound() uses - * the underlying matrix (calling computeMatrix if required.) */ + /** Overrides Group's computeBound. + * There is no need to override in subclasses from osg::Transform + * since this computeBound() uses the underlying matrix (calling + * computeMatrix if required.) */ virtual const bool computeBound() const; - - ref_ptr _computeTransformCallback; ReferenceFrame _referenceFrame; diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index 5bc5c383a..2b930db58 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -672,9 +672,12 @@ void Viewer::display() // application traverasal. times[2].timeApp+=app(i); + // cull traverasal. times[2].timeCull+=cull(i); + if (_printStats>=1) glFinish(); + // draw traverasal. times[2].timeDraw+=draw(i); if (_printStats==Statistics::STAT_PRIMSPERVIEW) diff --git a/src/osgPlugins/iv/main.cpp b/src/osgPlugins/iv/main.cpp index c715a11f4..386a4b72e 100644 --- a/src/osgPlugins/iv/main.cpp +++ b/src/osgPlugins/iv/main.cpp @@ -33,14 +33,17 @@ extern int yyparse(); extern int yydebug; extern MyNode *getRoot(); extern FILE *yyin; - int isatty(int) { return 0; } +extern void flush_scanner(); osg::Node *readVRMLNode(const char *file) { yydebug=0; yyin=fopen(file,"r"); std::cout << "Parsing..." << std::endl; - if (yyparse()!=0) return 0; + if (yyparse()!=0) { + flush_scanner(); + return 0; + } osg::ref_ptr n=getRoot(); try { std::cout << "Generating OSG tree..." << std::endl; diff --git a/src/osgPlugins/iv/osgvisitor.cpp b/src/osgPlugins/iv/osgvisitor.cpp index 353a2ee7f..620fefcb9 100644 --- a/src/osgPlugins/iv/osgvisitor.cpp +++ b/src/osgPlugins/iv/osgvisitor.cpp @@ -225,10 +225,10 @@ void OSGVisitor::makeGeode(osg::Geode *geode, osg::Geometry *geometry, bool twoS state->setAttributeAndModes(frontface,osg::StateAttribute::ON); osg::CullFace *cull=new osg::CullFace(); cull->setMode(osg::CullFace::BACK); - if (twoSided) { + if (!twoSided) { state->setAttributeAndModes(cull,osg::StateAttribute::ON); } else { - std::cout << "Deactivating culling for this object" << std::endl; + //std::cout << "Deactivating culling for this object" << std::endl; state->setAttributeAndModes(cull,osg::StateAttribute::OFF); osg::Transparency *transp=new osg::Transparency(); transp->setFunction(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/osgPlugins/iv/scanner.cpp b/src/osgPlugins/iv/scanner.cpp index c7e7bf9ae..f6babfc78 100644 --- a/src/osgPlugins/iv/scanner.cpp +++ b/src/osgPlugins/iv/scanner.cpp @@ -2116,3 +2116,8 @@ int yywrap(void) { return (1); } + +void flush_scanner(void) { + yy_flush_buffer(YY_CURRENT_BUFFER); + +} diff --git a/src/osgPlugins/iv/scanner.l b/src/osgPlugins/iv/scanner.l index be00d9b0c..b5da303d8 100644 --- a/src/osgPlugins/iv/scanner.l +++ b/src/osgPlugins/iv/scanner.l @@ -84,3 +84,8 @@ int yywrap(void) { return (1); } + +void flush_scanner(void) { + yy_flush_buffer(YY_CURRENT_BUFFER); + +}