00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "BVHMotionTransform.hxx"
00019
00020 #include "BVHVisitor.hxx"
00021 #include "BVHNode.hxx"
00022 #include "BVHGroup.hxx"
00023
00024 namespace simgear {
00025
00026 BVHMotionTransform::BVHMotionTransform() :
00027 _toWorldReference(SGMatrixd::unit()),
00028 _toLocalReference(SGMatrixd::unit()),
00029 _toWorldAmplification(1),
00030 _toLocalAmplification(1),
00031 _linearVelocity(0, 0, 0),
00032 _angularVelocity(0, 0, 0),
00033 _referenceTime(0),
00034 _startTime(0),
00035 _endTime(0),
00036 _id(0)
00037 {
00038 }
00039
00040 BVHMotionTransform::~BVHMotionTransform()
00041 {
00042 }
00043
00044 void
00045 BVHMotionTransform::accept(BVHVisitor& visitor)
00046 {
00047 visitor.apply(*this);
00048 }
00049
00050 void
00051 BVHMotionTransform::setTransform(const BVHMotionTransform& transform)
00052 {
00053 _toWorldReference = transform._toWorldReference;
00054 _toLocalReference = transform._toLocalReference;
00055 _toWorldAmplification = transform._toWorldAmplification;
00056 _toLocalAmplification = transform._toLocalAmplification;
00057 _linearVelocity = transform._linearVelocity;
00058 _angularVelocity = transform._angularVelocity;
00059 _referenceTime = transform._referenceTime;
00060 _startTime = transform._startTime;
00061 _endTime = transform._endTime;
00062 _id = transform._id;
00063 invalidateParentBound();
00064 }
00065
00066 void
00067 BVHMotionTransform::setToWorldTransform(const SGMatrixd& transform)
00068 {
00069 _toWorldReference = transform;
00070 invert(_toLocalReference, transform);
00071 updateAmplificationFactors();
00072 invalidateParentBound();
00073 }
00074
00075 void
00076 BVHMotionTransform::setToLocalTransform(const SGMatrixd& transform)
00077 {
00078 _toLocalReference = transform;
00079 invert(_toWorldReference, transform);
00080 updateAmplificationFactors();
00081 invalidateParentBound();
00082 }
00083
00084 SGSphered
00085 BVHMotionTransform::computeBoundingSphere() const
00086 {
00087 SGSphered sphere(BVHGroup::computeBoundingSphere());
00088 if (sphere.empty())
00089 return sphere;
00090 SGMatrixd toWorldStart = getToWorldTransform(_startTime);
00091 SGVec3d centerStart = toWorldStart.xformPt(sphere.getCenter());
00092 SGMatrixd toWorldEnd = getToWorldTransform(_endTime);
00093 SGVec3d centerEnd = toWorldEnd.xformPt(sphere.getCenter());
00094 double rad = 0.5*length(centerStart - centerEnd) + sphere.getRadius();
00095 rad *= _toWorldAmplification;
00096 return SGSphered(0.5*(centerStart + centerEnd), rad);
00097 }
00098
00099 void
00100 BVHMotionTransform::updateAmplificationFactors()
00101 {
00102
00103
00104
00105 double r = norm(_toWorldReference.xformVec(SGVec3d(1, 0, 0)));
00106 r = std::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 1, 0))));
00107 r = std::max(r, norm(_toWorldReference.xformVec(SGVec3d(0, 0, 1))));
00108 _toWorldAmplification = r;
00109
00110 r = norm(_toLocalReference.xformVec(SGVec3d(1, 0, 0)));
00111 r = std::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 1, 0))));
00112 r = std::max(r, norm(_toLocalReference.xformVec(SGVec3d(0, 0, 1))));
00113 _toLocalAmplification = r;
00114 }
00115
00116 }