Show
Ignore:
Timestamp:
03/10/09 11:56:00 (5 years ago)
Author:
robert
Message:

From David Callu, "Problem:

osgText::Text and osgText::Text3D use the same font file.
The first really load the file and obtain an osgText::Font object,
the second use the cache created during the first load of the
font file, and so obtain an osgText::Font object instead of
osgText::Font3D object. To obtain an osgText::Font3D object,
osgText::Text3D call osgDB::readObjectFile(...) with an option
to specify the plugin we want an osgText::Font3D instead of
osgText::Font.

Generalised Problem:

In osgDB::Registry, loaded file cache is referenced by the name
of this file, so if I load a file with some options, and the cache
already contain object for this filename, I obtain an object
potentially not loaded with my options.

Behaviours:

Cache management is delegate to osgDB::Registry, but cache
coherence (load a file with option then reuse it, deactivate the
cache when load a specific file or don't cached the loaded file)
is user's responsibility.

Text3D solution:

Postfix the font file name by .text3d or something similar and then have the freetype plugin return
osgText::Font3D when it detects this.
This operation is done by osgText::readFont3DFile() which unsure the filename have .text3d as extension.
This is totaly transparent for user, and backward compatible.

BTW, I fix the bug about the Normal of 3D text. Currently, the front and wall face have
the same normal (0,0,1) in the Text3D object coordinate. Now the wall face have its own
normal array computed by the plugin.

BTW 2, I implement
- void Text3D::accept(osg::Drawable::ConstAttributeFunctor?& af) const
- void Text3D::accept(osg::PrimitiveFunctor?& pf) const
so now statistics are well reported.
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgText/Font3D.cpp

    r7874 r9881  
    1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield  
     1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
    22 * 
    3  * This library is open source and may be redistributed and/or modified under   
    4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or  
     3 * This library is open source and may be redistributed and/or modified under 
     4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
    55 * (at your option) any later version.  The full license is in LICENSE file 
    66 * included with this distribution, and on the openscenegraph.org website. 
    7  *  
     7 * 
    88 * This library is distributed in the hope that it will be useful, 
    99 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
     10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    1111 * OpenSceneGraph Public License for more details. 
    1212*/ 
     
    8787 
    8888    // Not found, return empty string 
    89     osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;     
     89    osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl; 
    9090    return std::string(); 
    9191} 
     
    9595    if (filename=="") return 0; 
    9696 
    97     std::string foundFile = findFont3DFile(filename); 
     97    // unsure filename have not .text3d at the end 
     98    std::string tmpFilename; 
     99    std::string text3dExt = ".text3d"; 
     100    std::string ext = osgDB::getFileExtensionIncludingDot(filename); 
     101    if (ext == text3dExt) 
     102        tmpFilename = filename.substr(filename.size() - ext.size(), ext.size()); 
     103    else 
     104        tmpFilename = filename; 
     105 
     106    //search font file 
     107    std::string foundFile = findFont3DFile(tmpFilename); 
    98108    if (foundFile.empty()) return 0; 
    99      
     109 
     110    //unsure filename have .text3d at the end 
     111    foundFile += text3dExt; 
     112 
    100113    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex); 
    101114 
     
    105118        localOptions = new osgDB::ReaderWriter::Options; 
    106119        localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); 
    107         // ** HACK to load Font3D instead of Font 
    108         localOptions->setPluginData("3D", (void*) 1); 
    109     } 
    110     else 
    111     { 
    112         userOptions->setPluginData("3D", (void*) 1); 
    113120    } 
    114121 
    115122    osg::Object* object = osgDB::readObjectFile(foundFile, userOptions ? userOptions : localOptions.get()); 
    116      
     123 
    117124    // if the object is a font then return it. 
    118125    osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object); 
     
    143150    osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf"); 
    144151    if (reader == 0) return 0; 
    145      
     152 
    146153    osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get()); 
    147154    if (rr.error()) 
     
    151158    } 
    152159    if (!rr.validObject()) return 0; 
    153      
     160 
    154161    osg::Object *object = rr.takeObject(); 
    155162 
     
    167174    if (filename=="") return 0; 
    168175 
    169     std::string foundFile = findFont3DFile(filename); 
     176    std::string tmpFilename; 
     177    std::string text3dExt = ".text3d"; 
     178    std::string ext = osgDB::getFileExtensionIncludingDot(filename); 
     179    if (ext == text3dExt) 
     180        tmpFilename = filename.substr(0, filename.size() - ext.size()); 
     181    else 
     182        tmpFilename = filename; 
     183 
     184    std::string foundFile = findFont3DFile(tmpFilename); 
    170185    if (foundFile.empty()) return 0; 
    171      
     186 
     187    foundFile += text3dExt; 
     188 
    172189    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_Font3DFileMutex); 
    173190 
     
    177194        localOptions = new osgDB::ReaderWriter::Options; 
    178195        localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_OBJECTS); 
    179         // ** HACK to load Font3D instead of Font 
    180         localOptions->setPluginData("3D", (void*) 1); 
    181     } 
    182     else 
    183     { 
    184         userOptions->setPluginData("3D", (void*) 1); 
    185196    } 
    186197 
    187198    osg::ref_ptr<osg::Object> object = osgDB::readRefObjectFile(foundFile, userOptions ? userOptions : localOptions.get()); 
    188      
     199 
    189200    // if the object is a font then return it. 
    190201    osgText::Font3D* font3D = dynamic_cast<osgText::Font3D*>(object.get()); 
     
    213224    osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension("ttf"); 
    214225    if (reader == 0) return 0; 
    215      
     226 
    216227    osgDB::ReaderWriter::ReadResult rr = reader->readObject(stream, userOptions ? userOptions : localOptions.get()); 
    217228    if (rr.error()) 
     
    268279Font3D::Glyph3D* Font3D::getGlyph(unsigned int charcode) 
    269280{ 
    270     Glyph3D * glyph3D = NULL;  
    271      
     281    Glyph3D * glyph3D = NULL; 
     282 
    272283    Glyph3DMap::iterator itr = _glyph3DMap.find(charcode); 
    273284    if (itr!=_glyph3DMap.end()) glyph3D = itr->second.get(); 
    274      
     285 
    275286    else if (_implementation.valid()) 
    276287    { 
     
    278289        if (glyph3D) _glyph3DMap[charcode] = glyph3D; 
    279290    } 
    280      
     291 
    281292    return glyph3D; 
    282293} 
     
    285296{ 
    286297    Glyph3DMap::iterator it,end = _glyph3DMap.end(); 
    287      
     298 
    288299    for (it=_glyph3DMap.begin(); it!=end; ++it) 
    289300        it->second->setThreadSafeRefUnref(threadSafe);