00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef BVHMotionTransform_hxx
00019 #define BVHMotionTransform_hxx
00020
00021 #include "BVHVisitor.hxx"
00022 #include "BVHNode.hxx"
00023 #include "BVHGroup.hxx"
00024
00025 namespace simgear {
00026
00027 class BVHMotionTransform : public BVHGroup {
00028 public:
00029 BVHMotionTransform();
00030 virtual ~BVHMotionTransform();
00031
00032 virtual void accept(BVHVisitor& visitor);
00033
00034 void setTransform(const BVHMotionTransform& transform);
00035 void setToWorldTransform(const SGMatrixd& transform);
00036 void setToLocalTransform(const SGMatrixd& transform);
00037
00038 void setLinearVelocity(const SGVec3d& linearVelocity)
00039 { _linearVelocity = linearVelocity; }
00040 const SGVec3d& getLinearVelocity() const
00041 { return _linearVelocity; }
00042
00043 void setAngularVelocity(const SGVec3d& angularVelocity)
00044 { _angularVelocity = angularVelocity; }
00045 const SGVec3d& getAngularVelocity() const
00046 { return _angularVelocity; }
00047
00048 void setReferenceTime(const double& referenceTime)
00049 { _referenceTime = referenceTime; }
00050 const double& getReferenceTime() const
00051 { return _referenceTime; }
00052
00053 void setStartTime(const double& startTime)
00054 { _startTime = startTime; }
00055 const double& getStartTime() const
00056 { return _startTime; }
00057
00058 void setEndTime(const double& endTime)
00059 { _endTime = endTime; }
00060 const double& getEndTime() const
00061 { return _endTime; }
00062
00063 SGMatrixd getToWorldTransform(const double& t) const
00064 {
00065 if (t == _referenceTime)
00066 return _toWorldReference;
00067 double dt = t - _referenceTime;
00068 SGMatrixd matrix(_toWorldReference);
00069 matrix.postMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity));
00070 matrix.postMultTranslate(dt*_linearVelocity);
00071 return matrix;
00072 }
00073 SGMatrixd getToLocalTransform(const double& t) const
00074 {
00075 if (t == _referenceTime)
00076 return _toLocalReference;
00077 double dt = _referenceTime - t;
00078 SGMatrixd matrix(_toLocalReference);
00079 matrix.preMultRotate(SGQuatd::fromAngleAxis(dt*_angularVelocity));
00080 matrix.preMultTranslate(dt*_linearVelocity);
00081 return matrix;
00082 }
00083
00084 const SGMatrixd& getToWorldReferenceTransform() const
00085 { return _toWorldReference; }
00086 const SGMatrixd& getToLocalReferenceTransform() const
00087 { return _toLocalReference; }
00088
00089 SGVec3d getLinearVelocityAt(const SGVec3d& reference) const
00090 { return _linearVelocity + cross(_angularVelocity, reference); }
00091
00092 SGSphered sphereToLocal(const SGSphered& sphere, const double& t) const
00093 {
00094 SGMatrixd matrix = getToLocalTransform(t);
00095 SGVec3d center = matrix.xformPt(sphere.getCenter());
00096 double radius = _toLocalAmplification*sphere.getRadius();
00097 return SGSphered(center, radius);
00098 }
00099
00100 void setId(Id id)
00101 { _id = id; }
00102 Id getId() const
00103 { return _id; }
00104
00105 private:
00106 virtual SGSphered computeBoundingSphere() const;
00107 void updateAmplificationFactors();
00108
00109 SGMatrixd _toWorldReference;
00110 SGMatrixd _toLocalReference;
00111 double _toWorldAmplification;
00112 double _toLocalAmplification;
00113
00114 SGVec3d _linearVelocity;
00115 SGVec3d _angularVelocity;
00116
00117 double _referenceTime;
00118 double _startTime;
00119 double _endTime;
00120
00121 Id _id;
00122 };
00123
00124 }
00125
00126 #endif