Well, since it not a submission per say. Here is the sample source code that 
John wanted me to so you all. 


Enjoy! Comments welcome!!
... 

Laters!

D Glenn

------------------------
David Glenn
---------------
D Glenn 3D Computer Graphics & Media Systems.
www.dglenn.com

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=46681#46681



// Suggested Revisions to osgText::Text class.
// John Markano 3/21/2012
//
// The code below includes suggested fixes for two problems in osgText::Text
// in the OpenSceneGraph 2.8.1 release:
// (1) Text in object coordinates may be rendered with the wrong size.
//     If an application requests a font resolution that the font doesn't
//     support, OpenSceneGraph uses the closest supported
//     resolution. osgText::Text does not handle this situation properly.
//     It uses the requested resolution in some calculations where the
//     actual resolution is more appropriate.
// (2) Text in screen coordinates may not be scaled properly when a
//     perspective projection is specified. In particular, the displayed text
//     size may vary with the field of view when it should remain constant
//     relative to the screen.
//
// A class TextImproved is defined below to correct these problems. This class
// inherits osgText::Text and replaces three virtual functions in the parent
// class:
// - computeLastCharacterOnLine (for the first issue above)
// - computeGlyphRepresentation (for the first issue above)
// - computePositions (for the second issue above)
//
// Each of these functions includes suggested changes to the original code.
// The original code is also left in place for comparison. The preprocessor
// variable USE_ORIGINAL_CODE can be set to a non-zero value to compile the
// original code instead of the improved code.
//
// An example program is also provided below to provide a before-and-after
// illustration of these changes. This example program splits the screen
// into four quadrants, where
// - The upper left quadrant contains black text generated by osgText::Text
//   with screen coordinates specified. It changes size with the field of
//   view, but its size should be fixed.
// - The upper right quadrant contains black text generated by the
//   TextImproved class defined below. This text should, and does, appear
//   with a constant height of around 100 pixels. (No reference scale is
//   provided.)
// - The lower left quadrant contains red text generated by osgText::Text
//   with object coordinates specified. It should be one unit tall, but
//   its actual size varies depending on what the active font supports.
//   In this example, it's less than half as tall as the requested size
//   because the default font resolution of 32 is much higher than the
//   supported (by DefaultFont) resolution of 12.
// - The lower right quadrant contains red text generated by the TextImproved
//   class. It displays closer to the correct height of one unit.
//
// The example program allows the user to increase or decrease the field
// of view using keystrokes. Type '+' to increase the field of view, or '-'
// to decrease the field of view. The camera position is fixed, so this
// is the only available viewing parameter control.
//
// This code was developed and tested using Red Hat Enterprise Linux 5.5,
// Qt 4.5.2 and OpenSceneGraph 2.8.1.
//
// This fix uses an uppercase E to find the available font size. This is
// a kludge that is inappropriate for many fonts. A suggested
// improvement would be to add a function to osgText::Font (and the
// DefaultFont subclass) to return the supported font resolution that is
// closest to the requested resolution.

#include <osg/Camera>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/GL>
#include <osg/Group>
#include <osg/Math>
#include <osg/Matrix>
#include <osg/Notify>
#include <osg/Vec3>
#include <osg/Vec3d>
#include <osgGA/GUIEventHandler>
#include <osgText/Text>
#include <osgViewer/Viewer>

#define USE_ORIGINAL_CODE (0)

using namespace osg;
using namespace osgText;

class TextImproved : public osgText::Text
{
protected:

String::iterator computeLastCharacterOnLine(osg::Vec2& cursor, String::iterator 
first,String::iterator last)
{
    Font* activefont = getActiveFont();
    if (!activefont) return last;

#if USE_ORIGINAL_CODE
    float hr = _characterHeight/getFontHeight();
#else
    // Use an upper case E to determine which font size is available
    // near the requested font resolution.
    // Then compute a scale factor to scale the font to the requested
    // character height. Include a factor of 0.7 to allow lower
    // case characters to drop below the base of capital letters.
    Font::Glyph* glyphGenericUpper = activefont->getGlyph(_fontSize, 'E');
    float hr = 0.7 * (glyphGenericUpper
        ? _characterHeight/glyphGenericUpper->t()
        : _characterHeight/getFontHeight());
#endif
    float wr = hr/_characterAspectRatio;

    bool kerning = true;
    unsigned int previous_charcode = 0;

    String::iterator lastChar = first;

    std::set<unsigned int> deliminatorSet;
    deliminatorSet.insert(' ');
    deliminatorSet.insert('\n');
    deliminatorSet.insert(':');
    deliminatorSet.insert('/');
    deliminatorSet.insert(',');
    deliminatorSet.insert(';');
    deliminatorSet.insert(':');
    deliminatorSet.insert('.');

    for(bool outOfSpace=false;lastChar!=last;++lastChar)
    {
        unsigned int charcode = *lastChar;

        if (charcode=='\n')
        {
            return lastChar;
        }

        Font::Glyph* glyph = activefont->getGlyph(_fontSize, charcode);
        if (glyph)
        {

           float width = (float)(glyph->s()) * wr;
           //float height = (float)(glyph->t()) * hr;

           #ifdef TREES_CODE_FOR_MAKING_SPACES_EDITABLE
           if (width == 0.0f)  width = glyph->getHorizontalAdvance() * wr;
           //if (height == 0.0f) height = glyph->getVerticalAdvance() * hr;
           #endif

            if (_layout==RIGHT_TO_LEFT)
            {
                cursor.x() -= glyph->getHorizontalAdvance() * wr;
            }

            // adjust cursor position w.r.t any kerning.
            if (kerning && previous_charcode)
            {
                switch(_layout)
                {
                  case LEFT_TO_RIGHT:
                  {
                    osg::Vec2 delta(activefont->getKerning(_fontSize, 
previous_charcode,charcode,_kerningType));
                    cursor.x() += delta.x() * wr;
                    cursor.y() += delta.y() * hr;
                    break;
                  }
                  case RIGHT_TO_LEFT:
                  {
                    osg::Vec2 delta(activefont->getKerning(_fontSize, 
charcode,previous_charcode,_kerningType));
                    cursor.x() -= delta.x() * wr;
                    cursor.y() -= delta.y() * hr;
                    break;
                  }
                  case VERTICAL:
                    break; // no kerning when vertical.
                }            // check to see if we are still within line if not 
move to next line.
            }

            switch(_layout)
            {
              case LEFT_TO_RIGHT:
              {
                if (_maximumWidth>0.0f && cursor.x()+width>_maximumWidth) 
outOfSpace=true;
                if(_maximumHeight>0.0f && cursor.y()<-_maximumHeight) 
outOfSpace=true;
                break;
              }
              case RIGHT_TO_LEFT:
              {
                if (_maximumWidth>0.0f && cursor.x()<-_maximumWidth) 
outOfSpace=true;
                if(_maximumHeight>0.0f && cursor.y()<-_maximumHeight) 
outOfSpace=true;
                break;
              }
              case VERTICAL:
                if (_maximumHeight>0.0f && cursor.y()<-_maximumHeight) 
outOfSpace=true;
                break;
            }

            // => word boundary detection & wrapping
            if (outOfSpace) break;

            // move the cursor onto the next character.
            switch(_layout)
            {
              case LEFT_TO_RIGHT: cursor.x() += glyph->getHorizontalAdvance() * 
wr; break;
              case VERTICAL:      cursor.y() -= glyph->getVerticalAdvance() 
*hr; break;
              case RIGHT_TO_LEFT: break; // nop.
            }

        previous_charcode = charcode;

        }

    }

    // word boundary detection & wrapping
    if (lastChar!=last)
    {
        if (deliminatorSet.count(*lastChar)==0)
        {
            String::iterator lastValidChar = lastChar;
            while (lastValidChar!=first && 
deliminatorSet.count(*lastValidChar)==0)
            {
                --lastValidChar;

                // Subtract off glyphs from the cursor position (to correctly 
center text)
                Font::Glyph* glyph = activefont->getGlyph(_fontSize, 
*lastValidChar);
                if (glyph)
                {
                    switch(_layout)
                    {
                    case LEFT_TO_RIGHT: cursor.x() -= 
glyph->getHorizontalAdvance() * wr; break;
                    case VERTICAL:      cursor.y() += 
glyph->getVerticalAdvance() * hr; break;
                    case RIGHT_TO_LEFT: break; // nop.
                    }
                }
            }
            if (first!=lastValidChar)
            {
                ++lastValidChar;
                lastChar = lastValidChar;
            }
        }
    }

    return lastChar;
}

void computeGlyphRepresentation()
{
    Font* activefont = getActiveFont();
    if (!activefont) return;

    _textureGlyphQuadMap.clear();
    _lineCount = 0;

    if (_text.empty())
    {
        _textBB.set(0,0,0,0,0,0);//no size text
        TextBase::computePositions(); //to reset the origin
        return;
    }

    //OpenThreads::ScopedLock<Font::FontMutex> 
lock(*(activefont->getSerializeFontCallsMutex()));

    // initialize bounding box, it will be expanded during glyph position 
calculation
    _textBB.init();

    osg::Vec2 startOfLine_coords(0.0f,0.0f);
    osg::Vec2 cursor(startOfLine_coords);
    osg::Vec2 local(0.0f,0.0f);

    unsigned int previous_charcode = 0;
    unsigned int linelength = 0;
    bool horizontal = _layout!=VERTICAL;
    bool kerning = true;

    unsigned int lineNumber = 0;

#if USE_ORIGINAL_CODE
    float hr = _characterHeight/getFontHeight();
#else
    // Use an upper case E to determine which font size is available
    // near the requested font resolution.
    // Then compute a scale factor to scale the font to the requested
    // character height. Include a factor of 0.7 to allow lower
    // case characters to drop below the base of capital letters.
    Font::Glyph* glyphGenericUpper = activefont->getGlyph(_fontSize, 'E');
    float hr = 0.7 * (glyphGenericUpper
        ? _characterHeight/glyphGenericUpper->t()
        : _characterHeight/getFontHeight());
#endif
    float wr = hr/_characterAspectRatio;

    for(String::iterator itr=_text.begin();
        itr!=_text.end();
        )
    {
        // record the start of the current line
            String::iterator startOfLine_itr = itr;

            // find the end of the current line.
            osg::Vec2 endOfLine_coords(cursor);
            String::iterator endOfLine_itr = 
computeLastCharacterOnLine(endOfLine_coords, itr,_text.end());

            linelength = endOfLine_itr - startOfLine_itr;

            // Set line position to correct alignment.
            switch(_layout)
            {
            case LEFT_TO_RIGHT:
            {
            switch(_alignment)
            {
              // nothing to be done for these
              //case LEFT_TOP:
              //case LEFT_CENTER:
              //case LEFT_BOTTOM:
              //case LEFT_BASE_LINE:
              //case LEFT_BOTTOM_BASE_LINE:
              //  break;
              case CENTER_TOP:
              case CENTER_CENTER:
              case CENTER_BOTTOM:
              case CENTER_BASE_LINE:
              case CENTER_BOTTOM_BASE_LINE:
                cursor.x() = (cursor.x() - endOfLine_coords.x()) * 0.5f;
                break;
              case RIGHT_TOP:
              case RIGHT_CENTER:
              case RIGHT_BOTTOM:
              case RIGHT_BASE_LINE:
              case RIGHT_BOTTOM_BASE_LINE:
                cursor.x() = cursor.x() - endOfLine_coords.x();
                break;
              default:
                break;
              }
            break;
            }
            case RIGHT_TO_LEFT:
            {
            switch(_alignment)
            {
              case LEFT_TOP:
              case LEFT_CENTER:
              case LEFT_BOTTOM:
              case LEFT_BASE_LINE:
              case LEFT_BOTTOM_BASE_LINE:
                cursor.x() = 2*cursor.x() - endOfLine_coords.x();
                break;
              case CENTER_TOP:
              case CENTER_CENTER:
              case CENTER_BOTTOM:
              case CENTER_BASE_LINE:
              case CENTER_BOTTOM_BASE_LINE:
                cursor.x() = cursor.x() + (cursor.x() - endOfLine_coords.x()) * 
0.5f;
                break;
              // nothing to be done for these
              //case RIGHT_TOP:
              //case RIGHT_CENTER:
              //case RIGHT_BOTTOM:
              //case RIGHT_BASE_LINE:
              //case RIGHT_BOTTOM_BASE_LINE:
              //  break;
              default:
                break;
            }
            break;
            }
            case VERTICAL:
            {
            switch(_alignment)
            {
              // TODO: current behaviour top baselines lined up in both cases - 
need to implement
              //       top of characters alignment - Question is this necessary?
              // ... otherwise, nothing to be done for these 6 cases
              //case LEFT_TOP:
              //case CENTER_TOP:
              //case RIGHT_TOP:
              //  break;
              //case LEFT_BASE_LINE:
              //case CENTER_BASE_LINE:
              //case RIGHT_BASE_LINE:
              //  break;
              case LEFT_CENTER:
              case CENTER_CENTER:
              case RIGHT_CENTER:
                cursor.y() = cursor.y() + (cursor.y() - endOfLine_coords.y()) * 
0.5f;
                break;
              case LEFT_BOTTOM_BASE_LINE:
              case CENTER_BOTTOM_BASE_LINE:
              case RIGHT_BOTTOM_BASE_LINE:
                cursor.y() = cursor.y() - (linelength * _characterHeight);
                break;
              case LEFT_BOTTOM:
              case CENTER_BOTTOM:
              case RIGHT_BOTTOM:
                cursor.y() = 2*cursor.y() - endOfLine_coords.y();
                break;
              default:
                break;
            }
            break;
          }
        }

        if (itr!=endOfLine_itr)
        {

            for(;itr!=endOfLine_itr;++itr)
            {
                unsigned int charcode = *itr;

                Font::Glyph* glyph = activefont->getGlyph(_fontSize, charcode);
                if (glyph)
                {
                    float width = (float)(glyph->s()) * wr;
                    float height = (float)(glyph->t()) * hr;

                    #ifdef TREES_CODE_FOR_MAKING_SPACES_EDITABLE
                    if (width == 0.0f)  width = glyph->getHorizontalAdvance() * 
wr;
                    if (height == 0.0f) height = glyph->getVerticalAdvance() * 
hr;
                    #endif

                    if (_layout==RIGHT_TO_LEFT)
                    {
                        cursor.x() -= glyph->getHorizontalAdvance() * wr;
                    }

                    // adjust cursor position w.r.t any kerning.
                    if (kerning && previous_charcode)
                    {
                        switch(_layout)
                        {
                          case LEFT_TO_RIGHT:
                          {
                            osg::Vec2 delta(activefont->getKerning(_fontSize, 
previous_charcode,charcode,_kerningType));
                            cursor.x() += delta.x() * wr;
                            cursor.y() += delta.y() * hr;
                            break;
                          }
                          case RIGHT_TO_LEFT:
                          {
                            osg::Vec2 delta(activefont->getKerning(_fontSize, 
charcode,previous_charcode,_kerningType));
                            cursor.x() -= delta.x() * wr;
                            cursor.y() -= delta.y() * hr;
                            break;
                          }
                          case VERTICAL:
                            break; // no kerning when vertical.
                        }
                    }

                    local = cursor;
                    osg::Vec2 
bearing(horizontal?glyph->getHorizontalBearing():glyph->getVerticalBearing());
                    local.x() += bearing.x() * wr;
                    local.y() += bearing.y() * hr;

                    GlyphQuads& glyphquad = 
_textureGlyphQuadMap[glyph->getTexture()];

                    glyphquad._glyphs.push_back(glyph);
                    glyphquad._lineNumbers.push_back(lineNumber);

                    // set up the coords of the quad
                    glyphquad._coords.push_back(local+osg::Vec2(0.0f,height));
                    glyphquad._coords.push_back(local+osg::Vec2(0.0f,0.0f));
                    glyphquad._coords.push_back(local+osg::Vec2(width,0.0f));
                    glyphquad._coords.push_back(local+osg::Vec2(width,height));

                    // set up the tex coords of the quad
                    const osg::Vec2& mintc = glyph->getMinTexCoord();
                    const osg::Vec2& maxtc = glyph->getMaxTexCoord();

                    
glyphquad._texcoords.push_back(osg::Vec2(mintc.x(),maxtc.y()));
                    
glyphquad._texcoords.push_back(osg::Vec2(mintc.x(),mintc.y()));
                    
glyphquad._texcoords.push_back(osg::Vec2(maxtc.x(),mintc.y()));
                    
glyphquad._texcoords.push_back(osg::Vec2(maxtc.x(),maxtc.y()));

                    // move the cursor onto the next character.
                    // also expand bounding box
                    switch(_layout)
                    {
                      case LEFT_TO_RIGHT:
                          cursor.x() += glyph->getHorizontalAdvance() * wr;
                          
_textBB.expandBy(osg::Vec3(local.x(),local.y(),0.0f)); //lower left corner
                          
_textBB.expandBy(osg::Vec3(cursor.x(),local.y()+height,0.0f)); //upper right 
corner
                          break;
                      case VERTICAL:
                          cursor.y() -= glyph->getVerticalAdvance() *hr;
                          
_textBB.expandBy(osg::Vec3(local.x(),local.y()+height,0.0f)); //upper left 
corner
                          
_textBB.expandBy(osg::Vec3(local.x()+width,cursor.y(),0.0f)); //lower right 
corner
                          break;
                      case RIGHT_TO_LEFT:
                          
_textBB.expandBy(osg::Vec3(local.x()+width,local.y(),0.0f)); //lower right 
corner
                          
_textBB.expandBy(osg::Vec3(cursor.x(),local.y()+height,0.0f)); //upper left 
corner
                          break;
                    }

                    previous_charcode = charcode;

                }
            }

            if (itr!=_text.end())
            {
                // skip over spaces and return.
                while (*itr==' ') ++itr;
                if (*itr=='\n') ++itr;
            }

        }
        else
        {
            ++itr;
        }


        // move to new line.
        switch(_layout)
        {
          case LEFT_TO_RIGHT:
          {
            startOfLine_coords.y() -= _characterHeight * (1.0 + _lineSpacing);
            cursor = startOfLine_coords;
            previous_charcode = 0;
            _lineCount++;
            break;
          }
          case RIGHT_TO_LEFT:
          {
            startOfLine_coords.y() -= _characterHeight * (1.0 + _lineSpacing);
            cursor = startOfLine_coords;
            previous_charcode = 0;
            _lineCount++;
            break;
          }
          case VERTICAL:
          {
            startOfLine_coords.x() += _characterHeight/_characterAspectRatio * 
(1.0 + _lineSpacing);
            cursor = startOfLine_coords;
            previous_charcode = 0;
            // because _lineCount is the max vertical no. of characters....
            _lineCount = (_lineCount >linelength)?_lineCount:linelength;
          }
          break;
        }

        ++lineNumber;

    }

    TextBase::computePositions();
    computeBackdropBoundingBox();
    computeColorGradients();
}

virtual void computePositions(unsigned int contextID) const
{
    switch(_alignment)
    {
    case LEFT_TOP:      
_offset.set(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()); break;
    case LEFT_CENTER:   
_offset.set(_textBB.xMin(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin());
 break;
    case LEFT_BOTTOM:   
_offset.set(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()); break;

    case CENTER_TOP:    
_offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMax(),_textBB.zMin());
 break;
    case CENTER_CENTER: 
_offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin());
 break;
    case CENTER_BOTTOM: 
_offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,_textBB.yMin(),_textBB.zMin());
 break;

    case RIGHT_TOP:     
_offset.set(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()); break;
    case RIGHT_CENTER:  
_offset.set(_textBB.xMax(),(_textBB.yMax()+_textBB.yMin())*0.5f,_textBB.zMin());
 break;
    case RIGHT_BOTTOM:  
_offset.set(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()); break;

    case LEFT_BASE_LINE:  _offset.set(0.0f,0.0f,0.0f); break;
    case CENTER_BASE_LINE:  
_offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,0.0f,0.0f); break;
    case RIGHT_BASE_LINE:  _offset.set(_textBB.xMax(),0.0f,0.0f); break;

    case LEFT_BOTTOM_BASE_LINE:  
_offset.set(0.0f,-_characterHeight*(_lineCount-1),0.0f); break;
    case CENTER_BOTTOM_BASE_LINE:  
_offset.set((_textBB.xMax()+_textBB.xMin())*0.5f,-_characterHeight*(_lineCount-1),0.0f);
 break;
    case RIGHT_BOTTOM_BASE_LINE:  
_offset.set(_textBB.xMax(),-_characterHeight*(_lineCount-1),0.0f); break;
    }

    AutoTransformCache& atc = _autoTransformCache[contextID];
    osg::Matrix& matrix = atc._matrix;

    if (_characterSizeMode!=OBJECT_COORDS || _autoRotateToScreen)
    {

        matrix.makeTranslate(-_offset);

        osg::Matrix rotate_matrix;
        if (_autoRotateToScreen)
        {
            osg::Vec3d trans(atc._modelview.getTrans());
            atc._modelview.setTrans(0.0f,0.0f,0.0f);

            rotate_matrix.invert(atc._modelview);

            atc._modelview.setTrans(trans);
        }

        matrix.postMultRotate(_rotation);

        if (_characterSizeMode!=OBJECT_COORDS)
        {

            osg::Matrix M(rotate_matrix);
            M.postMultTranslate(_position);
            M.postMult(atc._modelview);
            osg::Matrix& P = atc._projection;

            // compute the pixel size vector.

#if USE_ORIGINAL_CODE
            // pre adjust P00,P20,P23,P33 by multiplying them by the viewport 
window matrix.
            // here we do it in short hand with the knowledge of how the window 
matrix is formed
            // note P23,P33 are multiplied by an implicit 1 which would come 
from the window matrix.
            // Robert Osfield, June 2002.

            // scaling for horizontal pixels
            float P00 = P(0,0)*atc._width*0.5f;
            float P20_00 = P(2,0)*atc._width*0.5f + P(2,3)*atc._width*0.5f;
            osg::Vec3 scale_00(M(0,0)*P00 + M(0,2)*P20_00,
                               M(1,0)*P00 + M(1,2)*P20_00,
                               M(2,0)*P00 + M(2,2)*P20_00);

            // scaling for vertical pixels
            float P10 = P(1,1)*atc._height*0.5f;
            float P20_10 = P(2,1)*atc._height*0.5f + P(2,3)*atc._height*0.5f;
            osg::Vec3 scale_10(M(0,1)*P10 + M(0,2)*P20_10,
                               M(1,1)*P10 + M(1,2)*P20_10,
                               M(2,1)*P10 + M(2,2)*P20_10);

            float P23 = P(2,3);
            float P33 = P(3,3);

            float pixelSizeVector_w = M(3,2)*P23 + M(3,3)*P33;

            float 
pixelSizeVert=(_characterHeight*sqrtf(scale_10.length2()))/(pixelSizeVector_w*0.701f);
            float 
pixelSizeHori=(_characterHeight/_characterAspectRatio*sqrtf(scale_00.length2()))/(pixelSizeVector_w*0.701f);
#else
            // Compute the product of the projection transform and the scaling
            // component of the viewport transform. Compute each term directly
            // to avoid explict multiplication of zeros and ones.
            float vpHalfWidth( atc._width * 0.5);
            float vpHalfHeight( atc._height * 0.5);
            osg::Matrix PW(
                P(0,0)*vpHalfWidth, 0.0, 0.0, 0.0,
                0.0, P(1,1)*vpHalfHeight, 0.0, 0.0,
                P(2,0)*vpHalfWidth, P(2,1)*vpHalfHeight, P(2,2)*0.5, P(2,3),
                P(3,0)*vpHalfWidth, P(3,1)*vpHalfHeight, P(3,2)*0.5, P(3,3));

            float P10( PW(1,1)); // For sign check in legacy code below.

            // Transform the object coordinate origin to screen coordinates.
            osg::Vec4 objOriginView( M(3,0), M(3,1), M(3,2), M(3,3));
            osg::Vec4 objOriginWin4( objOriginView * PW);
            osg::Vec3 objOriginWin(
                objOriginWin4.x()/objOriginWin4.w(),
                objOriginWin4.y()/objOriginWin4.w(),
                objOriginWin4.z()/objOriginWin4.w());

            // Transform the object coordinate unit x (horizontal) vector from
            // object coordinates to window coordinates and compute the length
            // of the result.
            osg::Vec4 objUnitXView(
                M(0,0)+M(3,0), M(0,1)+M(3,1), M(0,2)+M(3,2), 1.0);
            osg::Vec4 objUnitXWin4( objUnitXView * PW);
            osg::Vec3 objUnitXWin(
                objUnitXWin4.x()/objUnitXWin4.w() - objOriginWin.x(),
                objUnitXWin4.y()/objUnitXWin4.w() - objOriginWin.y(),
                objUnitXWin4.z()/objUnitXWin4.w() - objOriginWin.z());
            float objUnitXWinLength( objUnitXWin.length());

            // Transform the object coordinate unit y (vertical) vector from
            // object coordinates to window coordinates. Then compute the
            // length of the result.
            osg::Vec4 objUnitYView(
                M(1,0)+M(3,0), M(1,1)+M(3,1), M(1,2)+M(3,2), 1.0);
            osg::Vec4 objUnitYWin4( objUnitYView * PW);
            osg::Vec3 objUnitYWin(
                objUnitYWin4.x()/objUnitYWin4.w() - objOriginWin.x(),
                objUnitYWin4.y()/objUnitYWin4.w() - objOriginWin.y(),
                objUnitYWin4.z()/objUnitYWin4.w() - objOriginWin.z());
            float objUnitYWinLength( objUnitYWin.length());

            // Compute the vertical and horizontal screen coordinate
            // dimensions of a character after it is transformed into
            // screen coordinates.
            float pixelSizeVert( _characterHeight * objUnitYWinLength);
            float pixelSizeHori(
                _characterHeight / _characterAspectRatio * objUnitXWinLength);
#endif

            // avoid nasty math by preventing a divide by zero
            if (pixelSizeVert == 0.0f)
               pixelSizeVert= 1.0f;
            if (pixelSizeHori == 0.0f)
               pixelSizeHori= 1.0f;

            if (_characterSizeMode==SCREEN_COORDS)
            {
                float scale_font_vert=_characterHeight/pixelSizeVert;
                float 
scale_font_hori=_characterHeight/_characterAspectRatio/pixelSizeHori;

                if (P10<0)
                   scale_font_vert=-scale_font_vert;
                matrix.postMultScale(osg::Vec3f(scale_font_hori, 
scale_font_vert,1.0f));
            }
            else if (pixelSizeVert>getFontHeight())
            {
                float scale_font = getFontHeight()/pixelSizeVert;
                matrix.postMultScale(osg::Vec3f(scale_font, scale_font,1.0f));
            }

        }

        if (_autoRotateToScreen)
        {
            matrix.postMult(rotate_matrix);
        }

        matrix.postMultTranslate(_position);
    }
    else if (!_rotation.zeroRotation())
    {
        matrix.makeRotate(_rotation);
        matrix.preMultTranslate(-_offset);
        matrix.postMultTranslate(_position);
    }
    else
    {
        matrix.makeTranslate(_position-_offset);
    }

    // now apply matrix to the glyphs.
    for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin();
        titr!=_textureGlyphQuadMap.end();
        ++titr)
    {
        GlyphQuads& glyphquad = titr->second;
        GlyphQuads::Coords2& coords2 = glyphquad._coords;
        GlyphQuads::Coords3& transformedCoords = 
glyphquad._transformedCoords[contextID];

        unsigned int numCoords = coords2.size();
        if (numCoords!=transformedCoords.size())
        {
            transformedCoords.resize(numCoords);
        }

        for(unsigned int i=0;i<numCoords;++i)
        {
            transformedCoords[i] = 
osg::Vec3(coords2[i].x(),coords2[i].y(),0.0f)*matrix;
        }
    }

    computeBackdropPositions(contextID);

    _normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix);
    _normal.normalize();

    const_cast<TextImproved*>(this)->dirtyBound();
}

};

///////////////////////////////////////////////////////////////////////////////
// KeyHandler - Event handler to toggle different symbol display modes.
///////////////////////////////////////////////////////////////////////////////
class KeyHandler : public osgGA::GUIEventHandler
{
    osgViewer::Viewer*                 _viewer;

public:
    KeyHandler( osgViewer::Viewer* viewer)
        : _viewer( viewer)
    {}

    virtual bool handle(
        const osgGA::GUIEventAdapter& eventAdapter,
        osgGA::GUIActionAdapter&      actionAdapter)
    {
        switch (eventAdapter.getEventType())
        {
        case osgGA::GUIEventAdapter::FRAME:
            _viewer->setCameraManipulator( NULL);
            _viewer->getCamera()->setViewMatrixAsLookAt(
                osg::Vec3d( 0.0, 0.0, 10.0),   // eye
                osg::Vec3d( 0.0, 0.0, 0.0),    // center
                osg::Vec3d( 0.0, 1.0, 0.0));   // up

            break;

        case osgGA::GUIEventAdapter::KEYUP:
            switch (eventAdapter.getKey())
            {
            case '+':
            case '-':
                {
                    osg::Camera* camera( _viewer->getCamera());
                    double fovY, aspectRatio, zNear, zFar;
                    camera->getProjectionMatrixAsPerspective(
                        fovY, aspectRatio, zNear, zFar);
                    osg::notify( osg::NOTICE)
                        << "PROJECTION "
                        << fovY << " "
                        << aspectRatio << " "
                        << zNear << " "
                        << zFar << std::endl;

                    if (eventAdapter.getKey() == '+' && fovY < 172.0)
                        fovY += 4.0;
                    if (eventAdapter.getKey() == '-' && fovY > 8.0)
                        fovY -= 4.0;

                    camera->setProjectionMatrixAsPerspective(
                        fovY, aspectRatio, 1.0, 1000.0);
                    camera->setComputeNearFarMode(
                        osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
                }
                break;

            default: ;
            }
            break;

        default: ;
        }
        return false;
    }
};

///////////////////////////////////////////////////////////////////////////////
// main - Creates and displays text using both legacy and updated logic.
///////////////////////////////////////////////////////////////////////////////
int main( int argc, char **argv )
{   
    std::string textStr = "pHE,L q\npHE,L q";

    // Create "unimproved text objects to the left of center.
    // Black text 100 pixels tall.
    osgText::Text* text100pUnimp( new osgText::Text);
    text100pUnimp->setColor( osg::Vec4( 0.0, 0.0, 0.0, 1.0));
    text100pUnimp->setText( textStr);
    text100pUnimp->setPosition( osg::Vec3d( 0.0, 0.0, 0.0));
    text100pUnimp->setCharacterSize( 100.0);
    text100pUnimp->setCharacterSizeMode( osgText::Text::SCREEN_COORDS);
    text100pUnimp->setAlignment( osgText::Text::RIGHT_BOTTOM);
    text100pUnimp->setAutoRotateToScreen( false);

    // Red text 1 object coordinate unit tall.
    osgText::Text* text1uUnimp( new osgText::Text);
    text1uUnimp->setColor( osg::Vec4( 1.0, 0.0, 0.0, 1.0));
    text1uUnimp->setText( textStr);
    text1uUnimp->setPosition( osg::Vec3d( 0.0, 0.0, 0.0));
    text1uUnimp->setCharacterSize( 1.0);
    text1uUnimp->setCharacterSizeMode( osgText::Text::OBJECT_COORDS);
    text1uUnimp->setAlignment( osgText::Text::RIGHT_TOP);
    text1uUnimp->setAutoRotateToScreen( false);

    // Create "improved" text objects to the right of center.
    // Black text 100 pixels tall.
    TextImproved* text100pImpro( new TextImproved);
    text100pImpro->setColor( osg::Vec4( 0.0, 0.0, 0.0, 1.0));
    text100pImpro->setText( textStr);
    text100pImpro->setPosition( osg::Vec3d( 0.0, 0.0, 0.0));
    text100pImpro->setCharacterSize( 100.0);
    text100pImpro->setCharacterSizeMode( osgText::Text::SCREEN_COORDS);
    text100pImpro->setAlignment( osgText::Text::LEFT_BOTTOM);
    text100pImpro->setAutoRotateToScreen( false);

    // Red text 1 object coordinate unit tall.
    TextImproved* text1uImpro( new TextImproved);
    text1uImpro->setColor( osg::Vec4( 1.0, 0.0, 0.0, 1.0));
    text1uImpro->setText( textStr);
    text1uImpro->setPosition( osg::Vec3d( 0.0, 0.0, 0.0));
    text1uImpro->setCharacterSize( 1.0);
    text1uImpro->setCharacterSizeMode( osgText::Text::OBJECT_COORDS);
    text1uImpro->setAlignment( osgText::Text::LEFT_TOP);
    text1uImpro->setAutoRotateToScreen( false);

    // Four white one-unit squares centered at the object coordinate origin.
    osg::Vec3Array* vertices( new osg::Vec3Array);
    vertices->push_back( osg::Vec3( -1.0, -1.0, 0.0));
    vertices->push_back( osg::Vec3(  1.0, -1.0, 0.0));
    vertices->push_back( osg::Vec3( -1.0,  0.0, 0.0));
    vertices->push_back( osg::Vec3(  1.0,  0.0, 0.0));
    vertices->push_back( osg::Vec3( -1.0,  1.0, 0.0));
    vertices->push_back( osg::Vec3(  1.0,  1.0, 0.0));

    vertices->push_back( osg::Vec3( -1.0, -1.0, 0.0));
    vertices->push_back( osg::Vec3( -1.0,  1.0, 0.0));
    vertices->push_back( osg::Vec3(  0.0, -1.0, 0.0));
    vertices->push_back( osg::Vec3(  0.0,  1.0, 0.0));
    vertices->push_back( osg::Vec3(  1.0, -1.0, 0.0));
    vertices->push_back( osg::Vec3(  1.0,  1.0, 0.0));

    osg::Vec4Array* colors( new osg::Vec4Array);
    colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0));

    osg::Geometry* geom( new osg::Geometry);
    geom->setVertexArray( vertices);
    geom->setColorArray( colors);
    geom->setColorBinding( osg::Geometry::BIND_OVERALL);
    geom->addPrimitiveSet( new osg::DrawArrays( GL_LINES, 0, 12));

    osg::Geode* geode( new osg::Geode);
    geode->addDrawable( text100pUnimp);
    geode->addDrawable( text1uUnimp);
    geode->addDrawable( text100pImpro);
    geode->addDrawable( text1uImpro);
    geode->addDrawable( geom);

    osgViewer::Viewer viewer;
    viewer.setSceneData( geode);
    viewer.addEventHandler( new KeyHandler( &viewer));

    return viewer.run();
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to