root/OpenSceneGraph/trunk/src/osgText/FadeText.cpp @ 11477

Revision 11477, 13.1 kB (checked in by robert, 4 years ago)

converted osg::notify to OSG_INFO etc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
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
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14
15#include <osgText/FadeText>
16#include <osg/Notify>
17#include <osg/io_utils>
18#include <OpenThreads/Mutex>
19#include <OpenThreads/ScopedLock>
20
21using namespace osgText;
22
23struct FadeTextData : public osg::Referenced
24{
25    FadeTextData(FadeText* fadeText=0):
26        _fadeText(fadeText),
27        _visible(true) {}
28       
29    bool operator < (const FadeTextData& rhs) const
30    {
31        return _fadeText < rhs._fadeText;
32    }   
33   
34    double getNearestZ() const
35    {
36        double nearestZ = _vertices[0].z();
37        if (nearestZ < _vertices[1].z()) nearestZ = _vertices[1].z();
38        if (nearestZ < _vertices[2].z()) nearestZ = _vertices[2].z();
39        if (nearestZ < _vertices[3].z()) nearestZ = _vertices[3].z();
40
41        // OSG_NOTICE<<"getNearestZ()="<<_fadeText->getText().createUTF8EncodedString()<<" "<<nearestZ<<std::endl;
42
43        return nearestZ;
44    }
45
46    FadeText*   _fadeText;
47    osg::Vec3d   _vertices[4];
48    bool        _visible;
49};
50
51struct FadeTextPolytopeData : public FadeTextData, public osg::Polytope
52{
53    FadeTextPolytopeData(FadeTextData& fadeTextData):
54        FadeTextData(fadeTextData)
55    {
56        _referenceVertexList.push_back(_vertices[0]);
57        _referenceVertexList.push_back(_vertices[1]);
58        _referenceVertexList.push_back(_vertices[2]);
59        _referenceVertexList.push_back(_vertices[3]);
60    }
61   
62    void addEdgePlane(const osg::Vec3& corner, const osg::Vec3& edge)
63    {
64        osg::Vec3 normal( edge.y(), -edge.x(), 0.0f);
65        normal.normalize();
66       
67        add(osg::Plane(normal, corner));
68    }
69     
70    void buildPolytope()
71    {
72        osg::Vec3d edge01 = _vertices[1] - _vertices[0];
73        osg::Vec3d edge12 = _vertices[2] - _vertices[1];
74        osg::Vec3d edge23 = _vertices[3] - _vertices[2];
75        osg::Vec3d edge30 = _vertices[0] - _vertices[3];
76
77        osg::Vec3d normalFrontFace = edge01 ^ edge12;
78        bool needToFlip = normalFrontFace.z()>0.0f;
79
80        normalFrontFace.normalize();
81        add(osg::Plane(normalFrontFace, _vertices[0]));
82
83        add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[0], _vertices[1]));
84        add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[1], _vertices[2]));
85        add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[2], _vertices[3]));
86        add(osg::Plane( osg::Vec3d(0.0f,0.0f,0.0f), _vertices[3], _vertices[0]));
87       
88#if 0
89        OSG_NOTICE<<" normalFrontFace = "<<normalFrontFace<<std::endl;
90        OSG_NOTICE<<" edge01 = "<<edge01<<std::endl;
91        OSG_NOTICE<<" edge12 = "<<edge12<<std::endl;
92        OSG_NOTICE<<" edge23 = "<<edge23<<std::endl;
93        OSG_NOTICE<<" _vertices[0]= "<<_vertices[0]<<std::endl;
94        OSG_NOTICE<<" _vertices[1]= "<<_vertices[1]<<std::endl;
95        OSG_NOTICE<<" _vertices[2]= "<<_vertices[2]<<std::endl;
96        OSG_NOTICE<<" _vertices[3]= "<<_vertices[3]<<std::endl;
97#endif
98
99        if (needToFlip) flip();
100
101#if 0       
102        OSG_NOTICE<<"   plane 0 "<< _planeList[0]<<std::endl;
103        OSG_NOTICE<<"   plane 1 "<< _planeList[1]<<std::endl;
104        OSG_NOTICE<<"   plane 2 "<< _planeList[2]<<std::endl;
105        OSG_NOTICE<<"   plane 3 "<< _planeList[3]<<std::endl;
106        OSG_NOTICE<<"   plane 4 "<< _planeList[4]<<std::endl;
107#endif
108       
109    }
110   
111    inline bool contains(const std::vector<osg::Vec3>& vertices)
112    {
113        for(std::vector<osg::Vec3>::const_iterator itr = vertices.begin();
114            itr != vertices.end();
115            ++itr)
116        {
117            if (osg::Polytope::contains(*itr))
118            {
119                return true;
120            }
121        }
122        return false;
123    }
124   
125};
126
127struct FadeTextUserData : public osg::Referenced
128{
129    FadeTextUserData():
130        _frameNumber(0) {}
131
132    typedef std::list<FadeTextData> FadeTextList;
133    unsigned int _frameNumber;
134    FadeTextList _fadeTextInView;
135};
136
137struct GlobalFadeText : public osg::Referenced
138{
139    typedef std::set< osg::ref_ptr<FadeTextUserData> > UserDataSet;
140    typedef std::set<FadeText*> FadeTextSet;
141    typedef std::multimap<double, osg::ref_ptr<FadeTextPolytopeData> > FadeTextPolytopeMap;
142    typedef std::map<osg::View*, UserDataSet> ViewUserDataMap;
143    typedef std::map<osg::View*, FadeTextSet > ViewFadeTextMap;
144
145    GlobalFadeText():
146        _frameNumber(0xffffffff)
147    {
148    }
149
150   
151    FadeTextUserData* createNewFadeTextUserData(osg::View* view)
152    {
153        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
154       
155        FadeTextUserData* userData = new FadeTextUserData;
156
157        if (!userData)
158        {
159            OSG_NOTICE<<"Memory error, unable to create FadeTextUserData."<<std::endl;
160            return 0;
161        }
162
163        _viewMap[view].insert(userData);
164       
165        return userData;
166    }
167   
168   
169    void update(unsigned int frameNumber)
170    {
171        _frameNumber = frameNumber;
172       
173        for(GlobalFadeText::ViewUserDataMap::iterator vitr = _viewMap.begin();
174            vitr != _viewMap.end();
175            ++vitr)
176        {
177       
178            osg::View* view = vitr->first;
179
180            FadeTextSet& fadeTextSet = _viewFadeTextMap[view];
181            fadeTextSet.clear();
182
183            FadeTextPolytopeMap fadeTextPolytopeMap;
184
185            for(GlobalFadeText::UserDataSet::iterator uitr = vitr->second.begin();
186                uitr != vitr->second.end();
187                ++uitr)
188            {
189                FadeTextUserData* userData = uitr->get();
190               
191                int frameDelta = frameNumber - userData->_frameNumber;
192                if (frameDelta<=1)
193                {
194                    for(FadeTextUserData::FadeTextList::iterator fitr = userData->_fadeTextInView.begin();
195                        fitr != userData->_fadeTextInView.end();
196                        ++fitr)
197                    {
198                        FadeTextData& fadeTextData = *fitr;
199                        if (fadeTextSet.count(fadeTextData._fadeText)==0)
200                        {
201                            fadeTextSet.insert(fadeTextData._fadeText);
202                            fadeTextPolytopeMap.insert(FadeTextPolytopeMap::value_type(
203                                -fadeTextData.getNearestZ(), new FadeTextPolytopeData(fadeTextData)));
204                        }
205                    }
206                }
207            }
208
209            // for each FadeTexPoltopeData           
210            //    create polytopes
211            //    test against all FTPD's later in the list
212            //       test all control points on FTPD against each plane of the current polytope
213            //       if all control points removed or outside then discard FTPD and make FT visible = false;
214           
215            FadeTextPolytopeMap::iterator outer_itr = fadeTextPolytopeMap.begin();               
216            while (outer_itr != fadeTextPolytopeMap.end())
217            {
218                FadeTextPolytopeMap::iterator inner_itr = outer_itr;
219                ++inner_itr;
220
221                if (inner_itr == fadeTextPolytopeMap.end()) break;
222
223                FadeTextPolytopeData& outer_ftpm = *(outer_itr->second);
224                outer_ftpm.buildPolytope();
225
226                // OSG_NOTICE<<"Outer z "<<outer_ftpm.getNearestZ()<<std::endl;
227
228                while(inner_itr != fadeTextPolytopeMap.end())
229                {
230                    FadeTextPolytopeData& inner_ftpm = *(inner_itr->second);
231                   
232                    // OSG_NOTICE<<"Inner z "<<inner_ftpm.getNearestZ()<<std::endl;
233
234                    if (outer_ftpm.contains(inner_ftpm.getReferenceVertexList()))
235                    {
236                        FadeTextPolytopeMap::iterator erase_itr = inner_itr;
237                        // move to next ftpm
238                        ++inner_itr;
239                       
240                        fadeTextSet.erase(inner_ftpm._fadeText);
241
242                        // need to remove inner_ftpm as its occluded.
243                        fadeTextPolytopeMap.erase(erase_itr);
244                       
245                    }
246                    else
247                    {
248                        // move to next ftpm
249                        ++inner_itr;
250                    }
251                }
252
253                ++outer_itr;
254
255            }
256        }
257    }
258   
259    inline void updateIfRequired(unsigned int frameNumber)
260    {
261        if (_frameNumber!=frameNumber) update(frameNumber);
262    }
263
264    unsigned int _frameNumber;
265    OpenThreads::Mutex _mutex;
266    ViewUserDataMap _viewMap;
267    ViewFadeTextMap _viewFadeTextMap;
268};
269
270GlobalFadeText* getGlobalFadeText()
271{
272    static osg::ref_ptr<GlobalFadeText> s_globalFadeText = new GlobalFadeText;
273    return s_globalFadeText.get();
274}
275
276struct FadeText::FadeTextUpdateCallback : public osg::Drawable::UpdateCallback
277{
278    FadeTextData _ftd;
279
280    virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)
281    {
282        osgText::FadeText* fadeText = dynamic_cast<osgText::FadeText*>(drawable);
283        if (!fadeText) return;
284   
285        unsigned int frameNumber = nv->getFrameStamp()->getFrameNumber();
286
287        GlobalFadeText* gft = getGlobalFadeText();
288        gft->updateIfRequired(frameNumber);
289       
290        osgText::FadeText::ViewBlendColourMap& vbcm = fadeText->getViewBlendColourMap();
291
292        _ftd._fadeText = fadeText;
293       
294        float fadeSpeed = fadeText->getFadeSpeed();
295
296        GlobalFadeText::ViewFadeTextMap& vftm = gft->_viewFadeTextMap;
297        for(GlobalFadeText::ViewFadeTextMap::iterator itr = vftm.begin();
298            itr != vftm.end();
299            ++itr)
300        {
301            osg::View* view = itr->first;
302            GlobalFadeText::FadeTextSet& fadeTextSet = itr->second;
303            bool visible = fadeTextSet.count(fadeText)!=0;
304
305            osg::Vec4& tec = vbcm[view];
306            tec[0] = 1.0f;
307            tec[1] = 1.0f;
308            tec[2] = 1.0f;
309            if (visible)
310            {
311                if (tec[3]<1.0f)
312                {
313                    tec[3] += fadeSpeed;
314                    if (tec[3]>1.0f) tec[3] = 1.0f;
315                }
316
317            }
318            else
319            {
320                if (tec[3]>0.0f)
321                {
322                    tec[3] -= fadeSpeed;
323                    if (tec[3]<0.0f) tec[3] = 0.0f;
324                }
325            }
326        }
327
328    }
329};
330
331
332FadeText::FadeText()
333{
334    init();
335}
336
337FadeText::FadeText(const Text& text,const osg::CopyOp& copyop):
338    Text(text,copyop)
339{
340    init();
341}
342
343void FadeText::init()
344{
345    setDataVariance(osg::Object::DYNAMIC);
346
347    _fadeSpeed = 0.01f;
348    setUpdateCallback(new FadeTextUpdateCallback());
349}
350
351
352
353void FadeText::drawImplementation(osg::RenderInfo& renderInfo) const
354{
355
356    osg::State& state = *renderInfo.getState();
357
358    ViewBlendColourMap::iterator itr = _viewBlendColourMap.find(renderInfo.getView());
359    if (itr != _viewBlendColourMap.end())
360    {
361        Text::drawImplementation(*renderInfo.getState(), itr->second );
362    }
363    else
364    {
365        Text::drawImplementation(*renderInfo.getState(), osg::Vec4(1.0f,1.0f,1.0f,1.0f) );
366    }
367   
368
369    // now pass on new details
370
371    FadeTextUserData* userData = dynamic_cast<FadeTextUserData*>(renderInfo.getUserData());
372    if (!userData)
373    {
374        if (renderInfo.getUserData())
375        {
376            OSG_NOTICE<<"Warning user data not of supported type."<<std::endl;
377            return;
378        }
379
380        userData = getGlobalFadeText()->createNewFadeTextUserData(renderInfo.getView());
381
382        if (!userData)
383        {
384            OSG_NOTICE<<"Memory error, unable to create FadeTextUserData."<<std::endl;
385            return;
386        }
387
388        renderInfo.setUserData(userData);
389    }
390
391    unsigned int frameNumber = renderInfo.getState()->getFrameStamp()->getFrameNumber();
392    if (frameNumber != userData->_frameNumber)
393    {
394        // new frame so must reset UserData structure.
395        userData->_frameNumber = frameNumber;
396        userData->_fadeTextInView.clear();
397    }
398
399
400
401    osgText::Text::AutoTransformCache& atc = _autoTransformCache[renderInfo.getContextID()];
402   
403    osg::Matrix lmv = atc._matrix;
404    lmv.postMult(state.getModelViewMatrix());
405   
406    if (renderInfo.getView() && renderInfo.getView()->getCamera())
407    {
408        // move from camera into the view space.
409        lmv.postMult(state.getInitialInverseViewMatrix());
410        lmv.postMult(renderInfo.getView()->getCamera()->getViewMatrix());
411    }
412   
413    FadeTextData ftd(const_cast<osgText::FadeText*>(this));
414   
415    ftd._vertices[0].set(osg::Vec3d(_textBB.xMin(),_textBB.yMin(),_textBB.zMin())*lmv);
416    ftd._vertices[1].set(osg::Vec3d(_textBB.xMax(),_textBB.yMin(),_textBB.zMin())*lmv);
417    ftd._vertices[2].set(osg::Vec3d(_textBB.xMax(),_textBB.yMax(),_textBB.zMin())*lmv);
418    ftd._vertices[3].set(osg::Vec3d(_textBB.xMin(),_textBB.yMax(),_textBB.zMin())*lmv);
419
420    userData->_fadeTextInView.push_back(ftd);
421
422}
Note: See TracBrowser for help on using the browser.