root/OpenSceneGraph/trunk/src/osgManipulator/AntiSquish.cpp @ 6383

Revision 6383, 5.1 kB (checked in by robert, 7 years ago)

Added osg:: to computeLocalToWorld to fix build under VS7.

  • 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//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
14
15#include <osgManipulator/AntiSquish>
16
17using namespace osgManipulator;
18
19namespace
20{
21    class AntiSquishCallback: public osg::NodeCallback
22    {
23        public:
24            AntiSquishCallback(AntiSquish* asq) : osg::NodeCallback(), _antiSquish(asq) {}
25            virtual ~AntiSquishCallback() {};
26           
27            virtual void operator() (osg::Node*, osg::NodeVisitor* nv)
28            {
29                // Get the node path.
30                osg::NodePath np = nv->getNodePath();
31
32                // Remove the last node which is the anti squish node itself.
33                np.pop_back();
34
35                // Get the accumulated modeling matrix.
36                osg::Matrix localToWorld = osg::computeLocalToWorld(np);
37
38                // compute the unsquished matrix.
39                bool flag = false;
40                osg::Matrix _unsquishedMatrix = _antiSquish->computeUnSquishedMatrix(localToWorld, flag);
41                if (flag)
42                    _antiSquish->setMatrix(_unsquishedMatrix);
43            }
44
45        protected:
46            AntiSquish* _antiSquish;
47    };
48
49}
50
51AntiSquish::AntiSquish() : _usePivot(true), _usePosition(false)
52{
53    _asqCallback = new AntiSquishCallback(this);
54    setUpdateCallback(_asqCallback);
55}
56
57AntiSquish::AntiSquish(const osg::Vec3& pivot) : _pivot(pivot), _usePivot(true), _usePosition(false)
58{
59    _asqCallback = new AntiSquishCallback(this);
60    setUpdateCallback(_asqCallback);
61}
62
63AntiSquish::AntiSquish(const osg::Vec3& pivot, const osg::Vec3& pos)
64    : _pivot(pivot), _usePivot(true), _position(pos), _usePosition(true)
65{
66    _asqCallback = new AntiSquishCallback(this);
67    setUpdateCallback(_asqCallback);
68}
69
70
71AntiSquish::AntiSquish(const AntiSquish& pat,const osg::CopyOp& copyop) :
72    MatrixTransform(pat,copyop),
73    _asqCallback(pat._asqCallback),
74    _pivot(pat._pivot),
75    _usePivot(pat._usePivot),
76    _position(pat._position),
77    _usePosition(pat._usePosition),
78    _cachedLocalToWorld(pat._cachedLocalToWorld)
79{
80}
81
82AntiSquish::~AntiSquish()
83{
84}
85
86osg::Matrix AntiSquish::computeUnSquishedMatrix(const osg::Matrix& LTW, bool& flag)
87{
88    osg::Vec3d t, s;
89    osg::Quat r, so;
90
91    if (LTW == _cachedLocalToWorld && _dirty == false)
92    {
93        flag = false;
94        return osg::Matrix::identity();
95    }
96
97    _cachedLocalToWorld = LTW;
98
99    LTW.decompose(t, r, s, so);
100
101    // Let's take an average of the scale.
102    double av = (s[0] + s[1] + s[2])/3.0;
103    s[0] = av; s[1] = av; s[2]=av;
104
105    if (av == 0)
106    {
107        flag = false;
108        return osg::Matrix::identity();
109    }
110
111    osg::Matrix unsquished;
112   
113    //
114    // Final Matrix: [-Pivot][SO]^[S][SO][R][T][Pivot][LOCALTOWORLD]^[position]
115    // OR [SO]^[S][SO][R][T][LOCALTOWORLD]^
116    //
117    if (_usePivot)
118    {
119        osg::Matrix tmpPivot;
120        tmpPivot.setTrans(-_pivot);
121        unsquished.postMult(tmpPivot);
122
123        osg::Matrix tmps, invtmps;
124        so.get(tmps);
125        invtmps = osg::Matrix::inverse(tmps);
126        if (invtmps.isNaN())
127        {
128            flag = false;
129            return osg::Matrix::identity();
130        }
131 
132        //SO^
133        unsquished.postMult(invtmps);
134        //S
135        unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2]));
136        //SO
137        unsquished.postMult(tmps);
138        tmpPivot.makeIdentity();
139        osg::Matrix tmpr;
140        r.get(tmpr);
141        //R
142        unsquished.postMult(tmpr);
143        //T
144        unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2]));
145
146        osg::Matrix invltw;
147        invltw = osg::Matrix::inverse(LTW);
148        if (invltw.isNaN())
149        {
150            flag =false;
151            return osg::Matrix::identity();
152        }
153        // LTW^
154        unsquished.postMult( invltw );
155
156        // Position
157        tmpPivot.makeIdentity();
158        if (_usePosition)
159            tmpPivot.setTrans(_position);
160        else
161            tmpPivot.setTrans(_pivot);
162
163        unsquished.postMult(tmpPivot);
164    }
165    else
166    {
167        osg::Matrix tmps, invtmps;
168        so.get(tmps);
169        invtmps = osg::Matrix::inverse(tmps);
170        unsquished.postMult(invtmps);
171        unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2]));
172        unsquished.postMult(tmps);
173        osg::Matrix tmpr;
174        r.get(tmpr);
175        unsquished.postMult(tmpr);
176        unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2]));
177        unsquished.postMult( osg::Matrix::inverse(LTW) );
178    }
179
180    if (unsquished.isNaN())
181    {
182        flag = false;
183        return  osg::Matrix::identity();
184    }
185
186    flag = true;
187    _dirty = false;
188    return unsquished;
189}
190
191
Note: See TracBrowser for help on using the browser.