00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 # include <simgear_config.h>
00024 #endif
00025
00026 #include <osgDB/Registry>
00027 #include <osgDB/Input>
00028 #include <osgDB/Output>
00029
00030 #include "SGRotateTransform.hxx"
00031
00032 static void
00033 set_rotation (osg::Matrix &matrix, double position_rad,
00034 const SGVec3d ¢er, const SGVec3d &axis)
00035 {
00036 double temp_angle = -position_rad;
00037
00038 double s = sin(temp_angle);
00039 double c = cos(temp_angle);
00040 double t = 1 - c;
00041
00042
00043
00044 double x = axis[0];
00045 double y = axis[1];
00046 double z = axis[2];
00047
00048 matrix(0, 0) = t * x * x + c ;
00049 matrix(0, 1) = t * y * x - s * z ;
00050 matrix(0, 2) = t * z * x + s * y ;
00051 matrix(0, 3) = 0;
00052
00053 matrix(1, 0) = t * x * y + s * z ;
00054 matrix(1, 1) = t * y * y + c ;
00055 matrix(1, 2) = t * z * y - s * x ;
00056 matrix(1, 3) = 0;
00057
00058 matrix(2, 0) = t * x * z - s * y ;
00059 matrix(2, 1) = t * y * z + s * x ;
00060 matrix(2, 2) = t * z * z + c ;
00061 matrix(2, 3) = 0;
00062
00063
00064 x = center[0];
00065 y = center[1];
00066 z = center[2];
00067
00068 matrix(3, 0) = x - x*matrix(0, 0) - y*matrix(1, 0) - z*matrix(2, 0);
00069 matrix(3, 1) = y - x*matrix(0, 1) - y*matrix(1, 1) - z*matrix(2, 1);
00070 matrix(3, 2) = z - x*matrix(0, 2) - y*matrix(1, 2) - z*matrix(2, 2);
00071 matrix(3, 3) = 1;
00072 }
00073
00074 SGRotateTransform::SGRotateTransform() :
00075 _center(0, 0, 0),
00076 _axis(0, 0, 0),
00077 _angleRad(0)
00078 {
00079 setReferenceFrame(RELATIVE_RF);
00080 }
00081
00082 SGRotateTransform::SGRotateTransform(const SGRotateTransform& rot,
00083 const osg::CopyOp& copyop) :
00084 osg::Transform(rot, copyop),
00085 _center(rot._center),
00086 _axis(rot._axis),
00087 _angleRad(rot._angleRad)
00088 {
00089 }
00090
00091 bool
00092 SGRotateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
00093 osg::NodeVisitor* nv) const
00094 {
00095
00096 if (_referenceFrame == RELATIVE_RF) {
00097
00098 osg::Matrix tmp;
00099 set_rotation(tmp, _angleRad, _center, _axis);
00100 matrix.preMult(tmp);
00101 } else {
00102 osg::Matrix tmp;
00103 set_rotation(tmp, _angleRad, _center, _axis);
00104 matrix = tmp;
00105 }
00106 return true;
00107 }
00108
00109 bool
00110 SGRotateTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
00111 osg::NodeVisitor* nv) const
00112 {
00113 if (_referenceFrame == RELATIVE_RF) {
00114
00115 osg::Matrix tmp;
00116 set_rotation(tmp, -_angleRad, _center, _axis);
00117 matrix.postMult(tmp);
00118 } else {
00119
00120 osg::Matrix tmp;
00121 set_rotation(tmp, -_angleRad, _center, _axis);
00122 matrix = tmp;
00123 }
00124 return true;
00125 }
00126
00127 osg::BoundingSphere
00128 SGRotateTransform::computeBound() const
00129 {
00130 osg::BoundingSphere bs = osg::Group::computeBound();
00131 osg::BoundingSphere centerbs(toOsg(_center), bs.radius());
00132 centerbs.expandBy(bs);
00133 return centerbs;
00134 }
00135
00136
00137
00138 namespace {
00139
00140 bool RotateTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
00141 {
00142 SGRotateTransform& rot = static_cast<SGRotateTransform&>(obj);
00143 if (fr[0].matchWord("center")) {
00144 ++fr;
00145 osg::Vec3d center;
00146 if (fr.readSequence(center))
00147 fr += 3;
00148 else
00149 return false;
00150 rot.setCenter(toSG(center));
00151 }
00152 if (fr[0].matchWord("axis")) {
00153 ++fr;
00154 osg::Vec3d axis;
00155 if (fr.readSequence(axis))
00156 fr += 3;
00157 else
00158 return false;
00159 rot.setCenter(toSG(axis));
00160 }
00161 if (fr[0].matchWord("angle")) {
00162 ++fr;
00163 double angle;
00164 if (fr[0].getFloat(angle))
00165 ++fr;
00166 else
00167 return false;
00168 rot.setAngleRad(angle);
00169 }
00170 return true;
00171 }
00172
00173 bool RotateTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
00174 {
00175 const SGRotateTransform& rot = static_cast<const SGRotateTransform&>(obj);
00176 const SGVec3d& center = rot.getCenter();
00177 const SGVec3d& axis = rot.getAxis();
00178 const double angle = rot.getAngleRad();
00179 int prec = fw.precision();
00180 fw.precision(15);
00181 fw.indent() << "center ";
00182 for (int i = 0; i < 3; i++) {
00183 fw << center(i) << " ";
00184 }
00185 fw << std::endl;
00186 fw.precision(prec);
00187 fw.indent() << "axis ";
00188 for (int i = 0; i < 3; i++) {
00189 fw << axis(i) << " ";
00190 }
00191 fw << std::endl;
00192 fw.indent() << "angle ";
00193 fw << angle << std::endl;
00194 return true;
00195 }
00196 }
00197
00198 osgDB::RegisterDotOsgWrapperProxy g_SGRotateTransformProxy
00199 (
00200 new SGRotateTransform,
00201 "SGRotateTransform",
00202 "Object Node Transform SGRotateTransform Group",
00203 &RotateTransform_readLocalData,
00204 &RotateTransform_writeLocalData
00205 );