00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #ifndef FCL_BV_H
00038 #define FCL_BV_H
00039
00040
00041 #include "fcl/BV/kDOP.h"
00042 #include "fcl/BV/AABB.h"
00043 #include "fcl/BV/OBB.h"
00044 #include "fcl/BV/RSS.h"
00045 #include "fcl/BV/OBBRSS.h"
00046 #include "fcl/BV/kIOS.h"
00047 #include "fcl/math/transform.h"
00048
00050 namespace fcl
00051 {
00052
00054 namespace details
00055 {
00056
00058 template<typename BV1, typename BV2>
00059 class Converter
00060 {
00061 private:
00062 static void convert(const BV1& bv1, const Transform3f& tf1, BV2& bv2)
00063 {
00064
00065 }
00066 };
00067
00068
00070 template<>
00071 class Converter<AABB, AABB>
00072 {
00073 public:
00074 static void convert(const AABB& bv1, const Transform3f& tf1, AABB& bv2)
00075 {
00076 const Vec3f& center = bv1.center();
00077 FCL_REAL r = (bv1.max_ - bv1.min_).length() * 0.5;
00078 Vec3f center2 = tf1.transform(center);
00079 Vec3f delta(r, r, r);
00080 bv2.min_ = center2 - delta;
00081 bv2.max_ = center2 + delta;
00082 }
00083 };
00084
00085 template<>
00086 class Converter<AABB, OBB>
00087 {
00088 public:
00089 static void convert(const AABB& bv1, const Transform3f& tf1, OBB& bv2)
00090 {
00091
00092
00093
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 bv2.To = tf1.transform(bv1.center());
00128 bv2.extent = (bv1.max_ - bv1.min_) * 0.5;
00129 const Matrix3f& R = tf1.getRotation();
00130 bv2.axis[0] = R.getColumn(0);
00131 bv2.axis[1] = R.getColumn(1);
00132 bv2.axis[2] = R.getColumn(2);
00133 }
00134 };
00135
00136 template<>
00137 class Converter<OBB, OBB>
00138 {
00139 public:
00140 static void convert(const OBB& bv1, const Transform3f& tf1, OBB& bv2)
00141 {
00142 bv2.extent = bv1.extent;
00143 bv2.To = tf1.transform(bv1.To);
00144 bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]);
00145 bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]);
00146 bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]);
00147 }
00148 };
00149
00150 template<>
00151 class Converter<OBBRSS, OBB>
00152 {
00153 public:
00154 static void convert(const OBBRSS& bv1, const Transform3f& tf1, OBB& bv2)
00155 {
00156 Converter<OBB, OBB>::convert(bv1.obb, tf1, bv2);
00157 }
00158 };
00159
00160 template<>
00161 class Converter<RSS, OBB>
00162 {
00163 public:
00164 static void convert(const RSS& bv1, const Transform3f& tf1, OBB& bv2)
00165 {
00166 bv2.extent = Vec3f(bv1.l[0] * 0.5 + bv1.r, bv1.l[1] * 0.5 + bv1.r, bv1.r);
00167 bv2.To = tf1.transform(bv1.Tr);
00168 bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]);
00169 bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]);
00170 bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]);
00171 }
00172 };
00173
00174
00175 template<typename BV1>
00176 class Converter<BV1, AABB>
00177 {
00178 public:
00179 static void convert(const BV1& bv1, const Transform3f& tf1, AABB& bv2)
00180 {
00181 const Vec3f& center = bv1.center();
00182 FCL_REAL r = Vec3f(bv1.width(), bv1.height(), bv1.depth()).length() * 0.5;
00183 Vec3f delta(r, r, r);
00184 Vec3f center2 = tf1.transform(center);
00185 bv2.min_ = center2 - delta;
00186 bv2.max_ = center2 + delta;
00187 }
00188 };
00189
00190 template<typename BV1>
00191 class Converter<BV1, OBB>
00192 {
00193 public:
00194 static void convert(const BV1& bv1, const Transform3f& tf1, OBB& bv2)
00195 {
00196 AABB bv;
00197 Converter<BV1, AABB>::convert(bv1, Transform3f(), bv);
00198 Converter<AABB, OBB>::convert(bv, tf1, bv2);
00199 }
00200 };
00201
00202 template<>
00203 class Converter<OBB, RSS>
00204 {
00205 public:
00206 static void convert(const OBB& bv1, const Transform3f& tf1, RSS& bv2)
00207 {
00208 bv2.Tr = tf1.transform(bv1.To);
00209 bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]);
00210 bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]);
00211 bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]);
00212
00213 bv2.r = bv1.extent[2];
00214 bv2.l[0] = 2 * (bv1.extent[0] - bv2.r);
00215 bv2.l[1] = 2 * (bv1.extent[1] - bv2.r);
00216 }
00217 };
00218
00219 template<>
00220 class Converter<RSS, RSS>
00221 {
00222 public:
00223 static void convert(const RSS& bv1, const Transform3f& tf1, RSS& bv2)
00224 {
00225 bv2.Tr = tf1.transform(bv1.Tr);
00226 bv2.axis[0] = tf1.getQuatRotation().transform(bv1.axis[0]);
00227 bv2.axis[1] = tf1.getQuatRotation().transform(bv1.axis[1]);
00228 bv2.axis[2] = tf1.getQuatRotation().transform(bv1.axis[2]);
00229
00230 bv2.r = bv1.r;
00231 bv2.l[0] = bv1.l[0];
00232 bv2.l[1] = bv1.l[1];
00233 }
00234 };
00235
00236 template<>
00237 class Converter<OBBRSS, RSS>
00238 {
00239 public:
00240 static void convert(const OBBRSS& bv1, const Transform3f& tf1, RSS& bv2)
00241 {
00242 Converter<RSS, RSS>::convert(bv1.rss, tf1, bv2);
00243 }
00244 };
00245
00246 template<>
00247 class Converter<AABB, RSS>
00248 {
00249 public:
00250 static void convert(const AABB& bv1, const Transform3f& tf1, RSS& bv2)
00251 {
00252 bv2.Tr = tf1.transform(bv1.center());
00253
00255 FCL_REAL d[3] = {bv1.width(), bv1.height(), bv1.depth() };
00256 std::size_t id[3] = {0, 1, 2};
00257
00258 for(std::size_t i = 1; i < 3; ++i)
00259 {
00260 for(std::size_t j = i; j > 0; --j)
00261 {
00262 if(d[j] > d[j-1])
00263 {
00264 {
00265 FCL_REAL tmp = d[j];
00266 d[j] = d[j-1];
00267 d[j-1] = tmp;
00268 }
00269 {
00270 std::size_t tmp = id[j];
00271 id[j] = id[j-1];
00272 id[j-1] = tmp;
00273 }
00274 }
00275 }
00276 }
00277
00278 Vec3f extent = (bv1.max_ - bv1.min_) * 0.5;
00279 bv2.r = extent[id[2]];
00280 bv2.l[0] = (extent[id[0]] - bv2.r) * 2;
00281 bv2.l[1] = (extent[id[1]] - bv2.r) * 2;
00282
00283 const Matrix3f& R = tf1.getRotation();
00284 bool left_hand = (id[0] == (id[1] + 1) % 3);
00285 bv2.axis[0] = left_hand ? -R.getColumn(id[0]) : R.getColumn(id[0]);
00286 bv2.axis[1] = R.getColumn(id[1]);
00287 bv2.axis[2] = R.getColumn(id[2]);
00288 }
00289 };
00290
00291 }
00292
00294
00295
00297 template<typename BV1, typename BV2>
00298 static inline void convertBV(const BV1& bv1, const Transform3f& tf1, BV2& bv2)
00299 {
00300 details::Converter<BV1, BV2>::convert(bv1, tf1, bv2);
00301 }
00302
00303 }
00304
00305 #endif