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 "SGScaleTransform.hxx"
00031
00032 SGScaleTransform::SGScaleTransform() :
00033 _center(0, 0, 0),
00034 _scaleFactor(1, 1, 1),
00035 _boundScale(1)
00036 {
00037 setReferenceFrame(RELATIVE_RF);
00038 }
00039
00040 SGScaleTransform::SGScaleTransform(const SGScaleTransform& scale,
00041 const osg::CopyOp& copyop) :
00042 osg::Transform(scale, copyop),
00043 _center(scale._center),
00044 _scaleFactor(scale._scaleFactor),
00045 _boundScale(scale._boundScale)
00046 {
00047 }
00048
00049 bool
00050 SGScaleTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,
00051 osg::NodeVisitor* nv) const
00052 {
00053 osg::Matrix transform;
00054 transform(0,0) = _scaleFactor[0];
00055 transform(1,1) = _scaleFactor[1];
00056 transform(2,2) = _scaleFactor[2];
00057 transform(3,0) = _center[0]*(1 - _scaleFactor[0]);
00058 transform(3,1) = _center[1]*(1 - _scaleFactor[1]);
00059 transform(3,2) = _center[2]*(1 - _scaleFactor[2]);
00060 if (_referenceFrame == RELATIVE_RF)
00061 matrix.preMult(transform);
00062 else
00063 matrix = transform;
00064 return true;
00065 }
00066
00067 bool
00068 SGScaleTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,
00069 osg::NodeVisitor* nv) const
00070 {
00071 if (fabs(_scaleFactor[0]) < SGLimitsd::min())
00072 return false;
00073 if (fabs(_scaleFactor[1]) < SGLimitsd::min())
00074 return false;
00075 if (fabs(_scaleFactor[2]) < SGLimitsd::min())
00076 return false;
00077 SGVec3d rScaleFactor(1/_scaleFactor[0],
00078 1/_scaleFactor[1],
00079 1/_scaleFactor[2]);
00080 osg::Matrix transform;
00081 transform(0,0) = rScaleFactor[0];
00082 transform(1,1) = rScaleFactor[1];
00083 transform(2,2) = rScaleFactor[2];
00084 transform(3,0) = _center[0]*(1 - rScaleFactor[0]);
00085 transform(3,1) = _center[1]*(1 - rScaleFactor[1]);
00086 transform(3,2) = _center[2]*(1 - rScaleFactor[2]);
00087 if (_referenceFrame == RELATIVE_RF)
00088 matrix.postMult(transform);
00089 else
00090 matrix = transform;
00091 return true;
00092 }
00093
00094 osg::BoundingSphere
00095 SGScaleTransform::computeBound() const
00096 {
00097 osg::BoundingSphere bs = osg::Group::computeBound();
00098 _boundScale = normI(_scaleFactor);
00099 bs.radius() *= _boundScale;
00100 return bs;
00101 }
00102
00103 namespace {
00104
00105 bool ScaleTransform_readLocalData(osg::Object& obj, osgDB::Input& fr)
00106 {
00107 SGScaleTransform& scale = static_cast<SGScaleTransform&>(obj);
00108 if (fr[0].matchWord("center")) {
00109 ++fr;
00110 osg::Vec3d center;
00111 if (fr.readSequence(center))
00112 fr += 3;
00113 else
00114 return false;
00115 scale.setCenter(toSG(center));
00116 }
00117 if (fr[0].matchWord("scaleFactor")) {
00118 ++fr;
00119 osg::Vec3d scaleFactor;
00120 if (fr.readSequence(scaleFactor))
00121 fr += 3;
00122 else
00123 return false;
00124 scale.setScaleFactor(toSG(scaleFactor));
00125 }
00126 return true;
00127 }
00128
00129 bool ScaleTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
00130 {
00131 const SGScaleTransform& scale = static_cast<const SGScaleTransform&>(obj);
00132 const SGVec3d& center = scale.getCenter();
00133 const SGVec3d& scaleFactor = scale.getScaleFactor();
00134 int prec = fw.precision();
00135 fw.precision(15);
00136 fw.indent() << "center ";
00137 for (int i = 0; i < 3; i++)
00138 fw << center(i) << " ";
00139 fw << std::endl;
00140 fw.precision(prec);
00141 fw.indent() << "scaleFactor ";
00142 for (int i = 0; i < 3; i++)
00143 fw << scaleFactor(i) << " ";
00144 fw << std::endl;
00145 return true;
00146 }
00147
00148 }
00149
00150 osgDB::RegisterDotOsgWrapperProxy g_ScaleTransformProxy
00151 (
00152 new SGScaleTransform,
00153 "SGScaleTransform",
00154 "Object Node Transform SGScaleTransform Group",
00155 &ScaleTransform_readLocalData,
00156 &ScaleTransform_writeLocalData
00157 );