From 418856769bfcad86253f177e3f8a90454d1535b2 Mon Sep 17 00:00:00 2001 From: timoore Date: Sun, 22 Jul 2007 20:06:20 +0000 Subject: [PATCH] Support for reading and writing nodes in .osg files, plus some new accessors. --- simgear/scene/model/SGOffsetTransform.cxx | 48 +++++++++ simgear/scene/model/SGOffsetTransform.hxx | 16 ++- simgear/scene/model/SGRotateTransform.cxx | 83 ++++++++++++++ simgear/scene/model/SGRotateTransform.hxx | 4 + simgear/scene/model/SGScaleTransform.cxx | 69 ++++++++++++ simgear/scene/model/SGScaleTransform.hxx | 4 + simgear/scene/model/SGTranslateTransform.cxx | 66 ++++++++++++ simgear/scene/model/SGTranslateTransform.hxx | 4 + simgear/scene/model/placementtrans.cxx | 108 +++++++++++++++++++ simgear/scene/model/placementtrans.hxx | 14 ++- 10 files changed, 412 insertions(+), 4 deletions(-) diff --git a/simgear/scene/model/SGOffsetTransform.cxx b/simgear/scene/model/SGOffsetTransform.cxx index b59aebd8..7a3df3cf 100644 --- a/simgear/scene/model/SGOffsetTransform.cxx +++ b/simgear/scene/model/SGOffsetTransform.cxx @@ -23,6 +23,10 @@ # include #endif +#include +#include +#include + #include "SGOffsetTransform.hxx" SGOffsetTransform::SGOffsetTransform(double scaleFactor) : @@ -31,6 +35,14 @@ SGOffsetTransform::SGOffsetTransform(double scaleFactor) : { } +SGOffsetTransform::SGOffsetTransform(const SGOffsetTransform& offset, + const osg::CopyOp& copyop) : + osg::Transform(offset, copyop), + _scaleFactor(offset._scaleFactor), + _rScaleFactor(offset._rScaleFactor) +{ +} + bool SGOffsetTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const @@ -66,3 +78,39 @@ SGOffsetTransform::computeWorldToLocalMatrix(osg::Matrix& matrix, } return true; } + +namespace { + +bool OffsetTransform_readLocalData(osg::Object& obj, osgDB::Input& fr) +{ + SGOffsetTransform& offset = static_cast(obj); + if (fr[0].matchWord("scaleFactor")) { + ++fr; + double scaleFactor; + if (fr[0].getFloat(scaleFactor)) + ++fr; + else + return false; + offset.setScaleFactor(scaleFactor); + } + return true; +} + +bool OffsetTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw) +{ + const SGOffsetTransform& offset + = static_cast(obj); + fw.indent() << "scaleFactor " << offset.getScaleFactor() << std::endl; + return true; +} + +} + +osgDB::RegisterDotOsgWrapperProxy g_SGOffsetTransformProxy +( + new SGOffsetTransform, + "SGOffsetTransform", + "Object Node Transform SGOffsetTransform Group", + &OffsetTransform_readLocalData, + &OffsetTransform_writeLocalData +); diff --git a/simgear/scene/model/SGOffsetTransform.hxx b/simgear/scene/model/SGOffsetTransform.hxx index 5edddadb..641f90bd 100644 --- a/simgear/scene/model/SGOffsetTransform.hxx +++ b/simgear/scene/model/SGOffsetTransform.hxx @@ -26,11 +26,25 @@ class SGOffsetTransform : public osg::Transform { public: - SGOffsetTransform(double scaleFactor); + SGOffsetTransform(double scaleFactor = 1.0); + SGOffsetTransform(const SGOffsetTransform&, + const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + + META_Node(simgear, SGOffsetTransform); + + double getScaleFactor() const { return _scaleFactor; }; + + void setScaleFactor(double scaleFactor) + { + _scaleFactor = scaleFactor; + _rScaleFactor = 1.0 / scaleFactor; + } + virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const; virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const; + private: double _scaleFactor; double _rScaleFactor; diff --git a/simgear/scene/model/SGRotateTransform.cxx b/simgear/scene/model/SGRotateTransform.cxx index 84fb15d0..4f18fe61 100644 --- a/simgear/scene/model/SGRotateTransform.cxx +++ b/simgear/scene/model/SGRotateTransform.cxx @@ -23,6 +23,10 @@ # include #endif +#include +#include +#include + #include "SGRotateTransform.hxx" static void @@ -75,6 +79,15 @@ SGRotateTransform::SGRotateTransform() : setReferenceFrame(RELATIVE_RF); } +SGRotateTransform::SGRotateTransform(const SGRotateTransform& rot, + const osg::CopyOp& copyop) : + osg::Transform(rot, copyop), + _center(rot._center), + _axis(rot._axis), + _angleRad(rot._angleRad) +{ +} + bool SGRotateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const @@ -120,3 +133,73 @@ SGRotateTransform::computeBound() const return centerbs; } +// Functions to read/write SGRotateTransform from/to a .osg file. + +namespace { + +bool RotateTransform_readLocalData(osg::Object& obj, osgDB::Input& fr) +{ + SGRotateTransform& rot = static_cast(obj); + if (fr[0].matchWord("center")) { + ++fr; + SGVec3d center; + if (fr.readSequence(center.osg())) + fr += 3; + else + return false; + rot.setCenter(center); + } + if (fr[0].matchWord("axis")) { + ++fr; + SGVec3d axis; + if (fr.readSequence(axis.osg())) + fr += 3; + else + return false; + rot.setCenter(axis); + } + if (fr[0].matchWord("angle")) { + ++fr; + double angle; + if (fr[0].getFloat(angle)) + ++fr; + else + return false; + rot.setAngleRad(angle); + } + return true; +} + +bool RotateTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw) +{ + const SGRotateTransform& rot = static_cast(obj); + const SGVec3d& center = rot.getCenter(); + const SGVec3d& axis = rot.getAxis(); + const double angle = rot.getAngleRad(); + int prec = fw.precision(); + fw.precision(15); + fw.indent() << "center "; + for (int i = 0; i < 3; i++) { + fw << center(i) << " "; + } + fw << std::endl; + fw.precision(prec); + fw.indent() << "axis "; + for (int i = 0; i < 3; i++) { + fw << axis(i) << " "; + } + fw << std::endl; + fw.indent() << "angle "; + fw << angle << std::endl; + return true; +} +} + +osgDB::RegisterDotOsgWrapperProxy g_SGRotateTransformProxy +( + new SGRotateTransform, + "SGRotateTransform", + "Object Node Transform SGRotateTransform Group", + &RotateTransform_readLocalData, + &RotateTransform_writeLocalData +); diff --git a/simgear/scene/model/SGRotateTransform.hxx b/simgear/scene/model/SGRotateTransform.hxx index 22611ed4..2cf1d375 100644 --- a/simgear/scene/model/SGRotateTransform.hxx +++ b/simgear/scene/model/SGRotateTransform.hxx @@ -28,7 +28,11 @@ class SGRotateTransform : public osg::Transform { public: SGRotateTransform(); + SGRotateTransform(const SGRotateTransform&, + const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + META_Node(simgear, SGRotateTransform); + void setCenter(const SGVec3f& center) { setCenter(toVec3d(center)); } void setCenter(const SGVec3d& center) diff --git a/simgear/scene/model/SGScaleTransform.cxx b/simgear/scene/model/SGScaleTransform.cxx index f8d4ca31..6a4a581e 100644 --- a/simgear/scene/model/SGScaleTransform.cxx +++ b/simgear/scene/model/SGScaleTransform.cxx @@ -44,6 +44,10 @@ # include #endif +#include +#include +#include + #include "SGScaleTransform.hxx" SGScaleTransform::SGScaleTransform() : @@ -54,6 +58,15 @@ SGScaleTransform::SGScaleTransform() : setReferenceFrame(RELATIVE_RF); } +SGScaleTransform::SGScaleTransform(const SGScaleTransform& scale, + const osg::CopyOp& copyop) : + osg::Transform(scale, copyop), + _center(scale._center), + _scaleFactor(scale._scaleFactor), + _boundScale(scale._boundScale) +{ +} + bool SGScaleTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const @@ -107,3 +120,59 @@ SGScaleTransform::computeBound() const bs.radius() *= _boundScale; return bs; } + +namespace { + +bool ScaleTransform_readLocalData(osg::Object& obj, osgDB::Input& fr) +{ + SGScaleTransform& scale = static_cast(obj); + if (fr[0].matchWord("center")) { + ++fr; + SGVec3d center; + if (fr.readSequence(center.osg())) + fr += 3; + else + return false; + scale.setCenter(center); + } + if (fr[0].matchWord("scaleFactor")) { + ++fr; + SGVec3d scaleFactor; + if (fr.readSequence(scaleFactor.osg())) + fr += 3; + else + return false; + scale.setScaleFactor(scaleFactor); + } + return true; +} + +bool ScaleTransform_writeLocalData(const osg::Object& obj, osgDB::Output& fw) +{ + const SGScaleTransform& scale = static_cast(obj); + const SGVec3d& center = scale.getCenter(); + const SGVec3d& scaleFactor = scale.getScaleFactor(); + int prec = fw.precision(); + fw.precision(15); + fw.indent() << "center "; + for (int i = 0; i < 3; i++) + fw << center(i) << " "; + fw << std::endl; + fw.precision(prec); + fw.indent() << "scaleFactor "; + for (int i = 0; i < 3; i++) + fw << scaleFactor(i) << " "; + fw << std::endl; + return true; +} + +} + +osgDB::RegisterDotOsgWrapperProxy g_ScaleTransformProxy +( + new SGScaleTransform, + "SGScaleTransform", + "Object Node Transform SGScaleTransform Group", + &ScaleTransform_readLocalData, + &ScaleTransform_writeLocalData +); diff --git a/simgear/scene/model/SGScaleTransform.hxx b/simgear/scene/model/SGScaleTransform.hxx index 03b1c8a0..3e69aed1 100644 --- a/simgear/scene/model/SGScaleTransform.hxx +++ b/simgear/scene/model/SGScaleTransform.hxx @@ -28,6 +28,10 @@ class SGScaleTransform : public osg::Transform { public: SGScaleTransform(); + SGScaleTransform(const SGScaleTransform&, + const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + + META_Node(simgear, SGScaleTransform); void setCenter(const SGVec3f& center) { setCenter(toVec3d(center)); } diff --git a/simgear/scene/model/SGTranslateTransform.cxx b/simgear/scene/model/SGTranslateTransform.cxx index c7d0f978..9f6e5d8d 100644 --- a/simgear/scene/model/SGTranslateTransform.cxx +++ b/simgear/scene/model/SGTranslateTransform.cxx @@ -23,6 +23,10 @@ # include #endif +#include +#include +#include + #include "SGTranslateTransform.hxx" static inline void @@ -42,6 +46,14 @@ SGTranslateTransform::SGTranslateTransform() : setReferenceFrame(RELATIVE_RF); } +SGTranslateTransform::SGTranslateTransform(const SGTranslateTransform& trans, + const osg::CopyOp& copyop) : + osg::Transform(trans, copyop), + _axis(trans._axis), + _value(trans._value) +{ +} + bool SGTranslateTransform::computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const @@ -81,3 +93,57 @@ SGTranslateTransform::computeBound() const bs._center += _axis.osg()*_value; return bs; } + +namespace { + +bool TranslateTransform_readLocalData(osg::Object& obj, osgDB::Input& fr) +{ + SGTranslateTransform& trans = static_cast(trans); + + if (fr[0].matchWord("axis")) { + ++fr; + SGVec3d axis; + if (fr.readSequence(axis.osg())) + fr += 3; + else + return false; + trans.setAxis(axis); + } + if (fr[0].matchWord("value")) { + ++fr; + double value; + if (fr[0].getFloat(value)) + ++fr; + else + return false; + trans.setValue(value); + } + return true; +} + +bool TranslateTransform_writeLocalData(const osg::Object& obj, + osgDB::Output& fw) +{ + const SGTranslateTransform& trans + = static_cast(obj); + const SGVec3d& axis = trans.getAxis(); + double value = trans.getValue(); + + fw.indent() << "axis "; + for (int i = 0; i < 3; i++) + fw << axis(i) << " "; + fw << std::endl; + fw.indent() << "value " << value << std::endl; + return true; +} + +} + +osgDB::RegisterDotOsgWrapperProxy g_SGTranslateTransformProxy +( + new SGTranslateTransform, + "SGTranslateTransform", + "Object Node Transform SGTranslateTransform Group", + &TranslateTransform_readLocalData, + &TranslateTransform_writeLocalData +); diff --git a/simgear/scene/model/SGTranslateTransform.hxx b/simgear/scene/model/SGTranslateTransform.hxx index e4bd8f1d..be6ac0a7 100644 --- a/simgear/scene/model/SGTranslateTransform.hxx +++ b/simgear/scene/model/SGTranslateTransform.hxx @@ -28,7 +28,11 @@ class SGTranslateTransform : public osg::Transform { public: SGTranslateTransform(); + SGTranslateTransform(const SGTranslateTransform&, + const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + META_Node(simgear, SGTranslateTransform); + void setAxis(const SGVec3d& axis) { _axis = axis; dirtyBound(); } const SGVec3d& getAxis() const diff --git a/simgear/scene/model/placementtrans.cxx b/simgear/scene/model/placementtrans.cxx index 73011b2f..dfb2f7e0 100644 --- a/simgear/scene/model/placementtrans.cxx +++ b/simgear/scene/model/placementtrans.cxx @@ -27,6 +27,10 @@ # error This library requires C++ #endif +#include +#include +#include + #include #include @@ -69,6 +73,16 @@ SGPlacementTransform::SGPlacementTransform(void) : setUpdateCallback(new UpdateCallback); } +SGPlacementTransform::SGPlacementTransform(const SGPlacementTransform& trans, + const osg::CopyOp& copyop): + osg::Transform(trans, copyop), + _placement_offset(trans._placement_offset), + _scenery_center(trans._scenery_center), + _rotation(trans._rotation) +{ + +} + SGPlacementTransform::~SGPlacementTransform(void) { } @@ -111,3 +125,97 @@ SGPlacementTransform::computeWorldToLocalMatrix(osg::Matrix& matrix, matrix = t; return true; } + +// Functions to read / write SGPlacementTrans from / to a .osg file, +// mostly for debugging purposes. + +namespace { + +bool PlacementTrans_readLocalData(osg::Object& obj, osgDB::Input& fr) +{ + SGPlacementTransform& trans = static_cast(obj); + SGMatrixd rotation(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + SGVec3d placementOffset(0, 0, 0); + SGVec3d sceneryCenter(0, 0, 0); + + if (fr[0].matchWord("rotation") && fr[1].isOpenBracket()) { + fr += 2; + for (int i = 0; i < 3; i++) { + SGVec3d scratch; + if (!fr.readSequence(scratch.osg())) + return false; + fr += 3; + for (int j = 0; j < 3; j++) + rotation(j, i) = scratch[j]; + } + if (fr[0].isCloseBracket()) + ++fr; + else + return false; + } + if (fr[0].matchWord("placement")) { + ++fr; + if (fr.readSequence(placementOffset.osg())) + fr += 3; + else + return false; + } + if (fr[0].matchWord("sceneryCenter")) { + ++fr; + if (fr.readSequence(sceneryCenter.osg())) + fr += 3; + else + return false; + } + trans.setTransform(placementOffset, rotation); + trans.setSceneryCenter(sceneryCenter); + return true; +} + +bool PlacementTrans_writeLocalData(const osg::Object& obj, osgDB::Output& fw) +{ + const SGPlacementTransform& trans + = static_cast(obj); + const SGMatrixd& rotation = trans.getRotation(); + const SGVec3d& placement = trans.getGlobalPos(); + const SGVec3d& sceneryCenter = trans.getSceneryCenter(); + + fw.indent() << "rotation {" << std::endl; + fw.moveIn(); + for (int i = 0; i < 3; i++) { + fw.indent(); + for (int j = 0; j < 3; j++) { + fw << rotation(j, i) << " "; + } + fw << std::endl; + } + fw.moveOut(); + fw.indent() << "}" << std::endl; + int prec = fw.precision(); + fw.precision(15); + fw.indent() << "placement "; + for (int i = 0; i < 3; i++) { + fw << placement(i) << " "; + } + fw << std::endl; + fw.indent() << "sceneryCenter "; + for (int i = 0; i < 3; i++) { + fw << sceneryCenter(i) << " "; + } + fw << std::endl; + fw.precision(prec); + return true; +} +} + +osgDB::RegisterDotOsgWrapperProxy g_SGPlacementTransProxy +( + new SGPlacementTransform, + "SGPlacementTransform", + "Object Node Transform SGPlacementTransform Group", + &PlacementTrans_readLocalData, + &PlacementTrans_writeLocalData +); diff --git a/simgear/scene/model/placementtrans.hxx b/simgear/scene/model/placementtrans.hxx index 93ca1080..21aded0a 100644 --- a/simgear/scene/model/placementtrans.hxx +++ b/simgear/scene/model/placementtrans.hxx @@ -38,21 +38,29 @@ class SGPlacementTransform : public osg::Transform public: SGPlacementTransform(void); - virtual ~SGPlacementTransform(void); + SGPlacementTransform(const SGPlacementTransform&, + const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); + META_Node(simgear, SGPlacementTransform); + void setTransform(const SGVec3d& off) { _placement_offset = off; dirtyBound(); } void setTransform(const SGVec3d& off, const SGMatrixd& rot) { _placement_offset = off; _rotation = rot; dirtyBound(); } void setSceneryCenter(const SGVec3d& center) { _scenery_center = center; dirtyBound(); } - + const SGVec3d& getGlobalPos() const { return _placement_offset; } - + const SGMatrixd& getRotation() const { return _rotation; } + const SGVec3d& getSceneryCenter() const { return _scenery_center; } + virtual bool computeLocalToWorldMatrix(osg::Matrix&,osg::NodeVisitor*) const; virtual bool computeWorldToLocalMatrix(osg::Matrix&,osg::NodeVisitor*) const; +protected: + virtual ~SGPlacementTransform(void); + private: class UpdateCallback; -- 2.39.5