From 5eb65f65ccb61e904880dbfe42b1296f6bc1a330 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 6 Nov 2002 10:24:33 +0000 Subject: [PATCH] Added support for recording camera animation paths in osgGLUT::Viewer, and fixed the osgGA::AnimationPathManipulator to handle it. Added a new Drawable::ConstAttributeFunctor and make the accept(PrimitiveFunctor) be a const method so can disallows modification. Added Drawable::supports(...) methods for each of the AttributeFunctor, ConstAttributeFunctor and PrimitiveFunctor so that programs can querry whether it is possible to use functors with that object type. --- include/osg/AnimationPath | 9 +- include/osg/Drawable | 90 ++++++++++++++------ include/osg/GeoSet | 6 +- include/osg/Geometry | 14 +++- include/osg/ImpostorSprite | 17 +++- include/osg/Matrix | 2 +- include/osg/PrimitiveSet | 12 +-- include/osg/ProceduralGeometry | 15 +++- include/osg/Statistics | 8 +- include/osgGA/AnimationPathManipulator | 7 ++ include/osgGLUT/Viewer | 12 +++ src/Demos/sgv/sgv.cpp | 5 +- src/osg/AnimationPath.cpp | 4 +- src/osg/Drawable.cpp | 12 +-- src/osg/GeoSet.cpp | 26 +++++- src/osg/Geometry.cpp | 108 +++++++++++++++++++++--- src/osg/ImpostorSprite.cpp | 8 +- src/osg/PrimitiveSet.cpp | 12 +-- src/osg/ProceduralGeometry.cpp | 16 ++-- src/osgGA/AnimationPathManipulator.cpp | 45 +++++++--- src/osgGLUT/Viewer.cpp | 109 ++++++++++++++++++++----- 21 files changed, 422 insertions(+), 115 deletions(-) diff --git a/include/osg/AnimationPath b/include/osg/AnimationPath index 82e25f69f..7a32bd30f 100644 --- a/include/osg/AnimationPath +++ b/include/osg/AnimationPath @@ -108,12 +108,17 @@ class SG_EXPORT AnimationPath : public osg::Referenced LoopMode getLoopMode() const { return _loopMode; } + + typedef std::map TimeControlPointMap; + + TimeControlPointMap& getTimeControlPointMap() { return _timeControlPointMap; } + + const TimeControlPointMap& getTimeControlPointMap() const { return _timeControlPointMap; } + protected: virtual ~AnimationPath() {} - typedef std::map TimeControlPointMap; - TimeControlPointMap _timeControlPointMap; LoopMode _loopMode; diff --git a/include/osg/Drawable b/include/osg/Drawable index 1c970944d..1480a9495 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -284,22 +284,57 @@ class SG_EXPORT Drawable : public Object virtual void apply(AttributeType,unsigned int,Vec4*) {} virtual void apply(AttributeType,unsigned int,UByte4*) {} }; + + + /** return true if the Drawable subclass supports accept(AttributeFunctor&).*/ + virtual bool supports(AttributeFunctor&) const { return false; } - /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has. + * return true if functor handled by drawable, return false on failure of drawable to generate functor calls.*/ virtual void accept(AttributeFunctor&) {} + + class ConstAttributeFunctor + { + public: + + virtual ~ConstAttributeFunctor() {} + + virtual void apply(AttributeType,const unsigned int,const GLbyte*) {} + virtual void apply(AttributeType,const unsigned int,const GLshort*) {} + virtual void apply(AttributeType,const unsigned int,const GLint*) {} + + virtual void apply(AttributeType,const unsigned int,const GLubyte*) {} + virtual void apply(AttributeType,const unsigned int,const GLushort*) {} + virtual void apply(AttributeType,const unsigned int,const GLuint*) {} + + virtual void apply(AttributeType,const unsigned int,const float*) {} + virtual void apply(AttributeType,const unsigned int,const Vec2*) {} + virtual void apply(AttributeType,const unsigned int,const Vec3*) {} + virtual void apply(AttributeType,const unsigned int,const Vec4*) {} + virtual void apply(AttributeType,const unsigned int,const UByte4*) {} + }; + + /** return true if the Drawable subclass supports accept(ConstAttributeFunctor&).*/ + virtual bool supports(ConstAttributeFunctor&) const { return false; } + + /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has. + * return true if functor handled by drawable, return false on failure of drawable to generate functor calls.*/ + virtual void accept(ConstAttributeFunctor&) const {} + + class PrimitiveFunctor { public: virtual ~PrimitiveFunctor() {} - virtual void setVertexArray(unsigned int count,Vec3* vertices) = 0; + virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0; virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0; - virtual void drawElements(GLenum mode,GLsizei count,GLubyte* indices) = 0; - virtual void drawElements(GLenum mode,GLsizei count,GLushort* indices) = 0; - virtual void drawElements(GLenum mode,GLsizei count,GLuint* indices) = 0; + virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0; + virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0; + virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0; virtual void begin(GLenum mode) = 0; virtual void vertex(const Vec3& vert) = 0; @@ -308,9 +343,14 @@ class SG_EXPORT Drawable : public Object }; - /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ - virtual void accept(PrimitiveFunctor&) {} + /** return true if the Drawable subclass supports accept(PrimitiveFunctor&).*/ + virtual bool supports(PrimitiveFunctor&) const { return false; } + /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has. + * return true if functor handled by drawable, return false on failure of drawable to generate functor calls. + * Note, PrimtiveFunctor only provide const access of the primtives, as primitives may be procedurally generated + * so one cannot modify it.*/ + virtual void accept(PrimitiveFunctor&) const {} protected: @@ -422,7 +462,7 @@ public: virtual ~TriangleFunctor() {} - virtual void setVertexArray(unsigned int count,Vec3* vertices) + virtual void setVertexArray(unsigned int count,const Vec3* vertices) { _vertexArraySize = count; _vertexArrayPtr = vertices; @@ -436,14 +476,14 @@ public: { case(GL_TRIANGLES): { - Vec3* vlast = &_vertexArrayPtr[first+count]; - for(Vec3* vptr=&_vertexArrayPtr[first];vptr _vertexCache; diff --git a/include/osg/GeoSet b/include/osg/GeoSet index 53a36137c..82b0efc62 100644 --- a/include/osg/GeoSet +++ b/include/osg/GeoSet @@ -1,3 +1,4 @@ + //C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. @@ -332,8 +333,11 @@ class SG_EXPORT GeoSet : public Drawable /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ virtual void accept(AttributeFunctor& af); + /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(ConstAttributeFunctor& af) const; + /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ - virtual void accept(PrimitiveFunctor& pf); + virtual void accept(PrimitiveFunctor& pf) const; /** convinience function for converting GeoSet's to equivilant Geometry nodes.*/ Geometry* convertToGeometry(); diff --git a/include/osg/Geometry b/include/osg/Geometry index c807dd142..a3c64658d 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -163,11 +163,23 @@ class SG_EXPORT Geometry : public Drawable */ virtual void drawImmediateMode(State& state); + /** return true, osg::Geometry does support accept(AttributeFunctor&).*/ + virtual bool supports(AttributeFunctor&) const { return true; } + /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ virtual void accept(AttributeFunctor& af); + /** return true, osg::Geometry does support accept(ConstAttributeFunctor&).*/ + virtual bool supports(ConstAttributeFunctor&) const { return true; } + + /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(ConstAttributeFunctor& af) const; + + /** return true, osg::Geometry does support accept(PrimitiveFunctor&) .*/ + virtual bool supports(PrimitiveFunctor&) const { return true; } + /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ - virtual void accept(PrimitiveFunctor& pf); + virtual void accept(PrimitiveFunctor& pf) const; protected: diff --git a/include/osg/ImpostorSprite b/include/osg/ImpostorSprite index ca6e81de7..f92b4a8b1 100644 --- a/include/osg/ImpostorSprite +++ b/include/osg/ImpostorSprite @@ -116,11 +116,24 @@ class SG_EXPORT ImpostorSprite : public Drawable /** draw ImpostorSprite directly. */ virtual void drawImmediateMode(State& state); + /** return true, osg::ImpostorSprite does support accept(AttributeFunctor&).*/ + virtual bool supports(AttributeFunctor&) const { return true; } + /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ virtual void accept(AttributeFunctor& af); - + + /** return true, osg::ImpostorSprite does support accept(ConstAttributeFunctor&).*/ + virtual bool supports(ConstAttributeFunctor&) const { return true; } + + /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(ConstAttributeFunctor& af) const; + + /** return true, osg::ImpostorSprite does support accept(PrimitiveFunctor&) .*/ + virtual bool supports(PrimitiveFunctor&) const { return true; } + /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ - virtual void accept(PrimitiveFunctor& pf); + virtual void accept(PrimitiveFunctor& pf) const; + protected: diff --git a/include/osg/Matrix b/include/osg/Matrix index 920c4bebe..b9ff6e5c7 100644 --- a/include/osg/Matrix +++ b/include/osg/Matrix @@ -233,7 +233,7 @@ class SG_EXPORT Matrix : public Object // Matrix( const MatrixProduct& p ) //allows implicit evaluation of the product // { mult( p.A, p.B ); } - private: + protected: float _mat[4][4]; }; diff --git a/include/osg/PrimitiveSet b/include/osg/PrimitiveSet index e73edf430..059212d6b 100644 --- a/include/osg/PrimitiveSet +++ b/include/osg/PrimitiveSet @@ -123,7 +123,7 @@ class PrimitiveSet : public Object virtual void draw() const = 0; - virtual void accept(Drawable::PrimitiveFunctor&) {} + virtual void accept(Drawable::PrimitiveFunctor& functor) const = 0; virtual unsigned int index(unsigned int pos) const = 0; virtual unsigned int getNumIndices() const = 0; @@ -199,7 +199,7 @@ class SG_EXPORT DrawArrays : public PrimitiveSet virtual void draw() const; - virtual void accept(Drawable::PrimitiveFunctor& functor); + virtual void accept(Drawable::PrimitiveFunctor& functor) const; virtual unsigned int getNumIndices() const { return _count; } virtual unsigned int index(unsigned int pos) const { return _first+pos; } @@ -252,7 +252,7 @@ class SG_EXPORT DrawArrayLengths : public PrimitiveSet, public VectorSizei virtual void draw() const; - virtual void accept(Drawable::PrimitiveFunctor& functor); + virtual void accept(Drawable::PrimitiveFunctor& functor) const; virtual unsigned int getNumIndices() const; virtual unsigned int index(unsigned int pos) const { return _first+pos; } @@ -313,7 +313,7 @@ class SG_EXPORT DrawElementsUByte : public PrimitiveSet, public VectorUByte virtual void draw() const ; - virtual void accept(Drawable::PrimitiveFunctor& functor); + virtual void accept(Drawable::PrimitiveFunctor& functor) const; virtual unsigned int getNumIndices() const { return size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } @@ -353,7 +353,7 @@ class SG_EXPORT DrawElementsUShort : public PrimitiveSet, public VectorUShort virtual void draw() const; - virtual void accept(Drawable::PrimitiveFunctor& functor); + virtual void accept(Drawable::PrimitiveFunctor& functor) const; virtual unsigned int getNumIndices() const { return size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } @@ -392,7 +392,7 @@ class SG_EXPORT DrawElementsUInt : public PrimitiveSet, public VectorUInt virtual void draw() const; - virtual void accept(Drawable::PrimitiveFunctor& functor); + virtual void accept(Drawable::PrimitiveFunctor& functor) const; virtual unsigned int getNumIndices() const { return size(); } virtual unsigned int index(unsigned int pos) const { return (*this)[pos]; } diff --git a/include/osg/ProceduralGeometry b/include/osg/ProceduralGeometry index fb23696a8..463c7859b 100644 --- a/include/osg/ProceduralGeometry +++ b/include/osg/ProceduralGeometry @@ -126,11 +126,20 @@ class SG_EXPORT ProceduralGeometry : public Drawable */ virtual void drawImmediateMode(State& state); - /** accept an AttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ - virtual void accept(AttributeFunctor& af); + /** return false, osg::ProceduralGeoemtry does not support accept(AttributeFunctor&).*/ + virtual bool supports(AttributeFunctor&) const { return false; } + + /** return true, osg::ProceduralGeometry does support accept(ConstAttributeFunctor&).*/ + virtual bool supports(ConstAttributeFunctor&) const { return true; } + + /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/ + virtual void accept(ConstAttributeFunctor& af) const; + + /** return true, osg::ProceduralGeometry does support accept(PrimitiveFunctor&) .*/ + virtual bool supports(PrimitiveFunctor&) const { return true; } /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/ - virtual void accept(PrimitiveFunctor& pf); + virtual void accept(PrimitiveFunctor& pf) const; protected: diff --git a/include/osg/Statistics b/include/osg/Statistics index bbd3c85cb..0a0d99f82 100644 --- a/include/osg/Statistics +++ b/include/osg/Statistics @@ -64,12 +64,12 @@ class Statistics : public osg::Referenced, public osg::Drawable::PrimitiveFuncto void setType(statsType t) {stattype=t;} - virtual void setVertexArray(unsigned int count,Vec3*) { _vertexCount += count; } + virtual void setVertexArray(unsigned int count,const Vec3*) { _vertexCount += count; } virtual void drawArrays(GLenum mode,GLint,GLsizei count) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } - virtual void drawElements(GLenum mode,GLsizei count,GLubyte*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } - virtual void drawElements(GLenum mode,GLsizei count,GLushort*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } - virtual void drawElements(GLenum mode,GLsizei count,GLuint*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } + virtual void drawElements(GLenum mode,GLsizei count,const GLubyte*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } + virtual void drawElements(GLenum mode,GLsizei count,const GLushort*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } + virtual void drawElements(GLenum mode,GLsizei count,const GLuint*) { PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; prim.second+=count; } virtual void begin(GLenum mode) { _currentPrimtiveFunctorMode=mode; PrimitivePair& prim = _primitiveCount[mode]; ++prim.first; } virtual void vertex(const Vec3&) { PrimitivePair& prim = _primitiveCount[_currentPrimtiveFunctorMode]; ++prim.second; } diff --git a/include/osgGA/AnimationPathManipulator b/include/osgGA/AnimationPathManipulator index 0ffa48ffb..bfb26e7dd 100644 --- a/include/osgGA/AnimationPathManipulator +++ b/include/osgGA/AnimationPathManipulator @@ -39,6 +39,10 @@ class OSGGA_EXPORT AnimationPathManipulator : public CameraManipulator bool valid() const { return _animationPath.valid(); } + void init(const GUIEventAdapter& ea,GUIActionAdapter& us); + + void home(const GUIEventAdapter& ea,GUIActionAdapter& us); + virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us); private: @@ -48,6 +52,9 @@ class OSGGA_EXPORT AnimationPathManipulator : public CameraManipulator void handleFrame( double time ); osg::ref_ptr _animationPath; + + double _timeOffset; + double _timeScale; }; diff --git a/include/osgGLUT/Viewer b/include/osgGLUT/Viewer index 83c0eaad4..c86733129 100644 --- a/include/osgGLUT/Viewer +++ b/include/osgGLUT/Viewer @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -104,6 +105,14 @@ class OSGGLUT_EXPORT Viewer : public Window, public osgGA::GUIActionAdapter typedef std::vector > CameraManipList; typedef std::list > EventHandlerList; + + void setRecordingAnimationPath(bool on) { _recordingAnimationPath = on; } + bool getRecordingAnimationPath() const { return _recordingAnimationPath; } + + void setAnimationPath(osg::AnimationPath* path) { _animationPath = path; } + osg::AnimationPath* getAnimationPath() { return _animationPath.get(); } + const osg::AnimationPath* getAnimationPath() const { return _animationPath.get(); } + protected: virtual void clear(); @@ -177,6 +186,9 @@ class OSGGLUT_EXPORT Viewer : public Window, public osgGA::GUIActionAdapter osg::ref_ptr _frameStamp; osg::ref_ptr _displaySettings; + bool _recordingAnimationPath; + osg::ref_ptr _animationPath; + }; diff --git a/src/Demos/sgv/sgv.cpp b/src/Demos/sgv/sgv.cpp index e72b4bf7b..7b7a8ceb5 100644 --- a/src/Demos/sgv/sgv.cpp +++ b/src/Demos/sgv/sgv.cpp @@ -150,7 +150,10 @@ int main( int argc, char **argv ) if( !pathfile.empty() ) { osgGA::AnimationPathManipulator *apm = new osgGA::AnimationPathManipulator(pathfile); if( apm->valid() ) - viewer.registerCameraManipulator(apm); + { + unsigned int no = viewer.registerCameraManipulator(apm); + viewer.selectCameraManipulator(no); + } else delete apm; } diff --git a/src/osg/AnimationPath.cpp b/src/osg/AnimationPath.cpp index 7423e0328..6b8210ede 100644 --- a/src/osg/AnimationPath.cpp +++ b/src/osg/AnimationPath.cpp @@ -20,14 +20,14 @@ bool AnimationPath::getInterpolatedControlPoint(double time,ControlPoint& contro double fraction_part = modulated_time - floor(modulated_time); if (fraction_part>0.5) fraction_part = 1.0-fraction_part; - time = (fraction_part*2.0) * getPeriod(); + time = getFirstTime()+(fraction_part*2.0) * getPeriod(); break; } case(LOOP): { double modulated_time = (time - getFirstTime())/getPeriod(); double fraction_part = modulated_time - floor(modulated_time); - time = fraction_part * getPeriod(); + time = getFirstTime()+fraction_part * getPeriod(); break; } case(NO_LOOPING): diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index 3ed69667a..a3983889a 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -239,13 +239,13 @@ struct ComputeBound : public Drawable::PrimitiveFunctor { ComputeBound():_vertices(0) {} - virtual void setVertexArray(unsigned int,Vec3* vertices) { _vertices = vertices; } + virtual void setVertexArray(unsigned int,const Vec3* vertices) { _vertices = vertices; } virtual void drawArrays(GLenum,GLint first,GLsizei count) { if (_vertices) { - osg::Vec3* vert = _vertices+first; + const osg::Vec3* vert = _vertices+first; for(;count>0;--count,++vert) { _bb.expandBy(*vert); @@ -253,7 +253,7 @@ struct ComputeBound : public Drawable::PrimitiveFunctor } } - virtual void drawElements(GLenum,GLsizei count,GLubyte* indices) + virtual void drawElements(GLenum,GLsizei count,const GLubyte* indices) { if (_vertices) { @@ -264,7 +264,7 @@ struct ComputeBound : public Drawable::PrimitiveFunctor } } - virtual void drawElements(GLenum,GLsizei count,GLushort* indices) + virtual void drawElements(GLenum,GLsizei count,const GLushort* indices) { if (_vertices) { @@ -275,7 +275,7 @@ struct ComputeBound : public Drawable::PrimitiveFunctor } } - virtual void drawElements(GLenum,GLsizei count,GLuint* indices) + virtual void drawElements(GLenum,GLsizei count,const GLuint* indices) { if (_vertices) { @@ -291,7 +291,7 @@ struct ComputeBound : public Drawable::PrimitiveFunctor virtual void vertex(float x,float y,float z) { _bb.expandBy(x,y,z); } virtual void end() {} - Vec3* _vertices; + const Vec3* _vertices; BoundingBox _bb; }; diff --git a/src/osg/GeoSet.cpp b/src/osg/GeoSet.cpp index 94a6821b4..ebd34710e 100644 --- a/src/osg/GeoSet.cpp +++ b/src/osg/GeoSet.cpp @@ -880,8 +880,32 @@ void GeoSet::accept(AttributeFunctor& auf) } } +void GeoSet::accept(ConstAttributeFunctor& auf) const +{ + if (_numcoords == 0) computeNumVerts(); -void GeoSet::accept(PrimitiveFunctor& functor) + if (_coords && _numcoords) + { + auf.apply(VERTICES,_numcoords,_coords); + } + + if (_normals && _numnormals) + { + auf.apply(NORMALS,_numnormals,_normals); + } + + if (_colors && _numcolors) + { + auf.apply(COLORS,_numcolors,_colors); + } + + if (_tcoords && _numtcoords) + { + auf.apply(TEXTURE_COORDS_0,_numtcoords,_tcoords); + } +} + +void GeoSet::accept(PrimitiveFunctor& functor) const { // will easily convert into a Geometry. diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index 31a8ce698..2fc7e5cc8 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -842,22 +842,105 @@ void Geometry::drawImmediateMode(State& state) } +class AttrbuteFunctorArrayVisitor : public ArrayVisitor +{ + public: + + AttrbuteFunctorArrayVisitor(Drawable::AttributeFunctor& af): + _af(af) {} + + virtual ~AttrbuteFunctorArrayVisitor() {} + + virtual void apply(ByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(ShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(IntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(UByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(UShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(UIntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(UByte4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(FloatArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(Vec2Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(Vec3Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(Vec4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + + + inline void apply(Drawable::AttributeType type,Array* array) + { + if (array) + { + _type = type; + array->accept(*this); + } + } + + Drawable::AttributeFunctor& _af; + Drawable::AttributeType _type; +}; void Geometry::accept(AttributeFunctor& af) { - if (_vertexArray.valid() && !_vertexArray->empty()) - { - af.apply(VERTICES,_vertexArray->size(),&(_vertexArray->front())); - } + AttrbuteFunctorArrayVisitor afav(af); - if (_normalArray.valid() && !_normalArray->empty()) + afav.apply(VERTICES,_vertexArray.get()); + afav.apply(NORMALS,_normalArray.get()); + afav.apply(COLORS,_colorArray.get()); + + for(unsigned unit=0;unit<_texCoordList.size();++unit) { - af.apply(NORMALS,_normalArray->size(),&(_normalArray->front())); + afav.apply((AttributeType)(TEXTURE_COORDS_0+unit),_texCoordList[unit].first.get()); } - // need to add other attriubtes } -void Geometry::accept(PrimitiveFunctor& functor) +class ConstAttrbuteFunctorArrayVisitor : public ConstArrayVisitor +{ + public: + + ConstAttrbuteFunctorArrayVisitor(Drawable::ConstAttributeFunctor& af): + _af(af) {} + + virtual ~ConstAttrbuteFunctorArrayVisitor() {} + + virtual void apply(const ByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const ShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const IntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const UByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const UShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const UIntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const UByte4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const FloatArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const Vec2Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const Vec3Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + virtual void apply(const Vec4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); } + + + inline void apply(Drawable::AttributeType type,const Array* array) + { + if (array) + { + _type = type; + array->accept(*this); + } + } + + Drawable::ConstAttributeFunctor& _af; + Drawable::AttributeType _type; +}; + +void Geometry::accept(ConstAttributeFunctor& af) const +{ + ConstAttrbuteFunctorArrayVisitor afav(af); + + afav.apply(VERTICES,_vertexArray.get()); + afav.apply(NORMALS,_normalArray.get()); + afav.apply(COLORS,_colorArray.get()); + + for(unsigned unit=0;unit<_texCoordList.size();++unit) + { + afav.apply((AttributeType)(TEXTURE_COORDS_0+unit),_texCoordList[unit].first.get()); + } +} + +void Geometry::accept(PrimitiveFunctor& functor) const { if (!_vertexArray.valid() || _vertexArray->empty()) return; @@ -866,7 +949,7 @@ void Geometry::accept(PrimitiveFunctor& functor) { functor.setVertexArray(_vertexArray->size(),&(_vertexArray->front())); - for(PrimitiveSetList::iterator itr=_primitives.begin(); + for(PrimitiveSetList::const_iterator itr=_primitives.begin(); itr!=_primitives.end(); ++itr) { @@ -875,11 +958,11 @@ void Geometry::accept(PrimitiveFunctor& functor) } else { - for(PrimitiveSetList::iterator itr=_primitives.begin(); + for(PrimitiveSetList::const_iterator itr=_primitives.begin(); itr!=_primitives.end(); ++itr) { - PrimitiveSet* primitiveset = itr->get(); + const PrimitiveSet* primitiveset = itr->get(); GLenum mode=primitiveset->getMode(); switch(primitiveset->getType()) { @@ -977,7 +1060,8 @@ void Geometry::accept(PrimitiveFunctor& functor) } } } - } + } + return; } bool Geometry::verifyBindings() const diff --git a/src/osg/ImpostorSprite.cpp b/src/osg/ImpostorSprite.cpp index 43f82d652..9d6073589 100644 --- a/src/osg/ImpostorSprite.cpp +++ b/src/osg/ImpostorSprite.cpp @@ -121,7 +121,13 @@ void ImpostorSprite::accept(AttributeFunctor& af) af.apply(TEXTURE_COORDS_0,4,_texcoords); } -void ImpostorSprite::accept(PrimitiveFunctor& functor) +void ImpostorSprite::accept(ConstAttributeFunctor& af) const +{ + af.apply(VERTICES,4,_coords); + af.apply(TEXTURE_COORDS_0,4,_texcoords); +} + +void ImpostorSprite::accept(PrimitiveFunctor& functor) const { functor.setVertexArray(4,_coords); functor.drawArrays( GL_QUADS, 0, 4); diff --git a/src/osg/PrimitiveSet.cpp b/src/osg/PrimitiveSet.cpp index d6da45d3c..e9a0eaef1 100644 --- a/src/osg/PrimitiveSet.cpp +++ b/src/osg/PrimitiveSet.cpp @@ -7,7 +7,7 @@ void DrawArrays::draw() const glDrawArrays(_mode,_first,_count); } -void DrawArrays::accept(Drawable::PrimitiveFunctor& functor) +void DrawArrays::accept(Drawable::PrimitiveFunctor& functor) const { functor.drawArrays(_mode,_first,_count); } @@ -24,10 +24,10 @@ void DrawArrayLengths::draw() const } } -void DrawArrayLengths::accept(Drawable::PrimitiveFunctor& functor) +void DrawArrayLengths::accept(Drawable::PrimitiveFunctor& functor) const { GLint first = _first; - for(VectorSizei::iterator itr=begin(); + for(VectorSizei::const_iterator itr=begin(); itr!=end(); ++itr) { @@ -53,7 +53,7 @@ void DrawElementsUByte::draw() const glDrawElements(_mode,size(),GL_UNSIGNED_BYTE,&front()); } -void DrawElementsUByte::accept(Drawable::PrimitiveFunctor& functor) +void DrawElementsUByte::accept(Drawable::PrimitiveFunctor& functor) const { if (!empty()) functor.drawElements(_mode,size(),&front()); } @@ -74,7 +74,7 @@ void DrawElementsUShort::draw() const glDrawElements(_mode,size(),GL_UNSIGNED_SHORT,&front()); } -void DrawElementsUShort::accept(Drawable::PrimitiveFunctor& functor) +void DrawElementsUShort::accept(Drawable::PrimitiveFunctor& functor) const { if (!empty()) functor.drawElements(_mode,size(),&front()); } @@ -95,7 +95,7 @@ void DrawElementsUInt::draw() const glDrawElements(_mode,size(),GL_UNSIGNED_INT,&front()); } -void DrawElementsUInt::accept(Drawable::PrimitiveFunctor& functor) +void DrawElementsUInt::accept(Drawable::PrimitiveFunctor& functor) const { if (!empty()) functor.drawElements(_mode,size(),&front()); } diff --git a/src/osg/ProceduralGeometry.cpp b/src/osg/ProceduralGeometry.cpp index 20bfd4119..d945f4944 100644 --- a/src/osg/ProceduralGeometry.cpp +++ b/src/osg/ProceduralGeometry.cpp @@ -12,7 +12,7 @@ class DrawShapeVisitor : public ConstShapeVisitor { public: - DrawShapeVisitor(State& state,TessellationHints* hints): + DrawShapeVisitor(State& state,const TessellationHints* hints): _state(state), _hints(hints) {} @@ -29,7 +29,7 @@ class DrawShapeVisitor : public ConstShapeVisitor virtual void apply(const CompositeShape&); State& _state; - TessellationHints* _hints; + const TessellationHints* _hints; }; @@ -802,7 +802,7 @@ class PrimitiveShapeVisitor : public ConstShapeVisitor { public: - PrimitiveShapeVisitor(Drawable::PrimitiveFunctor& functor,TessellationHints* hints): + PrimitiveShapeVisitor(Drawable::PrimitiveFunctor& functor,const TessellationHints* hints): _functor(functor), _hints(hints) {} @@ -819,7 +819,7 @@ class PrimitiveShapeVisitor : public ConstShapeVisitor virtual void apply(const CompositeShape&); Drawable::PrimitiveFunctor& _functor; - TessellationHints* _hints; + const TessellationHints* _hints; }; @@ -1198,10 +1198,6 @@ void PrimitiveShapeVisitor::apply(const HeightField& field) float dx = field.getXInterval(); float dy = field.getYInterval(); - float du = 1.0f/((float)field.getNumColumns()-1.0f); - float dv = 1.0f/((float)field.getNumRows()-1.0f); - - float vBase = 0.0f; for(unsigned int row=0;rowgetFirstTime()-ea.time(); + } +} + +void AnimationPathManipulator::init(const GUIEventAdapter& ea,GUIActionAdapter& aa) +{ + home(ea,aa); +} + bool AnimationPathManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) { if( !valid() ) return false; @@ -49,6 +64,15 @@ bool AnimationPathManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GU retval = true; break; case GUIEventAdapter::KEYBOARD: + if (ea.getKey()==' ') + { + home(ea,us); + us.requestRedraw(); + us.requestContinuousUpdate(false); + return true; + } + return false; + retval = false; break; default: @@ -60,17 +84,14 @@ bool AnimationPathManipulator::handle(const osgGA::GUIEventAdapter& ea,osgGA::GU void AnimationPathManipulator::handleFrame( double time ) { osg::AnimationPath::ControlPoint cp; - _animationPath->getInterpolatedControlPoint( time, cp ); + _animationPath->getInterpolatedControlPoint( (time+_timeOffset)*_timeScale, cp ); - osg::Matrix mat; - cp.getMatrix( mat ); - - osg::Vec3 eye(mat(3,0), mat(3,1), mat(3,2)); - mat(3,0) = 0.0; - mat(3,1) = 0.0; - mat(3,2) = 0.0; - osg::Vec3 look = eye + (osg::Vec3(0,1,0) * mat); - osg::Vec3 up = osg::Vec3(0,0,1) * mat; - if( _camera.valid() ) - _camera->setView( eye, look, up ); + osg::Matrix matrix; + cp.getMatrix( matrix ); + + if (_camera.valid()) + { + _camera->home(); + _camera->transformLookAt(matrix); + } } diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index 819b68498..0fe48a30b 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -129,17 +129,7 @@ Viewer::Viewer() _displaySettings = osgNew osg::DisplaySettings; - - - - - - - - - - - + _recordingAnimationPath = false; } @@ -392,21 +382,34 @@ float Viewer::app(unsigned int viewport) ea->adaptFrame(_frameStamp->getReferenceTime()); bool handled = false; - for ( EventHandlerList::iterator eh = - _viewportList[viewport]._eventHandlerList.begin(); - eh != _viewportList[viewport]._eventHandlerList.end(); eh++ ) { - if ( eh->valid() ) { - if ( (*eh)->handle(*ea,*this) ) { + for (EventHandlerList::iterator eh = _viewportList[viewport]._eventHandlerList.begin(); + eh != _viewportList[viewport]._eventHandlerList.end(); + eh++ ) + { + if ( eh->valid() ) + { + if ( (*eh)->handle(*ea,*this) ) + { handled = true; break; } } } - if ( !handled ) { +// if ( !handled ) { _viewportList[viewport]._cameraManipulator->handle(*ea,*this); - } +// } + if (getRecordingAnimationPath() && getAnimationPath()) + { + osg::Camera* camera = getViewportSceneView(viewport)->getCamera(); + osg::Matrix matrix; + matrix.invert(camera->getModelViewMatrix()); + osg::Quat quat; + quat.set(matrix); + getAnimationPath()->insert(_frameStamp->getReferenceTime(),osg::AnimationPath::ControlPoint(matrix.getTrans(),quat)); + } + // do app traversal. getViewportSceneView(viewport)->setFrameStamp(_frameStamp.get()); @@ -912,7 +915,7 @@ void Viewer::keyboard(unsigned char key, int x, int y) if (key>='1' && key<='4') { int pos = key-'1'; - selectCameraManipulator(pos); + selectCameraManipulator(pos,_focusedViewport); } osgUtil::SceneView* sceneView = getViewportSceneView(_focusedViewport); @@ -1322,6 +1325,68 @@ void Viewer::keyboard(unsigned char key, int x, int y) } break; + case 'Z' : + case 'z' : + + if (getRecordingAnimationPath()) + { + // have already been recording so switch of recording. + setRecordingAnimationPath(false); + + osg::notify(osg::NOTICE) << "Finished recording camera animation, press 'Z' to reply."<< std::endl; + + if (getAnimationPath()) + { + std::ofstream fout("saved_animation.path"); + const AnimationPath::TimeControlPointMap& tcpm = getAnimationPath()->getTimeControlPointMap(); + for(AnimationPath::TimeControlPointMap::const_iterator tcpmitr=tcpm.begin(); + tcpmitr!=tcpm.end(); + ++tcpmitr) + { + const AnimationPath::ControlPoint& cp = tcpmitr->second; + fout<first<<" "<setLoopMode(osg::AnimationPath::LOOP); + osg::notify(osg::NOTICE) << "Recording camera animation, press 'z' to finish recording."<< std::endl; + } + + if (key=='Z') + { + osgGA::AnimationPathManipulator* apm = 0; + int apmNo = 0; + CameraManipList& cmlist = _viewportList[_focusedViewport]._cameraManipList; + for(CameraManipList::iterator cmlitr=cmlist.begin(); + cmlitr!=cmlist.end() && apm==0; + ++cmlitr,++apmNo) + { + apm = dynamic_cast(cmlitr->get()); + } + + if (!apm) + { + apm = new osgGA::AnimationPathManipulator(); + apmNo = registerCameraManipulator(apm,_focusedViewport); + } + + apm->setAnimationPath(getAnimationPath()); + apm->home(*ea,*this); + + selectCameraManipulator(apmNo,_focusedViewport); + } + + break; + case 27 : _exit = true; @@ -1412,6 +1477,12 @@ void Viewer::help(std::ostream& fout) <<" it just maximizes the window and leaves the window's borders."<< std::endl <<" If started in full screen mode on Linux, window will be borderless"<< std::endl <<" and will resize down, but will remain borderless."<< std::endl + << std::endl + <<"y Reduce fog density."<< std::endl + <<"Y Increase fog density."<< std::endl + << std::endl + <<"z Toggle recording of camera path."<< std::endl + <<"Z Reply recorded camera path."<< std::endl <<"Space Reset scene to the default view."<< std::endl <<"Esc Exit sgv."<< std::endl; }