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 "SGRotateTransform.hxx"
33 set_rotation (osg::Matrix &matrix, double position_rad,
34 const SGVec3d ¢er, const SGVec3d &axis)
36 double temp_angle = -position_rad;
38 double s = sin(temp_angle);
39 double c = cos(temp_angle);
42 // axis was normalized at load time
43 // hint to the compiler to put these into FP registers
48 matrix(0, 0) = t * x * x + c ;
49 matrix(0, 1) = t * y * x - s * z ;
50 matrix(0, 2) = t * z * x + s * y ;
53 matrix(1, 0) = t * x * y + s * z ;
54 matrix(1, 1) = t * y * y + c ;
55 matrix(1, 2) = t * z * y - s * x ;
58 matrix(2, 0) = t * x * z - s * y ;
59 matrix(2, 1) = t * y * z + s * x ;
60 matrix(2, 2) = t * z * z + c ;
63 // hint to the compiler to put these into FP registers
68 matrix(3, 0) = x - x*matrix(0, 0) - y*matrix(1, 0) - z*matrix(2, 0);
69 matrix(3, 1) = y - x*matrix(0, 1) - y*matrix(1, 1) - z*matrix(2, 1);
70 matrix(3, 2) = z - x*matrix(0, 2) - y*matrix(1, 2) - z*matrix(2, 2);
74 SGRotateTransform::SGRotateTransform() :
79 setReferenceFrame(RELATIVE_RF);
82 SGRotateTransform::SGRotateTransform(const SGRotateTransform& rot,
83 const osg::CopyOp& copyop) :
84 osg::Transform(rot, copyop),
87 _angleRad(rot._angleRad)
92 SGRotateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
93 osg::NodeVisitor* nv) const
95 // This is the fast path, optimize a bit
96 if (_referenceFrame == RELATIVE_RF) {
99 set_rotation(tmp, _angleRad, _center, _axis);
103 set_rotation(tmp, _angleRad, _center, _axis);
110 SGRotateTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
111 osg::NodeVisitor* nv) const
113 if (_referenceFrame == RELATIVE_RF) {
116 set_rotation(tmp, -_angleRad, _center, _axis);
117 matrix.postMult(tmp);
121 set_rotation(tmp, -_angleRad, _center, _axis);
128 SGRotateTransform::computeBound() const
130 osg::BoundingSphere bs = osg::Group::computeBound();
131 osg::BoundingSphere centerbs(_center.osg(), bs.radius());
132 centerbs.expandBy(bs);
136 // Functions to read/write SGRotateTransform from/to a .osg file.
140 bool RotateTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
142 SGRotateTransform& rot = static_cast<SGRotateTransform&>(obj);
143 if (fr[0].matchWord("center")) {
146 if (fr.readSequence(center))
150 rot.setCenter(SGVec3d(center));
152 if (fr[0].matchWord("axis")) {
155 if (fr.readSequence(axis))
159 rot.setCenter(SGVec3d(axis));
161 if (fr[0].matchWord("angle")) {
164 if (fr[0].getFloat(angle))
168 rot.setAngleRad(angle);
173 bool RotateTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
175 const SGRotateTransform& rot = static_cast<const SGRotateTransform&>(obj);
176 const SGVec3d& center = rot.getCenter();
177 const SGVec3d& axis = rot.getAxis();
178 const double angle = rot.getAngleRad();
179 int prec = fw.precision();
181 fw.indent() << "center ";
182 for (int i = 0; i < 3; i++) {
183 fw << center(i) << " ";
187 fw.indent() << "axis ";
188 for (int i = 0; i < 3; i++) {
189 fw << axis(i) << " ";
192 fw.indent() << "angle ";
193 fw << angle << std::endl;
198 osgDB::RegisterDotOsgWrapperProxy g_SGRotateTransformProxy
200 new SGRotateTransform,
202 "Object Node Transform SGRotateTransform Group",
203 &RotateTransform_readLocalData,
204 &RotateTransform_writeLocalData