3 * Copyright (C) 2006-2007 Mathias Froehlich
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.
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.
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,
23 # include <simgear_config.h>
26 #include <osgDB/Registry>
27 #include <osgDB/Input>
28 #include <osgDB/Output>
30 #include <simgear/scene/util/OsgMath.hxx>
32 #include "SGScaleTransform.hxx"
34 SGScaleTransform::SGScaleTransform() :
36 _scaleFactor(1, 1, 1),
39 setReferenceFrame(RELATIVE_RF);
40 // see osg::Transform doc: If the transformation matrix scales the subgraph
41 // then the normals of the underlying geometry will need to be renormalized
42 // to be unit vectors once more.
43 osg::StateSet* stateset = getOrCreateStateSet();
44 stateset->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
47 SGScaleTransform::SGScaleTransform(const SGScaleTransform& scale,
48 const osg::CopyOp& copyop) :
49 osg::Transform(scale, copyop),
50 _center(scale._center),
51 _scaleFactor(scale._scaleFactor),
52 _boundScale(scale._boundScale)
57 SGScaleTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
58 osg::NodeVisitor* nv) const
60 osg::Matrix transform;
61 transform(0,0) = _scaleFactor[0];
62 transform(1,1) = _scaleFactor[1];
63 transform(2,2) = _scaleFactor[2];
64 transform(3,0) = _center[0]*(1 - _scaleFactor[0]);
65 transform(3,1) = _center[1]*(1 - _scaleFactor[1]);
66 transform(3,2) = _center[2]*(1 - _scaleFactor[2]);
67 if (_referenceFrame == RELATIVE_RF)
68 matrix.preMult(transform);
75 SGScaleTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
76 osg::NodeVisitor* nv) const
78 if (fabs(_scaleFactor[0]) < SGLimitsd::min())
80 if (fabs(_scaleFactor[1]) < SGLimitsd::min())
82 if (fabs(_scaleFactor[2]) < SGLimitsd::min())
84 SGVec3d rScaleFactor(1/_scaleFactor[0],
87 osg::Matrix transform;
88 transform(0,0) = rScaleFactor[0];
89 transform(1,1) = rScaleFactor[1];
90 transform(2,2) = rScaleFactor[2];
91 transform(3,0) = _center[0]*(1 - rScaleFactor[0]);
92 transform(3,1) = _center[1]*(1 - rScaleFactor[1]);
93 transform(3,2) = _center[2]*(1 - rScaleFactor[2]);
94 if (_referenceFrame == RELATIVE_RF)
95 matrix.postMult(transform);
102 SGScaleTransform::computeBound() const
104 osg::BoundingSphere bs = osg::Group::computeBound();
105 _boundScale = normI(_scaleFactor);
106 bs.radius() *= _boundScale;
112 bool ScaleTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
114 SGScaleTransform& scale = static_cast<SGScaleTransform&>(obj);
115 if (fr[0].matchWord("center")) {
118 if (fr.readSequence(center))
122 scale.setCenter(toSG(center));
124 if (fr[0].matchWord("scaleFactor")) {
126 osg::Vec3d scaleFactor;
127 if (fr.readSequence(scaleFactor))
131 scale.setScaleFactor(toSG(scaleFactor));
136 bool ScaleTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
138 const SGScaleTransform& scale = static_cast<const SGScaleTransform&>(obj);
139 const SGVec3d& center = scale.getCenter();
140 const SGVec3d& scaleFactor = scale.getScaleFactor();
141 int prec = fw.precision();
143 fw.indent() << "center ";
144 for (int i = 0; i < 3; i++)
145 fw << center(i) << " ";
148 fw.indent() << "scaleFactor ";
149 for (int i = 0; i < 3; i++)
150 fw << scaleFactor(i) << " ";
157 osgDB::RegisterDotOsgWrapperProxy g_ScaleTransformProxy
159 new SGScaleTransform,
161 "Object Node Transform SGScaleTransform Group",
162 &ScaleTransform_readLocalData,
163 &ScaleTransform_writeLocalData