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

Revision 13041, 5.0 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • 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* 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                traverse(node,nv);
44            }
45
46        protected:
47            AntiSquish* _antiSquish;
48    };
49
50}
51
52AntiSquish::AntiSquish() : _usePivot(true), _usePosition(false)
53{
54    _asqCallback = new AntiSquishCallback(this);
55    setUpdateCallback(_asqCallback);
56}
57
58AntiSquish::AntiSquish(const osg::Vec3d& pivot) : _pivot(pivot), _usePivot(true), _usePosition(false)
59{
60    _asqCallback = new AntiSquishCallback(this);
61    setUpdateCallback(_asqCallback);
62}
63
64AntiSquish::AntiSquish(const osg::Vec3d& pivot, const osg::Vec3d& pos)
65    : _pivot(pivot), _usePivot(true), _position(pos), _usePosition(true)
66{
67    _asqCallback = new AntiSquishCallback(this);
68    setUpdateCallback(_asqCallback);
69}
70
71
72AntiSquish::AntiSquish(const AntiSquish& pat,const osg::CopyOp& copyop) :
73    MatrixTransform(pat,copyop),
74    _asqCallback(pat._asqCallback),
75    _pivot(pat._pivot),
76    _usePivot(pat._usePivot),
77    _position(pat._position),
78    _usePosition(pat._usePosition),
79    _cachedLocalToWorld(pat._cachedLocalToWorld)
80{
81}
82
83AntiSquish::~AntiSquish()
84{
85}
86
87osg::Matrix AntiSquish::computeUnSquishedMatrix(const osg::Matrix& LTW, bool& flag)
88{
89    osg::Vec3d t, s;
90    osg::Quat r, so;
91
92    if (LTW == _cachedLocalToWorld && _dirty == false)
93    {
94        flag = false;
95        return osg::Matrix::identity();
96    }
97
98    _cachedLocalToWorld = LTW;
99
100    LTW.decompose(t, r, s, so);
101
102    // Let's take an average of the scale.
103    double av = (s[0] + s[1] + s[2])/3.0;
104    s[0] = av; s[1] = av; s[2]=av;
105
106    if (av == 0)
107    {
108        flag = false;
109        return osg::Matrix::identity();
110    }
111
112    osg::Matrix unsquished;
113
114    //
115    // Final Matrix: [-Pivot][SO]^[S][SO][R][T][Pivot][LOCALTOWORLD]^[position]
116    // OR [SO]^[S][SO][R][T][LOCALTOWORLD]^
117    //
118    if (_usePivot)
119    {
120        unsquished.postMultTranslate(-_pivot);
121
122        osg::Matrix tmps, invtmps;
123        so.get(tmps);
124        if (!invtmps.invert(tmps))
125        {
126            flag = false;
127            return osg::Matrix::identity();
128        }
129
130        //SO^
131        unsquished.postMult(invtmps);
132        //S
133        unsquished.postMultScale(s);
134        //SO
135        unsquished.postMult(tmps);
136        //R
137        unsquished.postMultRotate(r);
138        //T
139        unsquished.postMultTranslate(t);
140
141        osg::Matrix invltw;
142        if (!invltw.invert(LTW))
143        {
144            flag = false;
145            return osg::Matrix::identity();
146        }
147        // LTW^
148        unsquished.postMult( invltw );
149
150        // Position
151        if (_usePosition)
152            unsquished.postMultTranslate(_position);
153        else
154            unsquished.postMultTranslate(_pivot);
155    }
156    else
157    {
158        osg::Matrix tmps, invtmps;
159        so.get(tmps);
160        if (!invtmps.invert(tmps))
161        {
162            flag = false;
163            return osg::Matrix::identity();
164        }
165        unsquished.postMult(invtmps);
166        unsquished.postMultScale(s);
167        unsquished.postMult(tmps);
168        unsquished.postMultRotate(r);
169        unsquished.postMultTranslate(t);
170        osg::Matrix invltw;
171        if (!invltw.invert(LTW))
172        {
173            flag = false;
174            return osg::Matrix::identity();
175        }
176        unsquished.postMult( invltw );
177    }
178
179    if (unsquished.isNaN())
180    {
181        flag = false;
182        return  osg::Matrix::identity();
183    }
184
185    flag = true;
186    _dirty = false;
187    return unsquished;
188}
189
190
Note: See TracBrowser for help on using the browser.