Index: /OpenSceneGraph/trunk/include/osgText/Text3D
===================================================================
--- /OpenSceneGraph/trunk/include/osgText/Text3D (revision 8441)
+++ /OpenSceneGraph/trunk/include/osgText/Text3D (revision 9881)
@@ -1,12 +1,12 @@
-/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  *
- * This library is open source and may be redistributed and/or modified under  
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * This library is open source and may be redistributed and/or modified under
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  * (at your option) any later version.  The full license is in LICENSE file
  * included with this distribution, and on the openscenegraph.org website.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * OpenSceneGraph Public License for more details.
 */
@@ -31,5 +31,5 @@
      *                   all wall face with the wall StateSet
      *                   all back face with the back StateSet (back face of the character, no the OpenGL back face)
-     * 
+     *
      * PER_GLYPH : render all Charactere with the default StateSet
      */
@@ -39,5 +39,5 @@
         PER_GLYPH
     };
-    
+
     Text3D();
     Text3D(const Text3D& text,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
@@ -49,5 +49,5 @@
     /** Set the Charactere Depth of text. */
     void setCharacterDepth(float characterDepth) { _characterDepth = characterDepth; computeGlyphRepresentation(); }
-    
+
     /** Get the render mode used to render the text. */
     RenderMode getRenderMode() const { return _renderMode; }
@@ -58,8 +58,8 @@
 //    osg::StateSet * getWallStateSet() { return _wallStateSet.get(); }
 //    /** Get or create the wall StateSet */
-//    osg::StateSet * getOrCreateWallStateSet() 
-//    { 
-//        if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet; 
-//        return _wallStateSet.get(); 
+//    osg::StateSet * getOrCreateWallStateSet()
+//    {
+//        if (_wallStateSet.valid() == false) _wallStateSet = new osg::StateSet;
+//        return _wallStateSet.get();
 //    }
 //    /** Set the wall StateSet */
@@ -72,7 +72,7 @@
 //    /** Set the back StateSet */
 //    void setBackStateSet(osg::StateSet * backStateSet)  { _backStateSet = backStateSet; }
-//            
-    
-    /** Set the Font to use to render the text.  
+//
+
+    /** Set the Font to use to render the text.
       * setFont(0) sets the use of the default font.*/
     inline void setFont(Font3D* font=0) { setFont(osg::ref_ptr<Font3D>(font)); };
@@ -87,10 +87,10 @@
     void setFont(const std::string& fontfile);
 
-    /** Get the font. Return 0 if default is being used.*/    
+    /** Get the font. Return 0 if default is being used.*/
     const Font3D* getFont() const { return _font.get(); }
 
-    
-    
-    
+
+
+
     /** Draw the text.*/
     virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
@@ -103,5 +103,5 @@
 
     /** accept an ConstAttributeFunctor and call its methods to tell it about the interal attributes that this Drawable has.*/
-//    virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
+    virtual void accept(osg::Drawable::ConstAttributeFunctor& af) const;
 
     /** return true, osgText::Text does support accept(PrimitiveFunctor&) .*/
@@ -109,5 +109,5 @@
 
     /** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.*/
-//    virtual void accept(osg::PrimitiveFunctor& pf) const;
+    virtual void accept(osg::PrimitiveFunctor& pf) const;
 
 
@@ -123,5 +123,5 @@
     virtual void releaseGLObjects(osg::State* state=0) const;
 
-//    // make Font a friend to allow it set the _font to 0 if the font is 
+//    // make Font a friend to allow it set the _font to 0 if the font is
 //    // forcefully unloaded.
     friend class Font3D;
@@ -132,6 +132,6 @@
 protected:
 
-    virtual ~Text3D() {} 
-    
+    virtual ~Text3D() {}
+
     void renderPerGlyph(osg::State & state) const;
     void renderPerFace(osg::State & state) const;
@@ -141,5 +141,5 @@
     void computeGlyphRepresentation();
     void computePositions(unsigned int contextID) const;
-    
+
     // ** glyph and other information to render the glyph
     struct GlyphRenderInfo
@@ -147,12 +147,12 @@
         GlyphRenderInfo(Font3D::Glyph3D * glyph, osg::Vec3 & pos) :
             _glyph(glyph), _position(pos) {}
-                    
+
         osg::ref_ptr<Font3D::Glyph3D> _glyph;
         osg::Vec3 _position;
     };
-    
+
     typedef std::vector<GlyphRenderInfo> LineRenderInfo;
-    typedef std::vector<LineRenderInfo> TextRenderInfo;    
-    
+    typedef std::vector<LineRenderInfo> TextRenderInfo;
+
     TextRenderInfo _textRenderInfo;
 
@@ -160,7 +160,7 @@
 
     float _characterDepth;
-    
+
     RenderMode _renderMode;
-    
+
     osg::ref_ptr<osg::StateSet> _wallStateSet;
     osg::ref_ptr<osg::StateSet> _backStateSet;
Index: /OpenSceneGraph/trunk/include/osgText/Font3D
===================================================================
--- /OpenSceneGraph/trunk/include/osgText/Font3D (revision 7874)
+++ /OpenSceneGraph/trunk/include/osgText/Font3D (revision 9881)
@@ -1,12 +1,12 @@
-/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  *
- * This library is open source and may be redistributed and/or modified under  
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * This library is open source and may be redistributed and/or modified under
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  * (at your option) any later version.  The full license is in LICENSE file
  * included with this distribution, and on the openscenegraph.org website.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * OpenSceneGraph Public License for more details.
 */
@@ -32,5 +32,5 @@
 
 /** Read a font from specified file. The filename may contain a path.
-  * It will search for the font file in the following places in this order: 
+  * It will search for the font file in the following places in this order:
   * - In the current directory
   * - All paths defined in OSG_FILE_PATH or OSGFILEPATH environment variable
@@ -46,5 +46,5 @@
   * - Other OS: In /usr/share/fonts/ttf/western
   * - Other OS: In /usr/share/fonts/ttf/decoratives
-  * 
+  *
   * If the given file could not be found, the path part will be stripped and
   * the file will be searched again in the OS specific directories.
@@ -68,5 +68,5 @@
 // declare the interface to a font.
 public:
-    
+
     // forward declare nested classes.
     class Glyph3D;
@@ -93,5 +93,5 @@
     /** Get a Glyph for specified charcode, and the font size nearest to the current font size hint.*/
     virtual Glyph3D* getGlyph(unsigned int charcode);
-    
+
     /** Return true if this font provides vertical alignments and spacing or glyphs.*/
     virtual bool hasVertical() const;
@@ -99,5 +99,5 @@
     /** Return the scale to apply on the glyph to have a charactere size equal to 1 */
     virtual float getScale() const { return _implementation->getScale(); };
-    
+
     // make Text a friend to allow it add and remove its entry in the Font's _textList.
     friend class Font3DImplementation;
@@ -110,5 +110,5 @@
     /** Set whether to use a mutex to ensure ref() and unref() */
     virtual void setThreadSafeRefUnref(bool threadSafe);
-    
+
     typedef OpenThreads::Mutex Font3DMutex;
 
@@ -116,8 +116,8 @@
 
     virtual ~Font3D();
-    
+
 //    void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph* glyph);
     void addGlyph(unsigned int charcode, Glyph3D* glyph);
-    
+
     // current active size of font
     unsigned int                        _depth;
@@ -128,9 +128,9 @@
 
     typedef std::map<char, osg::ref_ptr<Glyph3D> > Glyph3DMap;
-    Glyph3DMap _glyph3DMap; 
-    
+    Glyph3DMap _glyph3DMap;
+
     osg::ref_ptr<Font3DImplementation> _implementation;
 
-    
+
 // declare the nested classes.
 public:
@@ -139,9 +139,9 @@
     {
     public:
-    
+
         Font3DImplementation():
             osg::Referenced(true),
             _facade(0) {}
-    
+
         virtual std::string getFileName() const = 0;
 
@@ -154,18 +154,18 @@
         /** Return true if this font provides vertical alignments and spacing or glyphs.*/
         virtual bool hasVertical() const = 0;
-        
+
         virtual float getScale() const = 0;
-  
+
         void setFontWidth(unsigned int width) { _facade->_width = width; }
 
         void setFontHeight(unsigned int height) { _facade->_height = height; }
-        
+
         void setFontDepth(unsigned int depth) { _facade->_depth = depth; }
-        
+
 //        void addGlyph(unsigned int width, unsigned int height, unsigned int charcode, Glyph3D* glyph)
 //        {
 //            _facade->addGlyph(width, height, charcode, glyph);
 //        }
-//        
+//
 //        void addGlyph(unsigned int charcode, Glyph3D* glyph)
 //        {
@@ -182,5 +182,5 @@
         Glyph3D(unsigned int glyphCode):
             osg::Referenced(true),
-            _glyphCode(glyphCode), 
+            _glyphCode(glyphCode),
             _horizontalBearing(0,0),
             _horizontalAdvance(0),
@@ -188,18 +188,18 @@
             _verticalAdvance(0)
             {}
-        
+
 
         /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
 //        virtual int compare(const osg::StateAttribute& rhs) const;
-//        
+//
 //        virtual void apply(osg::State& state) const;
 
-        
-        
+
+
         unsigned int getGlyphCode() const { return _glyphCode; }
-        
+
         void setHorizontalBearing(const osg::Vec2& bearing) { _horizontalBearing=bearing; }
         const osg::Vec2 & getHorizontalBearing() const { return _horizontalBearing; }
-        
+
         void setHorizontalAdvance(float advance) { _horizontalAdvance=advance; }
         float getHorizontalAdvance() const { return _horizontalAdvance; }
@@ -210,13 +210,13 @@
         void setVerticalAdvance(float advance) { _verticalAdvance=advance; }
         float getVerticalAdvance() const { return _verticalAdvance; }
-                
+
         void setBoundingBox(osg::BoundingBox & bb) { _bb=bb; }
         const osg::BoundingBox & getBoundingBox() const { return _bb; }
-        
-        
+
+
         /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
         virtual void setThreadSafeRefUnref(bool threadSafe);
 
-        
+
         /** Get the PrimitiveSetList for the front face. */
         osg::Geometry::PrimitiveSetList & getFrontPrimitiveSetList() { return _frontPrimitiveSetList; }
@@ -225,25 +225,27 @@
         /** Get et the PrimitiveSetList for the back face. */
         osg::Geometry::PrimitiveSetList & getBackPrimitiveSetList() { return _backPrimitiveSetList; }
-        
+
         /** Set the VertexArray of the glyph. */
         void setVertexArray(osg::Vec3Array * va) { _vertexArray = va; }
         /** Get the VertexArray of the glyph. */
         osg::Vec3Array * getVertexArray() { return _vertexArray.get(); }
+        /** Set the VertexArray of the glyph. */
+        void setNormalArray(osg::Vec3Array * na) { _normalArray = na; }
         /** Get the NormalArray for the wall face. */
         osg::Vec3Array * getNormalArray() { return _normalArray.get(); }
-        
+
         float getHorizontalWidth() { return (-_horizontalBearing.x() + _horizontalAdvance); }
         float getHorizontalHeight() { return (-_horizontalBearing.y() + _bb.yMax()); }
         float getVerticalWidth() { return (-_verticalBearing.x() + _bb.xMax()); }
         float getVerticalHeight() { return (-_verticalBearing.y() + _verticalAdvance); }
-        
+
         void setWidth(float width) { _width = width; }
         float getWidth() { return _width; }
-        
+
         void setHeight(float height) { _height = height; }
         float getHeight() { return _height; }
-        
+
     protected:
-    
+
         virtual ~Glyph3D() {}
 
@@ -256,19 +258,19 @@
         float                       _verticalAdvance;
 
-        osg::BoundingBox            _bb;        
+        osg::BoundingBox            _bb;
 //        osg::Vec2                   _advance;
-        
+
         float _width;
         float _height;
-        
-        
+
+
         osg::ref_ptr<osg::Vec3Array> _vertexArray;
         osg::ref_ptr<osg::Vec3Array> _normalArray;
-        
+
         osg::Geometry::PrimitiveSetList _frontPrimitiveSetList;
         osg::Geometry::PrimitiveSetList _wallPrimitiveSetList;
         osg::Geometry::PrimitiveSetList _backPrimitiveSetList;
-        
-        
+
+
     };
 
Index: /OpenSceneGraph/trunk/src/osgPlugins/freetype/FreeTypeFont3D.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/freetype/FreeTypeFont3D.cpp (revision 7696)
+++ /OpenSceneGraph/trunk/src/osgPlugins/freetype/FreeTypeFont3D.cpp (revision 9881)
@@ -1,12 +1,12 @@
-/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  *
- * This library is open source and may be redistributed and/or modified under  
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * This library is open source and may be redistributed and/or modified under
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  * (at your option) any later version.  The full license is in LICENSE file
  * included with this distribution, and on the openscenegraph.org website.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * OpenSceneGraph Public License for more details.
 */
@@ -21,5 +21,5 @@
 
 #include <osg/Geometry>
-#include <osg/Notify>  
+#include <osg/Notify>
 #include <osgDB/WriteFile>
 #include <osgUtil/SmoothingVisitor>
@@ -27,5 +27,5 @@
 
 
-#include <ft2build.h>  
+#include <ft2build.h>
 #include FT_FREETYPE_H
 
@@ -174,5 +174,5 @@
 {
     Char3DInfo* char3d = (Char3DInfo*)user;
-    char3d->cubicTo( 
+    char3d->cubicTo(
         osg::Vec2(FT_NUM(control1->x),FT_NUM(control1->y)),
         osg::Vec2(FT_NUM(control2->x),FT_NUM(control2->y)),
@@ -221,5 +221,5 @@
     }
 
-    FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600); 
+    FT_Set_Char_Size( _face, 64*64, 64*64, 600, 600);
 
     int glyphIndex = FT_Get_Char_Index( _face, 'M' );
@@ -291,5 +291,5 @@
             // not dangling pointers remain
             freeTypeLibrary->removeFont3DImplmentation(this);
-        
+
             // free the freetype font face itself
             FT_Done_Face(_face);
@@ -309,10 +309,10 @@
 osgText::Font3D::Glyph3D * FreeTypeFont3D::getGlyph(unsigned int charcode)
 {
-    
-    
+
+
     //
-    // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being  
-    // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct 
-    // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.  
+    // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being
+    // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct
+    // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.
     // Microsoft uses a private field for its symbol fonts
     //
@@ -337,5 +337,5 @@
         return 0;
     }
-    
+
     // ** init FreeType to describe the glyph
     Char3DInfo char3d;
@@ -349,5 +349,5 @@
     funcs.shift = 0;
     funcs.delta = 0;
-    
+
     // ** record description
     FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d);
@@ -357,38 +357,38 @@
         return 0;
     }
-    
+
     // ** create geometry for each part of the glyph
     osg::ref_ptr<osg::Geometry> frontGeo(new osg::Geometry);
     frontGeo->setVertexArray(char3d.get()->getVertexArray());
     frontGeo->setPrimitiveSetList(char3d.get()->getPrimitiveSetList());
-    
+
     osg::ref_ptr<osg::Geometry> wallGeo(new osg::Geometry);
     wallGeo->setVertexArray(frontGeo->getVertexArray());
-    
+
     osg::ref_ptr<osg::Geometry> backGeo(new osg::Geometry);
     backGeo->setVertexArray(frontGeo->getVertexArray());
-        
-    
-    
-    // ** for conveniance.
+
+
+
+    // ** for convenience.
     osg::Vec3Array * vertices = char3d._verts.get();
-    
-    
-    
-    // ** duplicate the vertex for the back face 
+
+
+
+    // ** duplicate the vertex for the back face
     // ** with a depth equal to the font depth
     std::size_t len = vertices->size();
     std::size_t dlen = len * 2;
-      
+
     vertices->reserve(dlen);
-       
+
     osg::Vec3Array::iterator begin = vertices->begin();
     osg::Vec3Array::iterator it = vertices->begin();
-    
+
     for (std::size_t i = 0; i != len; ++i, ++it)
         vertices->push_back(*it);
 //    std::copy(begin, begin + len, begin + len + 1); TOCHECK
-    
- 
+
+
     // ** and decal new vertices
     unsigned int depth = _facade->getFontDepth();
@@ -397,9 +397,9 @@
         (*vertices)[i].z() -= depth;
     }
-    
+
     osg::Vec3Array::iterator end;
-    
+
     // ** create wall and back face from the front polygon
-    // **  then accumulate them in the apropriate geometry wallGeo and backGeo 
+    // **  then accumulate them in the appropriate geometry wallGeo and backGeo
     for (std::size_t i=0; i < frontGeo->getNumPrimitiveSets(); ++i)
     {
@@ -408,21 +408,21 @@
         unsigned int idx = daFront->getFirst();
         unsigned int cnt = daFront->getCount();
-        
+
         // ** reverse vertices to draw the front face in the CCW
         std::reverse(begin + idx, begin + idx + cnt);
-        
+
         // ** create the back polygon
         osg::ref_ptr<osg::DrawArrays> daBack(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, idx + len, cnt));
         backGeo->addPrimitiveSet(daBack.get());
-        
-        
+
+
         // ** create the wall triangle strip
-        osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP)); 
+        osg::ref_ptr<osg::DrawElementsUInt> deWall(new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP));
         wallGeo->addPrimitiveSet(deWall.get());
-        
+
         // **  link triangle strip
         deWall->push_back(idx + len);
         for (unsigned int j = 1; j < cnt; ++j)
-        {   
+        {
             deWall->push_back(idx + cnt - j);
             deWall->push_back(idx + len + j);
@@ -440,5 +440,5 @@
         ts.retessellatePolygons(*frontGeo);
     }
-    
+
     {
         osgUtil::Tessellator ts;
@@ -455,15 +455,16 @@
         geode->accept(sm);
     }
-    
-    // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list 
+
+    // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
     osgText::Font3D::Glyph3D * glyph3D = new osgText::Font3D::Glyph3D(charcode);
 
     glyph3D->setVertexArray(dynamic_cast<osg::Vec3Array*>(frontGeo->getVertexArray()));
-    
+    glyph3D->setNormalArray(dynamic_cast<osg::Vec3Array*>(wallGeo->getNormalArray()));
+
     glyph3D->getFrontPrimitiveSetList() = frontGeo->getPrimitiveSetList();
     glyph3D->getWallPrimitiveSetList() = wallGeo->getPrimitiveSetList();
     glyph3D->getBackPrimitiveSetList() = backGeo->getPrimitiveSetList();
 
-    
+
     FT_Glyph_Metrics* metrics = &(_face->glyph->metrics);
 
@@ -476,5 +477,5 @@
     glyph3D->setHeight((float)metrics->height / 64.0f);
 
-    
+
     FT_BBox ftbb;
     FT_Outline_Get_BBox(&outline, &ftbb);
@@ -484,9 +485,9 @@
     long ymin = ft_floor( ftbb.yMin );
     long ymax = ft_ceiling( ftbb.yMax );
-        
+
     osg::BoundingBox bb(xmin / 64.0f, ymin / 64.0f, 0.0f, xmax / 64.0f, ymax / 64.0f, 0.0f);
-    
+
     glyph3D->setBoundingBox(bb);
-    
+
     return glyph3D;
 }
@@ -501,6 +502,6 @@
     FT_UInt left = FT_Get_Char_Index( _face, leftcharcode );
     FT_UInt right = FT_Get_Char_Index( _face, rightcharcode );
-    
-    // get the kerning distances.   
+
+    // get the kerning distances.
     FT_Vector  kerning;
 
@@ -525,6 +526,6 @@
 }
 
-float FreeTypeFont3D::getScale() const 
-{ 
-    return _scale; 
-}
+float FreeTypeFont3D::getScale() const
+{
+    return _scale;
+}
Index: /OpenSceneGraph/trunk/src/osgPlugins/freetype/ReaderWriterFreeType.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgPlugins/freetype/ReaderWriterFreeType.cpp (revision 8680)
+++ /OpenSceneGraph/trunk/src/osgPlugins/freetype/ReaderWriterFreeType.cpp (revision 9881)
@@ -18,12 +18,13 @@
             supportsExtension("cff","OpenType format");
             supportsExtension("cef","OpenType format");
-            supportsExtension("fon","Windows bitmap fonts format");
+            supportsExtension("fon","Windows bitmap fonts format");
             supportsExtension("fnt","Windows bitmap fonts format");
+            supportsExtension("text3d","use 3D Font instead of 2D Font");
 
             supportsOption("monochrome","Select monochrome font.");
         }
-        
+
         virtual const char* className() const { return "FreeType Font Reader/Writer"; }
-        
+
         static unsigned int getFlags(const osgDB::ReaderWriter::Options* options)
         {
@@ -33,5 +34,5 @@
                 flags |= FT_LOAD_MONOCHROME;
             }
-            
+
             return flags;
         }
@@ -39,12 +40,26 @@
         virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
         {
-            std::string ext = osgDB::getLowerCaseFileExtension(file);
+            std::string tmpFile = file;
+            bool needFont3D = false;
+
+            std::string ext = osgDB::getLowerCaseFileExtension(tmpFile);
+            if (ext == "text3d")
+            {
+                needFont3D = true;
+                tmpFile.erase(tmpFile.size()-7, 7);
+                ext = osgDB::getLowerCaseFileExtension(tmpFile);
+            }
+            else if ((options != NULL) && (options->getPluginData("3D")))
+            {
+                needFont3D = true;
+            }
+
             if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
 
-            std::string fileName = osgDB::findDataFile( file, options );
+            std::string fileName = osgDB::findDataFile( tmpFile, options );
             if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
-            
+
             FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance();
-            if (!freeTypeLibrary) 
+            if (!freeTypeLibrary)
             {
                 osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<<std::endl;
@@ -52,5 +67,5 @@
             }
 
-            if ( (options != NULL) && (options->getPluginData("3D")) )
+            if (needFont3D)
                 return freeTypeLibrary->getFont3D(fileName,0,getFlags(options));
             else
@@ -61,5 +76,5 @@
         {
             FreeTypeLibrary* freeTypeLibrary = FreeTypeLibrary::instance();
-            if (!freeTypeLibrary) 
+            if (!freeTypeLibrary)
             {
                 osg::notify(osg::WARN)<<"Warning:: cannot create freetype font after freetype library has been deleted."<<std::endl;
Index: /OpenSceneGraph/trunk/src/osgText/Text3D.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgText/Text3D.cpp (revision 8868)
+++ /OpenSceneGraph/trunk/src/osgText/Text3D.cpp (revision 9881)
@@ -1,12 +1,12 @@
-/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  *
- * This library is open source and may be redistributed and/or modified under  
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * This library is open source and may be redistributed and/or modified under
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  * (at your option) any later version.  The full license is in LICENSE file
  * included with this distribution, and on the openscenegraph.org website.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * OpenSceneGraph Public License for more details.
 */
@@ -14,5 +14,5 @@
 #include <osgText/Text3D>
 #include <osg/io_utils>
-namespace osgText 
+namespace osgText
 {
 
@@ -33,23 +33,64 @@
 }
 
-//void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const
-//{
-//    TODO
-//}
-
-//void Text3D::accept(osg::PrimitiveFunctor& /*pf*/) const
-//{
-//    TODO 
-//}
+void Text3D::accept(osg::Drawable::ConstAttributeFunctor& af) const
+{
+    // ** for each line, do ...
+    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
+    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
+    {
+        // ** for each glyph in the line, do ...
+        LineRenderInfo::const_iterator it, end = itLine->end();
+        for (it = itLine->begin(); it!=end; ++it)
+        {
+            // ** apply the vertex array
+            af.apply(osg::Drawable::VERTICES, it->_glyph->getVertexArray()->size(), &(it->_glyph->getVertexArray()->front()));
+        }
+    }
+}
+void Text3D::accept(osg::PrimitiveFunctor& pf) const
+{
+    // ** for each line, do ...
+    TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
+    for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
+    {
+        // ** for each glyph in the line, do ...
+        LineRenderInfo::const_iterator it, end = itLine->end();
+        for (it = itLine->begin(); it!=end; ++it)
+        {
+            pf.setVertexArray(it->_glyph->getVertexArray()->size(),&(it->_glyph->getVertexArray()->front()));
+
+            // ** render the front face of the glyph
+            osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList();
+            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
+            {
+                (*itr)->accept(pf);
+            }
+
+            // ** render the wall face of the glyph
+            osg::Geometry::PrimitiveSetList & pslWall = it->_glyph->getWallPrimitiveSetList();
+            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslWall.begin(), end=pslWall.end(); itr!=end; ++itr)
+            {
+                (*itr)->accept(pf);
+            }
+
+            // ** render the back face of the glyph
+            osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList();
+            for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
+            {
+                (*itr)->accept(pf);
+            }
+        }
+    }
+}
 
 void Text3D::setFont(osg::ref_ptr<Font3D> font)
-{ 
+{
     _font = font;
-    
+
     computeGlyphRepresentation();
 }
 
 void Text3D::setFont(const std::string & fontfile)
-{ 
+{
     setFont(readRefFont3DFile(fontfile));
 }
@@ -76,9 +117,9 @@
     float maximumHeight = _maximumHeight / _font->getScale();
     float maximumWidth = _maximumWidth / _font->getScale();
-    
+
     for(bool outOfSpace=false;lastChar!=last;++lastChar)
     {
         unsigned int charcode = *lastChar;
-        
+
         if (charcode=='\n')
         {
@@ -90,14 +131,14 @@
         {
             const osg::BoundingBox & bb = glyph->getBoundingBox();
-            
+
             // adjust cursor position w.r.t any kerning.
             if (previous_charcode)
             {
-                
+
                 if (_layout == RIGHT_TO_LEFT)
                 {
                     cursor.x() -= glyph->getHorizontalAdvance();
                 }
-                
+
                 if (kerning)
                 {
@@ -120,5 +161,5 @@
             }
             else
-            { 
+            {
                 switch (_layout)
                 {
@@ -136,8 +177,8 @@
                         break;
                 }
-                
-            }
-            
-            
+
+            }
+
+
 
             switch(_layout)
@@ -159,5 +200,5 @@
                 break;
             }
-            
+
             // => word boundary detection & wrapping
             if (outOfSpace) break;
@@ -176,9 +217,9 @@
 
     }
-    
+
     // word boundary detection & wrapping
     if (lastChar!=last)
     {
-        if (deliminatorSet.count(*lastChar)==0) 
+        if (deliminatorSet.count(*lastChar)==0)
         {
             String::iterator lastValidChar = lastChar;
@@ -186,5 +227,5 @@
             {
                 --lastValidChar;
-                
+
                 //Substract off glyphs from the cursor position (to correctly center text)
                 Font3D::Glyph3D* glyph = _font->getGlyph(*lastValidChar);
@@ -199,5 +240,5 @@
                 }
             }
-            
+
             if (first!=lastValidChar)
             {
@@ -214,9 +255,9 @@
 {
     if (_font.valid() == false) return;
-    
+
     _textRenderInfo.clear();
     _lineCount = 0;
-    
-    if (_text.empty()) 
+
+    if (_text.empty())
     {
         _textBB.set(0,0,0, 0,0,0);//no size text
@@ -224,5 +265,5 @@
         return;
     }
-    
+
     // initialize bounding box, it will be expanded during glyph position calculation
     _textBB.init();
@@ -232,12 +273,12 @@
     osg::Vec2 local(0.0f,0.0f);
     osg::Vec2 startOffset(0.0f,0.0f);
-    
+
     unsigned int previous_charcode = 0;
     unsigned int linelength = 0;
     bool kerning = true;
-    
+
     unsigned int lineNumber = 0;
 
-  
+
 
     for(String::iterator itr=_text.begin(); itr!=_text.end(); )
@@ -245,5 +286,5 @@
         _textRenderInfo.resize(lineNumber + 1);
         LineRenderInfo & currentLineRenderInfo = _textRenderInfo.back();
-        
+
         // record the start of the current line
         String::iterator startOfLine_itr = itr;
@@ -252,9 +293,9 @@
         osg::Vec2 endOfLine_coords(cursor);
         String::iterator endOfLine_itr = computeLastCharacterOnLine(endOfLine_coords, itr,_text.end());
-        
-        // ** position the cursor function to the Layout and the alignement 
+
+        // ** position the cursor function to the Layout and the alignement
         TextBase::positionCursor(endOfLine_coords, cursor, (unsigned int) (endOfLine_itr - startOfLine_itr));
 
-        
+
         if (itr!=endOfLine_itr)
         {
@@ -267,5 +308,5 @@
                 {
                     const osg::BoundingBox & bb = glyph->getBoundingBox();
-                    
+
                     // adjust cursor position w.r.t any kerning.
                     if (previous_charcode)
@@ -275,5 +316,5 @@
                             cursor.x() -= glyph->getHorizontalAdvance();
                         }
-                        
+
                         if (kerning)
                         {
@@ -296,5 +337,5 @@
                     }
                     else
-                    { 
+                    {
                         switch (_layout)
                         {
@@ -315,9 +356,9 @@
                             }
                         }
-                        
+
                     }
 
                     local = cursor;
-                    
+
                     if (_layout==VERTICAL)
                     {
@@ -325,7 +366,7 @@
                         local.y() += -glyph->getVerticalBearing().y();
                     }
-                     
-                    
-                    
+
+
+
                     // move the cursor onto the next character.
                     // also expand bounding box
@@ -345,12 +386,12 @@
                             _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMax(), cursor.y() + bb.yMax(), 0.0f)); //upper right corner
                             _textBB.expandBy(osg::Vec3(cursor.x()+bb.xMin(), cursor.y()+bb.yMin(), 0.0f)); //lower left corner
-                            
+
                             break;
                     }
-                    
+
                     osg::Vec3 pos = osg::Vec3(local.x(), local.y(), 0.0f);
                     currentLineRenderInfo.push_back(Text3D::GlyphRenderInfo(glyph, pos));
 
-                    
+
                     previous_charcode = charcode;
                 }
@@ -361,5 +402,5 @@
             ++itr;
         }
-                                
+
         if (itr!=_text.end())
         {
@@ -367,5 +408,5 @@
             if (*itr=='\n') ++itr;
         }
-                
+
         // move to new line.
         switch(_layout)
@@ -395,9 +436,7 @@
     }
     _textBB.expandBy(0.0f,0.0f,-1);
-    
+
     TextBase::computePositions();
 }
-
-
 
 osg::BoundingBox Text3D::computeBound() const
@@ -411,23 +450,15 @@
             osg::Matrix& matrix = _autoTransformCache[i]._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.zMax())*matrix);
-//          bbox.expandBy(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*matrix);
-        }
-    }
-    
+        }
+    }
+
     return bbox;
 }
 
-
-
-
-
-
-
 void Text3D::computePositions(unsigned int contextID) const
 {
     if (_font.valid() == false) return;
-    
+
     switch(_alignment)
     {
@@ -447,14 +478,14 @@
     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;
 
-    
+
     float scale = _font->getScale();
     osg::Vec3 scaleVec(scale * _characterHeight, scale * _characterHeight / _characterAspectRatio, _characterDepth);
@@ -464,9 +495,9 @@
     matrix.postMultTranslate(_position);
 
-    
+
     _normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix);
     _normal.normalize();
 
-    const_cast<Text3D*>(this)->dirtyBound();    
+    const_cast<Text3D*>(this)->dirtyBound();
 }
 
@@ -475,6 +506,6 @@
     osg::State & state = *renderInfo.getState();
     unsigned int contextID = state.getContextID();
-    
-    
+
+
     // ** save the previous modelview matrix
     osg::ref_ptr<osg::RefMatrix> previous(new osg::RefMatrix(state.getModelViewMatrix()));
@@ -485,16 +516,16 @@
     // ** mult previous by the modelview for this context
     modelview->postMult(*previous.get());
-   
+
     // ** apply this new modelview matrix
     state.applyModelViewMatrix(modelview.get());
-    
-    
+
+
     if (_drawMode & TEXT)
     {
         renderInfo.getState()->disableAllVertexArrays();
-        
+
         glPushAttrib(GL_TRANSFORM_BIT);
         glEnable(GL_RESCALE_NORMAL);
-        
+
         switch(_renderMode)
         {
@@ -503,5 +534,5 @@
             default:        renderPerGlyph(*renderInfo.getState());  break;
         }
-        
+
         glPopAttrib();
     }
@@ -515,10 +546,10 @@
             osg::Vec3 c110(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMax()));
             osg::Vec3 c010(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMax()));
-        
+
             osg::Vec3 c001(osg::Vec3(_textBB.xMin(),_textBB.yMin(),_textBB.zMin()));
             osg::Vec3 c101(osg::Vec3(_textBB.xMax(),_textBB.yMin(),_textBB.zMin()));
             osg::Vec3 c111(osg::Vec3(_textBB.xMax(),_textBB.yMax(),_textBB.zMin()));
             osg::Vec3 c011(osg::Vec3(_textBB.xMin(),_textBB.yMax(),_textBB.zMin()));
-        
+
             glBegin(GL_LINE_LOOP);
                 glVertex3fv(c000.ptr());
@@ -527,5 +558,5 @@
                 glVertex3fv(c010.ptr());
             glEnd();
-            
+
             glBegin(GL_LINE_LOOP);
                 glVertex3fv(c001.ptr());
@@ -534,20 +565,20 @@
                 glVertex3fv(c101.ptr());
             glEnd();
-            
+
             glBegin(GL_LINES);
                 glVertex3fv(c000.ptr());
                 glVertex3fv(c001.ptr());
-                
+
                 glVertex3fv(c100.ptr());
                 glVertex3fv(c101.ptr());
-                
+
                 glVertex3fv(c110.ptr());
                 glVertex3fv(c111.ptr());
-                
+
                 glVertex3fv(c010.ptr());
                 glVertex3fv(c011.ptr());
             glEnd();
         }
-    }    
+    }
 
     if (_drawMode & ALIGNMENT)
@@ -566,5 +597,5 @@
             glVertex3fv(vb.ptr());
         glEnd();
-        
+
     }
 
@@ -573,8 +604,6 @@
 }
 
-
-
 void Text3D::renderPerGlyph(osg::State & state) const
-{   
+{
     // ** for each line, do ...
     TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
@@ -585,22 +614,21 @@
         for (it = itLine->begin(); it!=end; ++it)
         {
-            
+
             glPushMatrix();
 
             glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
-           
+
             // ** apply the vertex array
             state.setVertexPointer(it->_glyph->getVertexArray());
-            
+
             // ** render the front face of the glyph
             glNormal3f(0.0f,0.0f,1.0f);
-            
+
             osg::Geometry::PrimitiveSetList & pslFront = it->_glyph->getFrontPrimitiveSetList();
             for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslFront.begin(), end = pslFront.end(); itr!=end; ++itr)
             {
-                
                 (*itr)->draw(state, false);
             }
-            
+
             // ** render the wall face of the glyph
             state.setNormalPointer(it->_glyph->getNormalArray());
@@ -610,8 +638,9 @@
                 (*itr)->draw(state, false);
             }
-            
+            state.disableNormalPointer();
+
             // ** render the back face of the glyph
             glNormal3f(0.0f,0.0f,-1.0f);
-                        
+
             osg::Geometry::PrimitiveSetList & pslBack = it->_glyph->getBackPrimitiveSetList();
             for(osg::Geometry::PrimitiveSetList::const_iterator itr=pslBack.begin(), end=pslBack.end(); itr!=end; ++itr)
@@ -619,5 +648,5 @@
                 (*itr)->draw(state, false);
             }
-            
+
             glPopMatrix();
         }
@@ -629,5 +658,5 @@
     // ** render all front faces
     glNormal3f(0.0f,0.0f,1.0f);
-    
+
     TextRenderInfo::const_iterator itLine, endLine = _textRenderInfo.end();
     for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
@@ -635,10 +664,10 @@
         // ** for each glyph in the line, do ...
         LineRenderInfo::const_iterator it, end = itLine->end();
-        for (it = itLine->begin(); it!=end; ++it)   
+        for (it = itLine->begin(); it!=end; ++it)
         {
             glPushMatrix();
             glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
             state.setVertexPointer(it->_glyph->getVertexArray());
-            
+
             // ** render the front face of the glyph
             osg::Geometry::PrimitiveSetList & psl = it->_glyph->getFrontPrimitiveSetList();
@@ -650,5 +679,5 @@
         }
     }
-    
+
 
     // ** render all wall face of the text
@@ -663,5 +692,5 @@
             state.setVertexPointer(it->_glyph->getVertexArray());
             state.setNormalPointer(it->_glyph->getNormalArray());
-            
+
             osg::Geometry::PrimitiveSetList & psl = it->_glyph->getWallPrimitiveSetList();
             for(osg::Geometry::PrimitiveSetList::const_iterator itr=psl.begin(), end=psl.end(); itr!=end; ++itr)
@@ -673,8 +702,8 @@
     }
 
-    
+
     // ** render all back face of the text
     glNormal3f(0.0f,0.0f,-1.0f);
-                
+
     for (itLine = _textRenderInfo.begin(); itLine!=endLine; ++itLine)
     {
@@ -686,5 +715,5 @@
             glTranslatef(it->_position.x(), it->_position.y(), it->_position.z());
             state.setVertexPointer(it->_glyph->getVertexArray());
-            
+
             // ** render the back face of the glyph
             osg::Geometry::PrimitiveSetList & psl = it->_glyph->getBackPrimitiveSetList();
@@ -710,5 +739,5 @@
 {
     TextBase::resizeGLObjectBuffers(maxSize);
-    
+
     if (_font.valid()) _font->resizeGLObjectBuffers(maxSize);
 }
@@ -717,5 +746,5 @@
 {
     TextBase::releaseGLObjects(state);
-    
+
     if (_font.valid()) _font->releaseGLObjects(state);
 }
Index: /OpenSceneGraph/trunk/src/osgText/Font3D.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgText/Font3D.cpp (revision 7874)
+++ /OpenSceneGraph/trunk/src/osgText/Font3D.cpp (revision 9881)
@@ -1,12 +1,12 @@
-/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
+/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
  *
- * This library is open source and may be redistributed and/or modified under  
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
+ * This library is open source and may be redistributed and/or modified under
+ * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  * (at your option) any later version.  The full license is in LICENSE file
  * included with this distribution, and on the openscenegraph.org website.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * OpenSceneGraph Public License for more details.
 */
@@ -87,5 +87,5 @@
 
     // Not found, return empty string
-    osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;    
+    osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;
     return std::string();
 }
@@ -95,7 +95,20 @@
     if (filename=="") return 0;
 
-    std::string foundFile = findFont3DFile(filename);
+    // unsure filename have not .text3d at the end
+    std::string tmpFilename;
+    std::string text3dExt = ".text3d";
+    std::string ext = osgDB::getFileExtensionIncludingDot(filename);
+    if (ext == text3dExt)
+        tmpFilename = filename.substr(filename.size() - ext.size(), ext.size());
+    else
+        tmpFilename = filename;
+
+    //search font file
+    std::string foundFile = findFont3DFile(tmpFilename);
     if (foundFile.empty()) return 0;
-    
+
+    //unsure filename have .text3d at the end
+    foundFile += text3dExt;
+
     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex);
 
@@ -105,14 +118,8 @@
         localOptions = new osgDB::ReaderWriter::Options;
         localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
-        // ** HACK to load Font3D instead of Font
-        localOptions->setPluginData("3D", (void*) 1);
-    }
-    else
-    {
-        userOptions->setPluginData("3D", (void*) 1);
     }
 
     osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? userOptions : localOptions.get());
-    
+
     // if the object is a font then return it.
     osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object);
@@ -143,5 +150,5 @@
     osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf");
     if (reader == 0) return 0;
-    
+
     osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get());
     if (rr.error())
@@ -151,5 +158,5 @@
     }
     if (!rr.validObject()) return 0;
-    
+
     osg::Object *object = rr.takeObject();
 
@@ -167,7 +174,17 @@
     if (filename=="") return 0;
 
-    std::string foundFile = findFont3DFile(filename);
+    std::string tmpFilename;
+    std::string text3dExt = ".text3d";
+    std::string ext = osgDB::getFileExtensionIncludingDot(filename);
+    if (ext == text3dExt)
+        tmpFilename = filename.substr(0, filename.size() - ext.size());
+    else
+        tmpFilename = filename;
+
+    std::string foundFile = findFont3DFile(tmpFilename);
     if (foundFile.empty()) return 0;
-    
+
+    foundFile += text3dExt;
+
     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex);
 
@@ -177,14 +194,8 @@
         localOptions = new osgDB::ReaderWriter::Options;
         localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS);
-        // ** HACK to load Font3D instead of Font
-        localOptions->setPluginData("3D", (void*) 1);
-    }
-    else
-    {
-        userOptions->setPluginData("3D", (void*) 1);
     }
 
     osg::ref_ptr<osg::Object> object = osgDB::readRefObjectFile(foundFile, userOptions ? userOptions : localOptions.get());
-    
+
     // if the object is a font then return it.
     osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object.get());
@@ -213,5 +224,5 @@
     osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf");
     if (reader == 0) return 0;
-    
+
     osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get());
     if (rr.error())
@@ -268,9 +279,9 @@
 Font3D::Glyph3D* Font3D::getGlyph(unsigned int charcode)
 {
-    Glyph3D * glyph3D = NULL; 
-    
+    Glyph3D * glyph3D = NULL;
+
     Glyph3DMap::iterator itr = _glyph3DMap.find(charcode);
     if (itr!=_glyph3DMap.end()) glyph3D = itr->second.get();
-    
+
     else if (_implementation.valid())
     {
@@ -278,5 +289,5 @@
         if (glyph3D) _glyph3DMap[charcode] = glyph3D;
     }
-    
+
     return glyph3D;
 }
@@ -285,5 +296,5 @@
 {
     Glyph3DMap::iterator it,end = _glyph3DMap.end();
-    
+
     for (it=_glyph3DMap.begin(); it!=end; ++it)
         it->second->setThreadSafeRefUnref(threadSafe);
Index: /OpenSceneGraph/trunk/src/osgDB/Registry.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgDB/Registry.cpp (revision 9880)
+++ /OpenSceneGraph/trunk/src/osgDB/Registry.cpp (revision 9881)
@@ -319,6 +319,7 @@
     addFileExtensionAlias("cef",   "freetype");  // OpenType
     addFileExtensionAlias("fon",   "freetype");  // Windows bitmap fonts
-    addFileExtensionAlias("fnt",   "freetype");    // Windows bitmap fonts
-    
+    addFileExtensionAlias("fnt",   "freetype");  // Windows bitmap fonts
+    addFileExtensionAlias("text3d", "freetype"); // use 3D Font instead of 2D Font
+
     // wont't add type1 and type2 until resolve extension collision with Performer binary and ascii files.
     // addFileExtensionAlias("pfb",   "freetype");  // type1 binary
