]> git.mxchange.org Git - simgear.git/blob - simgear/scene/model/SGScaleTransform.cxx
Provide something more sensible for the properties root
[simgear.git] / simgear / scene / model / SGScaleTransform.cxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich 
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include <simgear_config.h>
24 #endif
25
26 #include <osgDB/Registry>
27 #include <osgDB/Input>
28 #include <osgDB/Output>
29
30 #include "SGScaleTransform.hxx"
31
32 SGScaleTransform::SGScaleTransform() :
33   _center(0, 0, 0),
34   _scaleFactor(1, 1, 1),
35   _boundScale(1)
36 {
37   setReferenceFrame(RELATIVE_RF);
38 }
39
40 SGScaleTransform::SGScaleTransform(const SGScaleTransform& scale,
41                                    const osg::CopyOp& copyop) :
42     osg::Transform(scale, copyop),
43     _center(scale._center),
44     _scaleFactor(scale._scaleFactor),
45     _boundScale(scale._boundScale)
46 {
47 }
48
49 bool
50 SGScaleTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
51                                             osg::NodeVisitor* nv) const
52 {
53   osg::Matrix transform;
54   transform(0,0) = _scaleFactor[0];
55   transform(1,1) = _scaleFactor[1];
56   transform(2,2) = _scaleFactor[2];
57   transform(3,0) = _center[0]*(1 - _scaleFactor[0]);
58   transform(3,1) = _center[1]*(1 - _scaleFactor[1]);
59   transform(3,2) = _center[2]*(1 - _scaleFactor[2]);
60   if (_referenceFrame == RELATIVE_RF)
61     matrix.preMult(transform);
62   else
63     matrix = transform;
64   return true;
65 }
66
67 bool
68 SGScaleTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
69                                             osg::NodeVisitor* nv) const
70 {
71   if (fabs(_scaleFactor[0]) < SGLimitsd::min())
72     return false;
73   if (fabs(_scaleFactor[1]) < SGLimitsd::min())
74     return false;
75   if (fabs(_scaleFactor[2]) < SGLimitsd::min())
76     return false;
77   SGVec3d rScaleFactor(1/_scaleFactor[0],
78                        1/_scaleFactor[1],
79                        1/_scaleFactor[2]);
80   osg::Matrix transform;
81   transform(0,0) = rScaleFactor[0];
82   transform(1,1) = rScaleFactor[1];
83   transform(2,2) = rScaleFactor[2];
84   transform(3,0) = _center[0]*(1 - rScaleFactor[0]);
85   transform(3,1) = _center[1]*(1 - rScaleFactor[1]);
86   transform(3,2) = _center[2]*(1 - rScaleFactor[2]);
87   if (_referenceFrame == RELATIVE_RF)
88     matrix.postMult(transform);
89   else
90     matrix = transform;
91   return true;
92 }
93
94 osg::BoundingSphere
95 SGScaleTransform::computeBound() const
96 {
97   osg::BoundingSphere bs = osg::Group::computeBound();
98   _boundScale = normI(_scaleFactor);
99   bs.radius() *= _boundScale;
100   return bs;
101 }
102
103 namespace {
104
105 bool ScaleTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
106 {
107     SGScaleTransform& scale = static_cast<SGScaleTransform&>(obj);
108     if (fr[0].matchWord("center")) {
109         ++fr;
110         SGVec3d center;
111         if (fr.readSequence(center.osg()))
112             fr += 3;
113         else
114             return false;
115         scale.setCenter(center);
116     }
117     if (fr[0].matchWord("scaleFactor")) {
118         ++fr;
119         SGVec3d scaleFactor;
120         if (fr.readSequence(scaleFactor.osg()))
121             fr += 3;
122         else
123             return false;
124         scale.setScaleFactor(scaleFactor);
125     }
126     return true;
127 }
128
129 bool ScaleTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
130 {
131     const SGScaleTransform& scale = static_cast<const SGScaleTransform&>(obj);
132     const SGVec3d& center = scale.getCenter();
133     const SGVec3d& scaleFactor = scale.getScaleFactor();
134     int prec = fw.precision();
135     fw.precision(15);
136     fw.indent() << "center ";
137     for (int i = 0; i < 3; i++)
138         fw << center(i) << " ";
139     fw << std::endl;
140     fw.precision(prec);
141     fw.indent() << "scaleFactor ";
142     for (int i = 0; i < 3; i++)
143         fw << scaleFactor(i) << " ";
144     fw << std::endl;
145     return true;
146 }
147
148 }
149
150 osgDB::RegisterDotOsgWrapperProxy g_ScaleTransformProxy
151 (
152     new SGScaleTransform,
153     "SGScaleTransform",
154     "Object Node Transform SGScaleTransform Group",
155     &ScaleTransform_readLocalData,
156     &ScaleTransform_writeLocalData
157 );