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 "SGRotateTransform.hxx"
35 set_rotation (osg::Matrix &matrix, double position_rad,
36 const SGVec3d ¢er, const SGVec3d &axis)
38 double temp_angle = -position_rad;
40 double s = sin(temp_angle);
41 double c = cos(temp_angle);
44 // axis was normalized at load time
45 // hint to the compiler to put these into FP registers
50 matrix(0, 0) = t * x * x + c ;
51 matrix(0, 1) = t * y * x - s * z ;
52 matrix(0, 2) = t * z * x + s * y ;
55 matrix(1, 0) = t * x * y + s * z ;
56 matrix(1, 1) = t * y * y + c ;
57 matrix(1, 2) = t * z * y - s * x ;
60 matrix(2, 0) = t * x * z - s * y ;
61 matrix(2, 1) = t * y * z + s * x ;
62 matrix(2, 2) = t * z * z + c ;
65 // hint to the compiler to put these into FP registers
70 matrix(3, 0) = x - x*matrix(0, 0) - y*matrix(1, 0) - z*matrix(2, 0);
71 matrix(3, 1) = y - x*matrix(0, 1) - y*matrix(1, 1) - z*matrix(2, 1);
72 matrix(3, 2) = z - x*matrix(0, 2) - y*matrix(1, 2) - z*matrix(2, 2);
76 SGRotateTransform::SGRotateTransform() :
81 setReferenceFrame(RELATIVE_RF);
84 SGRotateTransform::SGRotateTransform(const SGRotateTransform& rot,
85 const osg::CopyOp& copyop) :
86 osg::Transform(rot, copyop),
89 _angleRad(rot._angleRad)
94 SGRotateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
95 osg::NodeVisitor* nv) const
97 // This is the fast path, optimize a bit
98 if (_referenceFrame == RELATIVE_RF) {
101 set_rotation(tmp, _angleRad, _center, _axis);
105 set_rotation(tmp, _angleRad, _center, _axis);
112 SGRotateTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
113 osg::NodeVisitor* nv) const
115 if (_referenceFrame == RELATIVE_RF) {
118 set_rotation(tmp, -_angleRad, _center, _axis);
119 matrix.postMult(tmp);
123 set_rotation(tmp, -_angleRad, _center, _axis);
130 SGRotateTransform::computeBound() const
132 osg::BoundingSphere bs = osg::Group::computeBound();
133 osg::BoundingSphere centerbs(toOsg(_center), bs.radius());
134 centerbs.expandBy(bs);
138 // Functions to read/write SGRotateTransform from/to a .osg file.
142 bool RotateTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
144 SGRotateTransform& rot = static_cast<SGRotateTransform&>(obj);
145 if (fr[0].matchWord("center")) {
148 if (fr.readSequence(center))
152 rot.setCenter(toSG(center));
154 if (fr[0].matchWord("axis")) {
157 if (fr.readSequence(axis))
161 rot.setCenter(toSG(axis));
163 if (fr[0].matchWord("angle")) {
166 if (fr[0].getFloat(angle))
170 rot.setAngleRad(angle);
175 bool RotateTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
177 const SGRotateTransform& rot = static_cast<const SGRotateTransform&>(obj);
178 const SGVec3d& center = rot.getCenter();
179 const SGVec3d& axis = rot.getAxis();
180 const double angle = rot.getAngleRad();
181 int prec = fw.precision();
183 fw.indent() << "center ";
184 for (int i = 0; i < 3; i++) {
185 fw << center(i) << " ";
189 fw.indent() << "axis ";
190 for (int i = 0; i < 3; i++) {
191 fw << axis(i) << " ";
194 fw.indent() << "angle ";
195 fw << angle << std::endl;
200 osgDB::RegisterDotOsgWrapperProxy g_SGRotateTransformProxy
202 new SGRotateTransform,
204 "Object Node Transform SGRotateTransform Group",
205 &RotateTransform_readLocalData,
206 &RotateTransform_writeLocalData