diff --git a/examples/osghangglide/GliderManipulator.cpp b/examples/osghangglide/GliderManipulator.cpp index ffeff66fc..a65e59814 100644 --- a/examples/osghangglide/GliderManipulator.cpp +++ b/examples/osghangglide/GliderManipulator.cpp @@ -210,7 +210,7 @@ bool GliderManipulator::calcMovement() osg::Vec3 sv = _camera->getSideVector(); osg::Vec3 lv = _camera->getLookVector(); - float pitch = inDegrees(dy*70.0f*dt); + float pitch = inDegrees(-dy*70.0f*dt); float roll = inDegrees(dx*60.0f*dt); osg::Matrix mat; diff --git a/examples/osghud/osghud.cpp b/examples/osghud/osghud.cpp index 00a943152..8234fd93f 100644 --- a/examples/osghud/osghud.cpp +++ b/examples/osghud/osghud.cpp @@ -44,8 +44,8 @@ osg::Node* createHUD() geode->addDrawable( text ); text->setFont(timesFont); + text->setPosition(position); text->setText("Head Up Displays are simple :-)"); - text->setPosition(position); position += delta; } @@ -56,8 +56,9 @@ osg::Node* createHUD() geode->addDrawable( text ); text->setFont(timesFont); + text->setAutoScaleToScreen(true); + text->setPosition(position); text->setText("All you need to do is create your text in a subgraph."); - text->setPosition(position); position += delta; } @@ -68,8 +69,8 @@ osg::Node* createHUD() geode->addDrawable( text ); text->setFont(timesFont); + text->setPosition(position); text->setText("Disable depth test in this subgraph to ensure its always ontop."); - text->setPosition(position); position += delta; } @@ -79,8 +80,8 @@ osg::Node* createHUD() geode->addDrawable( text ); text->setFont(timesFont); + text->setPosition(position); text->setText("Then place an osg::Projection node above the subgraph\nto create an orthographic projection."); - text->setPosition(position); position += delta; } @@ -90,8 +91,8 @@ osg::Node* createHUD() geode->addDrawable( text ); text->setFont(timesFont); - text->setText("And add an osg::ModelViewMatrix set to ABSOLUTE to ensure\nit remains independent from any external model view matrices."); text->setPosition(position); + text->setText("And add an osg::ModelViewMatrix set to ABSOLUTE to ensure\nit remains independent from any external model view matrices."); position += delta; } diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 3fa768d80..a70dc766d 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -130,7 +130,7 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb) osgText::Text* text = new osgText::Text; text->setFont(font); - text->setFontSize(64,64); + text->setFontResolution(64,64); text->setAlignment(osgText::Text::CENTER_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin()))); @@ -157,7 +157,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb) osgText::Text* text = new osgText::Text; text->setFont(font); - text->setFontSize(110,120); + text->setFontResolution(110,120); text->setAlignment(osgText::Text::RIGHT_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); diff --git a/examples/osgtext/osgtext.cpp b/examples/osgtext/osgtext.cpp index 0feafe25f..63622f1d1 100644 --- a/examples/osgtext/osgtext.cpp +++ b/examples/osgtext/osgtext.cpp @@ -114,9 +114,9 @@ osg::Group* createHUDText() text->setPosition(cursor); // use text that uses 10 by 10 texels as a target resolution for fonts. - text->setFontSize(10,10); // blocky but small texture memory usage + text->setFontResolution(10,10); // blocky but small texture memory usage - text->setText("text->setFontSize(10,10); // blocky but small texture memory usage"); + text->setText("text->setFontResolution(10,10); // blocky but small texture memory usage"); geode->addDrawable(text); } @@ -129,9 +129,9 @@ osg::Group* createHUDText() text->setPosition(cursor); // use text that uses 10 by 10 texels as a target resolution for fonts. - text->setFontSize(20,20); // smoother but higher texture memory usage (but still quite low). + text->setFontResolution(20,20); // smoother but higher texture memory usage (but still quite low). - text->setText("text->setFontSize(20,20); // smoother but higher texture memory usage (but still quite low)."); + text->setText("text->setFontResolution(20,20); // smoother but higher texture memory usage (but still quite low)."); geode->addDrawable(text); } @@ -144,9 +144,9 @@ osg::Group* createHUDText() text->setPosition(cursor); // use text that uses 10 by 10 texels as a target resolution for fonts. - text->setFontSize(40,40); // even smoother but again higher texture memory usage. + text->setFontResolution(40,40); // even smoother but again higher texture memory usage. - text->setText("text->setFontSize(40,40); // even smoother but again higher texture memory usage."); + text->setText("text->setFontResolution(40,40); // even smoother but again higher texture memory usage."); geode->addDrawable(text); } @@ -164,7 +164,7 @@ osg::Group* createHUDText() osgText::Text* text = new osgText::Text; text->setFont(font); text->setColor(characterSizeColor); - text->setFontSize(20,20); + text->setFontResolution(20,20); text->setPosition(cursor); // use text that 20 units high. @@ -179,7 +179,7 @@ osg::Group* createHUDText() osgText::Text* text = new osgText::Text; text->setFont(font); text->setColor(characterSizeColor); - text->setFontSize(30,30); + text->setFontResolution(30,30); text->setPosition(cursor); // use text that 20 units high. @@ -194,7 +194,7 @@ osg::Group* createHUDText() osgText::Text* text = new osgText::Text; text->setFont(font); text->setColor(characterSizeColor); - text->setFontSize(40,40); + text->setFontResolution(40,40); text->setPosition(cursor); // use text that uses 10 by 10 texels as a target resolution for fonts. diff --git a/include/osg/Drawable b/include/osg/Drawable index cb9824680..782369d35 100644 --- a/include/osg/Drawable +++ b/include/osg/Drawable @@ -192,24 +192,6 @@ class SG_EXPORT Drawable : public Object /** Get the non const UpdateCallback.*/ UpdateCallback* getUpdateCallback() { return _updateCallback.get(); } -#ifdef USE_DEPRECATED_API - struct AppCallback : public UpdateCallback - { - /** do customized app code.*/ - virtual void app(osg::NodeVisitor *visitor, osg::Drawable* drawable) = 0; - - virtual void update(osg::NodeVisitor *visitor, osg::Drawable* drawable) { app(visitor,drawable); } - }; - - /** deprecated.*/ - void setAppCallback(AppCallback* ac) { setUpdateCallback(ac); } - - /** deprecated.*/ - AppCallback* getAppCallback() { return getUpdateCallback(); } - - /** deprecated.*/ - const AppCallback* getAppCallback() const { return getUpdateCallback(); } -#endif struct CullCallback : public virtual osg::Referenced { diff --git a/include/osg/Export b/include/osg/Export index 2178966f9..ba3303057 100644 --- a/include/osg/Export +++ b/include/osg/Export @@ -17,7 +17,7 @@ // define used to include in API which is being fazed out // if you can compile your apps with this turned off you are // well placed for compatablity with future versions. -//#define USE_DEPRECATED_API +#define USE_DEPRECATED_API #if defined(_MSC_VER) #pragma warning( disable : 4244 ) @@ -56,13 +56,4 @@ #endif #endif -#ifdef USE_DEPRECATED_API - - #define osgNew new - #define osgDelete delete - #define osgFree free - #define osgMalloc malloc - -#endif - #endif diff --git a/include/osg/Node b/include/osg/Node index 1363f1364..3f1eeaecf 100644 --- a/include/osg/Node +++ b/include/osg/Node @@ -135,17 +135,6 @@ class SG_EXPORT Node : public Object /** Get const update node callback, called during update traversal. */ inline const NodeCallback* getUpdateCallback() const { return _updateCallback.get(); } -#ifdef USE_DEPRECATED_API - /** deprecated. */ - void setAppCallback(NodeCallback* nc) { setUpdateCallback(nc); } - - /** deprecated. */ - inline NodeCallback* getAppCallback() { return getUpdateCallback(); } - - /** deprecated. */ - inline const NodeCallback* getAppCallback() const { return getUpdateCallback(); } -#endif - /** Get the number of Children of this node which require App traversal, * since they have an AppCallback attached to them or their children.*/ inline unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; } diff --git a/include/osg/Texture2D b/include/osg/Texture2D index 905e0d759..41aa6b4f3 100644 --- a/include/osg/Texture2D +++ b/include/osg/Texture2D @@ -89,10 +89,10 @@ class SG_EXPORT Texture2D : public Texture /** Set the number of mip map levels the the texture has been created with, should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/ - void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; } + void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; } /** Get the number of mip map levels the the texture has been created with.*/ - unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } + unsigned int getNumMipmapLevels() const { return _numMipmapLevels; } /** Copy pixels into a 2D texture image.As per glCopyTexImage2D. @@ -132,7 +132,7 @@ class SG_EXPORT Texture2D : public Texture mutable GLsizei _textureWidth, _textureHeight; // number of mip map levels the the texture has been created with, - mutable GLsizei _numMimpmapLevels; + mutable GLsizei _numMipmapLevels; ref_ptr _subloadCallback; diff --git a/include/osg/TextureCubeMap b/include/osg/TextureCubeMap index f94b61c2f..60af5a80d 100644 --- a/include/osg/TextureCubeMap +++ b/include/osg/TextureCubeMap @@ -99,10 +99,10 @@ class SG_EXPORT TextureCubeMap : public Texture /** Set the number of mip map levels the the texture has been created with, should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/ - void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; } + void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; } /** Get the number of mip map levels the the texture has been created with.*/ - unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; } + unsigned int getNumMipmapLevels() const { return _numMipmapLevels; } /** On first apply (unless already compiled), create the minmapped * texture and bind it, subsequent apply will simple bind to texture.*/ @@ -162,7 +162,7 @@ class SG_EXPORT TextureCubeMap : public Texture mutable GLsizei _textureWidth, _textureHeight; // number of mip map levels the the texture has been created with, - mutable GLsizei _numMimpmapLevels; + mutable GLsizei _numMipmapLevels; ref_ptr _subloadCallback; diff --git a/include/osgText/Text b/include/osgText/Text index 76fe33111..08c6ff0dc 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -48,11 +48,20 @@ public: /** Get the font. Return 0 if default is being used.*/ const Font* getFont() const { return _font.get(); } +#ifdef USE_DEPRECATED_API + + /* deprecated */ + void setFontSize(unsigned int width, unsigned int height) + { + setFontResolution(width,height); + } +#endif + /** Set the Font reference width and height resolution in texels. * Note, the size may not be supported by current font, * the closest supported font size will be selected.*/ - void setFontSize(unsigned int width, unsigned int height); - + void setFontResolution(unsigned int width, unsigned int height); + unsigned int getFontWidth() const { return _fontWidth; } unsigned int getFontHeight() const { return _fontWidth; } @@ -142,7 +151,6 @@ public: }; void setAlignment(AlignmentType alignment); - AlignmentType getAlignment() const { return _alignment; } @@ -156,13 +164,22 @@ public: void setAxisAlignment(AxisAlignment axis); - AxisAlignment getAxisAlignment() const { return _axisAlignment; } - - void setRotation(const osg::Quat& quat); - const osg::Quat& getRotation() const { return _rotation; } + void setAutoUpdateEyeMovementTolerance(float tolerance) { _autoUpdateEyeMovementTolerance = tolerance; } + float getAutoUpdateEyeMovementTolerance() const { return _autoUpdateEyeMovementTolerance; } + + void setAutoRotateToScreen(bool autoRotateToScreen); + bool getAutoRotateToScreen() const { return _autoRotateToScreen; } + + void setAutoScaleToScreen(bool autoScaleToScreen); + bool getAutoScaleToScreen() const { return _autoScaleToScreen; } + + void setScale(float scale); + float getScale() const { return _scale; } + + enum Layout { @@ -215,6 +232,40 @@ public: // make Font a friend to allow it set the _font to 0 if the font is // forcefully unloaded. friend class Font; +public: + + // internal structures, variable and methods used for rendering of characters. + struct OSGTEXT_EXPORT GlyphQuads + { + typedef std::vector Coords2; + typedef std::vector Coords3; + typedef std::vector TexCoords; + + Coords2 _coords; + Coords3 _transformedCoords; + TexCoords _texcoords; + + Coords2& getCoords() { return _coords; } + const Coords2& getCoords() const { return _coords; } + + Coords3& getTransformedCoords() { return _transformedCoords; } + const Coords3& getTransformedCoords() const { return _transformedCoords; } + + TexCoords& getTexCoords() { return _texcoords; } + const TexCoords& getTexCoords() const { return _texcoords; } + }; + + typedef std::map,GlyphQuads> TextureGlyphQuadMap; + + /** Direct Access to GlyphQuads */ + const GlyphQuads* getGlyphQuad(unsigned int index) const + { + if (index>=_textureGlyphQuadMap.size()) return NULL; + + TextureGlyphQuadMap::const_iterator itGlyph = _textureGlyphQuadMap.begin(); + while((index--) && (itGlyph!=_textureGlyphQuadMap.end())) itGlyph++; + return &itGlyph->second; + } protected: @@ -238,44 +289,15 @@ protected: String _text; osg::Vec3 _position; AlignmentType _alignment; - AxisAlignment _axisAlignment; + float _scale; osg::Quat _rotation; + float _autoUpdateEyeMovementTolerance; + bool _autoRotateToScreen; + bool _autoScaleToScreen; Layout _layout; osg::Vec4 _color; unsigned int _drawMode; -public: - - // internal structures, variable and methods used for rendering of characters. - struct OSGTEXT_EXPORT GlyphQuads - { - typedef std::vector Coords; - typedef std::vector TexCoords; - - Coords _coords; - TexCoords _texcoords; - - Coords& getCoords() { return _coords; } - const Coords& getCoords() const { return _coords; } - - TexCoords& getTexCoords() { return _texcoords; } - const TexCoords& getTexCoords() const { return _texcoords; } - }; - - typedef std::map,GlyphQuads> TextureGlyphQuadMap; - - /** Direct Access to GlyphQuads */ - const GlyphQuads* getGlyphQuad(unsigned int index) const - { - if (index>=_textureGlyphQuadMap.size()) return NULL; - - TextureGlyphQuadMap::const_iterator itGlyph = _textureGlyphQuadMap.begin(); - while((index--) && (itGlyph!=_textureGlyphQuadMap.end())) itGlyph++; - return &itGlyph->second; - } - -protected: - // iternal map used for rendering. Set up by the computeGlyphRepresentation() method. TextureGlyphQuadMap _textureGlyphQuadMap; @@ -284,7 +306,10 @@ protected: // internal caches of the positioning of the text. osg::Matrix _matrix; osg::Vec3 _offset; + osg::Vec3 _normal; mutable osg::BoundingBox _textBB; + + void setUpAutoCallback(); void computePositions(); diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index 8f2516a18..7ced37853 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -23,7 +23,7 @@ using namespace osg; Texture2D::Texture2D(): _textureWidth(0), _textureHeight(0), - _numMimpmapLevels(0) + _numMipmapLevels(0) { setUseHardwareMipMapGeneration(true); } @@ -33,7 +33,7 @@ Texture2D::Texture2D(const Texture2D& text,const CopyOp& copyop): _image(copyop(text._image.get())), _textureWidth(text._textureWidth), _textureHeight(text._textureHeight), - _numMimpmapLevels(text._numMimpmapLevels), + _numMipmapLevels(text._numMipmapLevels), _subloadCallback(text._subloadCallback) { } @@ -109,7 +109,7 @@ void Texture2D::apply(State& state) const else if (_image.valid() && getModifiedTag(contextID) != _image->getModifiedTag()) { applyTexImage2D_subload(GL_TEXTURE_2D,_image.get(),state, - _textureWidth, _textureHeight, _numMimpmapLevels); + _textureWidth, _textureHeight, _numMipmapLevels); // update the modified tag to show that it is upto date. getModifiedTag(contextID) = _image->getModifiedTag(); @@ -143,7 +143,7 @@ void Texture2D::apply(State& state) const applyTexParameters(GL_TEXTURE_2D,state); applyTexImage2D_load(GL_TEXTURE_2D,_image.get(),state, - _textureWidth, _textureHeight, _numMimpmapLevels); + _textureWidth, _textureHeight, _numMipmapLevels); // update the modified tag to show that it is upto date. getModifiedTag(contextID) = _image->getModifiedTag(); diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index 372a2c184..be99be309 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -89,7 +89,7 @@ static GLenum faceTarget[6] = TextureCubeMap::TextureCubeMap(): _textureWidth(0), _textureHeight(0), - _numMimpmapLevels(0) + _numMipmapLevels(0) { setUseHardwareMipMapGeneration(false); } @@ -98,7 +98,7 @@ TextureCubeMap::TextureCubeMap(const TextureCubeMap& text,const CopyOp& copyop): Texture(text,copyop), _textureWidth(text._textureWidth), _textureHeight(text._textureHeight), - _numMimpmapLevels(text._numMimpmapLevels), + _numMipmapLevels(text._numMipmapLevels), _subloadCallback(text._subloadCallback) { _images[0] = copyop(text._images[0].get()); @@ -224,7 +224,7 @@ void TextureCubeMap::apply(State& state) const const osg::Image* image = _images[n].get(); if (image && getModifiedTag((Face)n,contextID) != image->getModifiedTag()) { - applyTexImage2D_subload( faceTarget[n], _images[n].get(), state, _textureWidth, _textureHeight, _numMimpmapLevels); + applyTexImage2D_subload( faceTarget[n], _images[n].get(), state, _textureWidth, _textureHeight, _numMipmapLevels); getModifiedTag((Face)n,contextID) = image->getModifiedTag(); } } @@ -260,7 +260,7 @@ void TextureCubeMap::apply(State& state) const const osg::Image* image = _images[n].get(); if (image) { - applyTexImage2D_load( faceTarget[n], image, state, _textureWidth, _textureHeight, _numMimpmapLevels); + applyTexImage2D_load( faceTarget[n], image, state, _textureWidth, _textureHeight, _numMipmapLevels); getModifiedTag((Face)n,contextID) = image->getModifiedTag(); } diff --git a/src/osgPlugins/osgText/IO_Text.cpp b/src/osgPlugins/osgText/IO_Text.cpp index 3c3fae9a4..8ae8ec8b8 100644 --- a/src/osgPlugins/osgText/IO_Text.cpp +++ b/src/osgPlugins/osgText/IO_Text.cpp @@ -38,13 +38,13 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) } - if (fr[0].matchWord("fontSize")) + if (fr[0].matchWord("fontResolution") || fr[0].matchWord("fontSize")) { unsigned int width; unsigned int height; if (fr[1].getUInt(width) && fr[2].getUInt(height)) { - text.setFontSize(width,height); + text.setFontResolution(width,height); fr += 3; itAdvanced = true; } @@ -127,6 +127,38 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) } } + if (fr.matchSequence("scale %f")) + { + float scale; + fr[1].getFloat(scale); + text.setScale(scale); + fr += 2; + itAdvanced = true; + } + + if (fr.matchSequence("autoUpdateEyeMovementTolerance %f")) + { + float scale; + fr[1].getFloat(scale); + text.setAutoUpdateEyeMovementTolerance(scale); + fr += 2; + itAdvanced = true; + } + + if (fr.matchSequence("autoRotateToScreen TRUE")) + { + text.setAutoRotateToScreen(true); + fr += 2; + itAdvanced = true; + } + + if (fr.matchSequence("autoScaleToScreen TRUE")) + { + text.setAutoScaleToScreen(true); + fr += 2; + itAdvanced = true; + } + if (fr.matchSequence("layout %w")) { std::string str = fr[1].getStr(); @@ -226,7 +258,7 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) } // font resolution - fw.indent() << "fontSize " << text.getFontWidth() << " " << text.getFontHeight() << std::endl; + fw.indent() << "fontResolution " << text.getFontWidth() << " " << text.getFontHeight() << std::endl; // charater size. fw.indent() << "characterSize " << text.getCharacterHeight() << " " << text.getCharacterAspectRatio() << std::endl; @@ -264,21 +296,30 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) }; - // axis alignment - fw.indent() << "axisAlignment "; - switch(text.getAxisAlignment()) - { - case osgText::Text::XY_PLANE: fw << "XY_PLANE" << std::endl; break; - case osgText::Text::XZ_PLANE: fw << "XZ_PLANE" << std::endl; break; - case osgText::Text::YZ_PLANE: fw << "YZ_PLANE" << std::endl; break; - case osgText::Text::SCREEN: fw << "SCREEN" << std::endl; break; - }; - if (!text.getRotation().zeroRotation()) { fw.indent() << "rotation " << text.getRotation() << std::endl; } + if (text.getScale()!=1.0f) + { + fw.indent() << "scale " << text.getScale() << std::endl; + } + + if (text.getAutoUpdateEyeMovementTolerance()!=0.0f) + { + fw.indent() << "autoUpdateEyeMovementTolerance " << text.getAutoUpdateEyeMovementTolerance() << std::endl; + } + + if (text.getAutoRotateToScreen()) + { + fw.indent() << "autoRotateToScreen TRUE"<< std::endl; + } + + if (text.getAutoScaleToScreen()) + { + fw.indent() << "autoScaleToScreen TRUE"<< std::endl; + } // layout fw.indent() << "layout "; diff --git a/src/osgProducer/ViewerEventHandler.cpp b/src/osgProducer/ViewerEventHandler.cpp index 9ad53ccbe..35fea8cdb 100644 --- a/src/osgProducer/ViewerEventHandler.cpp +++ b/src/osgProducer/ViewerEventHandler.cpp @@ -226,7 +226,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createHelpText() osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorDescription); - text->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(posDescription); text->setMaximumWidth(maxWidthOfDisplayRegion); @@ -252,7 +252,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createHelpText() osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorOption); - text->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(posOption); text->setAlignment(osgText::Text::BASE_LINE); @@ -279,7 +279,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createHelpText() osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorExplanation); - text->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(posExplanation); text->setMaximumWidth(maxWidth); @@ -613,7 +613,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() osgText::Text* text = new osgText::Text; text->setFont("fonts/arial.ttf"); text->setColor(colorUpdate); - text->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + text->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); text->setCharacterSize(characterSize); text->setPosition(pos); text->setAlignment(osgText::Text::BASE_LINE); @@ -627,7 +627,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() _updateTimeText->setFont("fonts/arial.ttf"); _updateTimeText->setColor(colorUpdate); - _updateTimeText->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + _updateTimeText->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); _updateTimeText->setCharacterSize(characterSize); _updateTimeText->setPosition(pos); _updateTimeText->setAlignment(osgText::Text::BASE_LINE); @@ -650,7 +650,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() osgText::Text* cullLabel = new osgText::Text; cullLabel->setFont("fonts/arial.ttf"); cullLabel->setColor(colorCull); - cullLabel->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + cullLabel->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); cullLabel->setCharacterSize(characterSize); cullLabel->setPosition(pos); cullLabel->setAlignment(osgText::Text::BASE_LINE); @@ -664,7 +664,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() cullField->setFont("fonts/arial.ttf"); cullField->setColor(colorCull); - cullField->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + cullField->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); cullField->setCharacterSize(characterSize); cullField->setPosition(pos); cullField->setAlignment(osgText::Text::BASE_LINE); @@ -680,7 +680,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() osgText::Text* drawLabel = new osgText::Text; drawLabel->setFont("fonts/arial.ttf"); drawLabel->setColor(colorDraw); - drawLabel->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + drawLabel->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); drawLabel->setCharacterSize(characterSize); drawLabel->setPosition(pos); drawLabel->setAlignment(osgText::Text::BASE_LINE); @@ -694,7 +694,7 @@ void ViewerEventHandler::StatsAndHelpDrawCallback::createStatsText() drawField->setFont("fonts/arial.ttf"); drawField->setColor(colorDraw); - drawField->setFontSize((unsigned int)characterSize,(unsigned int)characterSize); + drawField->setFontResolution((unsigned int)characterSize,(unsigned int)characterSize); drawField->setCharacterSize(characterSize); drawField->setPosition(pos); drawField->setAlignment(osgText::Text::BASE_LINE); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7cc840832..9ec10f85d 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -14,12 +14,91 @@ #include #include +#include #include #include "DefaultFont.h" using namespace osgText; +struct TextCullCallback : public osg::Drawable::CullCallback +{ + + TextCullCallback(osgText::Text* text): + _firstTimeToInitEyePoint(true), + _previousWidth(0), + _previousHeight(0), + _text(text) {} + + /** do customized cull code.*/ + virtual bool cull(osg::NodeVisitor *nv, osg::Drawable*, osg::State*) const + { + osgUtil::CullVisitor* cs = static_cast(nv); + if (!cs) return false; + + int width = _previousWidth; + int height = _previousHeight; + + osg::Viewport* viewport = cs->getViewport(); + if (viewport) + { + width = viewport->width(); + height = viewport->height(); + } + + osg::Vec3 eyePoint = cs->getEyeLocal(); + + bool doUpdate = _firstTimeToInitEyePoint; + if (!_firstTimeToInitEyePoint) + { + osg::Vec3 dv = _previousEyePoint-eyePoint; + if (dv.length2()>_text->getAutoUpdateEyeMovementTolerance()*(eyePoint-_text->getPosition()).length2()) + { + doUpdate = true; + } + else if (width!=_previousWidth || height!=_previousHeight) + { + doUpdate = true; + } + } + _firstTimeToInitEyePoint = false; + + if (doUpdate) + { + + if (_text->getAutoScaleToScreen()) + { + float size = 1.0f/cs->pixelSize(_text->getPosition(),1.0f); + _text->setScale(size); + } + + if (_text->getAutoRotateToScreen()) + { + osg::Quat rotation; + rotation.set(cs->getModelViewMatrix()); + _text->setRotation(rotation.inverse()); + } + + _previousEyePoint = eyePoint; + _previousWidth = width; + _previousHeight = height; + + } + + return false; + } + + + mutable bool _firstTimeToInitEyePoint; + mutable osg::Vec3 _previousEyePoint; + mutable int _previousWidth; + mutable int _previousHeight; + mutable osgText::Text* _text; + +}; + + + Text::Text(): _fontWidth(32), _fontHeight(32), @@ -28,8 +107,11 @@ Text::Text(): _maximumWidth(0.0f), _maximumHeight(0.0f), _alignment(BASE_LINE), - _axisAlignment(XY_PLANE), _rotation(), + _scale(1.0f), + _autoUpdateEyeMovementTolerance(0.0f), + _autoRotateToScreen(false), + _autoScaleToScreen(false), _layout(LEFT_TO_RIGHT), _color(1.0f,1.0f,1.0f,1.0f), _drawMode(TEXT) @@ -49,12 +131,17 @@ Text::Text(const Text& text,const osg::CopyOp& copyop): _text(text._text), _position(text._position), _alignment(text._alignment), - _axisAlignment(text._axisAlignment), _rotation(text._rotation), + _scale(text._scale), + _autoUpdateEyeMovementTolerance(text._autoUpdateEyeMovementTolerance), + _autoRotateToScreen(text._autoRotateToScreen), + _autoScaleToScreen(text._autoScaleToScreen), _layout(text._layout), _color(text._color), _drawMode(text._drawMode) { + setUpAutoCallback(); + computeGlyphRepresentation(); } Text::~Text() @@ -75,7 +162,7 @@ void Text::setFont(const std::string& fontfile) setFont(readFontFile(fontfile)); } -void Text::setFontSize(unsigned int width, unsigned int height) +void Text::setFontResolution(unsigned int width, unsigned int height) { _fontWidth = width; _fontHeight = height; @@ -142,8 +229,28 @@ void Text::setAlignment(AlignmentType alignment) void Text::setAxisAlignment(AxisAlignment axis) { - _axisAlignment = axis; - computePositions(); + switch(axis) + { + case XZ_PLANE: + setRotation(osg::Quat(osg::inDegrees(90.0f),osg::Vec3(1.0f,0.0f,0.0f))); + break; + case YZ_PLANE: + setRotation(osg::Quat(osg::inDegrees(90.0f),osg::Vec3(1.0f,0.0f,0.0f))* + osg::Quat(osg::inDegrees(90.0f),osg::Vec3(0.0f,0.0f,1.0f))); + break; + case XY_PLANE: + setRotation(osg::Quat()); // nop - already on XY plane. + break; + case SCREEN: + setAutoRotateToScreen(true); + break; + } +} + +void Text::setAutoRotateToScreen(bool autoRotateToScreen) +{ + _autoRotateToScreen = autoRotateToScreen; + setUpAutoCallback(); } void Text::setRotation(const osg::Quat& quat) @@ -152,6 +259,31 @@ void Text::setRotation(const osg::Quat& quat) computePositions(); } +void Text::setAutoScaleToScreen(bool autoScaleToScreen) +{ + _autoScaleToScreen = autoScaleToScreen; + setUpAutoCallback(); +} + +void Text::setScale(float scale) +{ + _scale = scale; + setUpAutoCallback(); + computePositions(); +} + +void Text::setUpAutoCallback() +{ + if (_autoRotateToScreen || _autoScaleToScreen) + { + if (!getCullCallback()) + { + setCullCallback(new TextCullCallback(this)); + } + } + else setCullCallback(0); +} + void Text::setLayout(Layout layout) { _layout = layout; @@ -169,33 +301,10 @@ bool Text::computeBound() const if (_textBB.valid()) { - if (_axisAlignment==SCREEN) - { - // build a sphere around the text box, centerd at the offset point. - float maxlength2 = (_textBB.corner(0)-_offset).length2(); - - float length2 = (_textBB.corner(1)-_offset).length2(); - maxlength2 = osg::maximum(maxlength2,length2); - - length2 = (_textBB.corner(2)-_offset).length2(); - maxlength2 = osg::maximum(maxlength2,length2); - - length2 = (_textBB.corner(3)-_offset).length2(); - maxlength2 = osg::maximum(maxlength2,length2); - - float radius = sqrtf(maxlength2); - osg::Vec3 center(_position); - - _bbox.set(center.x()-radius,center.y()-radius,center.z()-radius, - center.x()+radius,center.y()+radius,center.z()+radius); - } - else - { - _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*_matrix); - _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*_matrix); - _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*_matrix); - _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*_matrix); - } + _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*_matrix); + _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*_matrix); + _bbox.expandBy(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*_matrix); + _bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*_matrix); } _bbox_computed = true; @@ -384,7 +493,7 @@ void Text::computeGlyphRepresentation() { const GlyphQuads& glyphquad = titr->second; - for(GlyphQuads::Coords::const_iterator citr = glyphquad._coords.begin(); + for(GlyphQuads::Coords2::const_iterator citr = glyphquad._coords.begin(); citr != glyphquad._coords.end(); ++citr) { @@ -421,32 +530,47 @@ void Text::computePositions() case RIGHT_BASE_LINE: _offset.set((_textBB.xMax()+_textBB.xMin()),0.0f,0.0f); break; } - // adjust offset for axis alignment - switch(_axisAlignment) + if (_scale!=1.0f || !_rotation.zeroRotation()) { - case XZ_PLANE: _offset.set(_offset.x(),-_offset.z(),_offset.y()); break; - case YZ_PLANE: _offset.set(_offset.z(),_offset.x(),_offset.y()); break; - case XY_PLANE: break; // nop - already on XY plane. - case SCREEN: break; // nop - need to account for rotation in draw as it depends on ModelView _matrix. + _matrix.makeTranslate(-_offset); + + if (_scale!=1.0f) + _matrix.postMult(osg::Matrix::scale(_scale,_scale,_scale)); + if (!_rotation.zeroRotation()) + _matrix.postMult(osg::Matrix::rotate(_rotation)); + + + _matrix.postMult(osg::Matrix::translate(_position)); + } + else + { + _matrix.makeTranslate(_position-_offset); } - _matrix.makeTranslate(_position-_offset); - - switch(_axisAlignment) + // now apply matrix to the glyphs. + for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin(); + titr!=_textureGlyphQuadMap.end(); + ++titr) { - case XZ_PLANE: _matrix.preMult(osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f)); break; - case YZ_PLANE: _matrix.preMult(osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f)*osg::Matrix::rotate(osg::inDegrees(90.0f),0.0f,0.0f,1.0f)); break; - case XY_PLANE: break; // nop - already on XY plane. - case SCREEN: break; // nop - need to account for rotation in draw as it depends on ModelView _matrix. + GlyphQuads& glyphquad = titr->second; + GlyphQuads::Coords2& coords2 = glyphquad._coords; + GlyphQuads::Coords3& transformedCoords = glyphquad._transformedCoords; + + unsigned int numCoords = coords2.size(); + if (numCoords!=transformedCoords.size()) + { + transformedCoords.resize(numCoords); + } + + for(unsigned int i=0;isecond; - state.setVertexPointer( 2, GL_FLOAT, 0, &(glyphquad._coords.front())); + state.setVertexPointer( 3, GL_FLOAT, 0, &(glyphquad._transformedCoords.front())); state.setTexCoordPointer( 0, 2, GL_FLOAT, 0, &(glyphquad._texcoords.front())); glDrawArrays(GL_QUADS,0,glyphquad._coords.size()); @@ -509,13 +611,19 @@ void Text::drawImplementation(osg::State& state) const if (_textBB.valid()) { state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); + + osg::Vec3 c00(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*_matrix); + osg::Vec3 c10(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*_matrix); + osg::Vec3 c11(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*_matrix); + osg::Vec3 c01(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*_matrix); + glColor4f(1.0f,1.0f,0.0f,1.0f); glBegin(GL_LINE_LOOP); - glVertex3f(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()); - glVertex3f(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()); - glVertex3f(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); - glVertex3f(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); + glVertex3fv(c00.ptr()); + glVertex3fv(c10.ptr()); + glVertex3fv(c11.ptr()); + glVertex3fv(c01.ptr()); glEnd(); } } @@ -523,23 +631,27 @@ void Text::drawImplementation(osg::State& state) const if (_drawMode & ALIGNMENT) { glColor4f(1.0f,0.0f,1.0f,1.0f); - glTranslatef(_offset.x(),_offset.y(),_offset.z()); - + + float cursorsize = _characterHeight*0.5f*_scale; + + osg::Vec3 hl(osg::Vec3(_offset.x()-cursorsize,_offset.y(),_offset.z())*_matrix); + osg::Vec3 hr(osg::Vec3(_offset.x()+cursorsize,_offset.y(),_offset.z())*_matrix); + osg::Vec3 vt(osg::Vec3(_offset.x(),_offset.y()-cursorsize,_offset.z())*_matrix); + osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_offset.z())*_matrix); + state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF); - float cursorsize = _characterHeight*0.5f; - glBegin(GL_LINES); - glVertex3f(-cursorsize,0.0f,0.0f); - glVertex3f(cursorsize,0.0f,0.0f); - glVertex3f(0.0f,-cursorsize,0.0f); - glVertex3f(0.0f,cursorsize,0.0f); + glVertex3fv(hl.ptr()); + glVertex3fv(hr.ptr()); + glVertex3fv(vt.ptr()); + glVertex3fv(vb.ptr()); glEnd(); } - glPopMatrix(); +// glPopMatrix(); } void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const @@ -549,7 +661,7 @@ void Text::accept(osg::Drawable::ConstAttributeFunctor& af) const ++titr) { const GlyphQuads& glyphquad = titr->second; - af.apply(osg::Drawable::VERTICES,glyphquad._coords.size(),&(glyphquad._coords.front())); + af.apply(osg::Drawable::VERTICES,glyphquad._transformedCoords.size(),&(glyphquad._transformedCoords.front())); af.apply(osg::Drawable::TEXTURE_COORDS_0,glyphquad._texcoords.size(),&(glyphquad._texcoords.front())); } } @@ -563,8 +675,8 @@ void Text::accept(osg::Drawable::PrimitiveFunctor& pf) const const GlyphQuads& glyphquad = titr->second; pf.begin(GL_QUADS); - for(GlyphQuads::Coords::const_iterator itr = glyphquad._coords.begin(); - itr!=glyphquad._coords.end(); + for(GlyphQuads::Coords3::const_iterator itr = glyphquad._transformedCoords.begin(); + itr!=glyphquad._transformedCoords.end(); ++itr) {