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