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