00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_MATH_COLLISIONLIB_H__
00009 #define __SP_MATH_COLLISIONLIB_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spMath.hpp"
00014 #include "Base/spDimensionPolygon.hpp"
00015
00016
00017 namespace sp
00018 {
00019 namespace scene
00020 {
00021 class ViewFrustum;
00022 }
00023 namespace math
00024 {
00025
00026
00028 namespace CollisionLibrary
00029 {
00030
00037 SP_EXPORT dim::vector3df getClosestPoint(const dim::triangle3df &Triangle, const dim::vector3df &Point);
00038
00045 SP_EXPORT bool getClosestPointStraight(
00046 const dim::triangle3df &Triangle, const dim::vector3df &Point, dim::vector3df &PointOnTriangle
00047 );
00048
00055 SP_EXPORT dim::vector3df getClosestPoint(const dim::aabbox3df &Box, const dim::vector3df &Point);
00056
00061 SP_EXPORT dim::vector3df getClosestPoint(
00062 const dim::aabbox3df &Box, const dim::vector3df &Point, dim::vector3df &Normal
00063 );
00064
00071 SP_EXPORT dim::vector3df getClosestPoint(const dim::obbox3df &Box, const dim::vector3df &Point);
00072
00079 SP_EXPORT dim::line3df getClosestLine(const dim::triangle3df &Triangle, const dim::line3df &Line);
00080
00088 SP_EXPORT bool getClosestLineStraight(const dim::triangle3df &Triangle, const dim::line3df &Line, dim::line3df &LineToTriangle);
00089
00097 SP_EXPORT dim::line3df getClosestLine(const dim::quadrangle3df &Quadrangle, const dim::line3df &Line);
00098
00105 SP_EXPORT dim::line3df getClosestLine(const dim::aabbox3df &Box, const dim::line3df &Line);
00106
00108 SP_EXPORT f32 getPointBoxDistanceSq(const dim::obbox3df &Box, const dim::vector3df &Point);
00109
00111 inline f32 getPointBoxDistance(const dim::obbox3df &Box, const dim::vector3df &Point)
00112 {
00113 return sqrt(getPointBoxDistanceSq(Box, Point));
00114 }
00115
00120 SP_EXPORT f32 getLineBoxDistanceSq(const dim::aabbox3df &Box, const dim::line3df &Line);
00121
00123 inline f32 getLineBoxDistance(const dim::aabbox3df &Box, const dim::line3df &Line)
00124 {
00125 return sqrt(getLineBoxDistanceSq(Box, Line));
00126 }
00127
00137 SP_EXPORT f32 getLineLineDistanceSq(
00138 const dim::line3df &LineA, const dim::line3df &LineB, dim::vector3df &PointP, dim::vector3df &PointQ
00139 );
00140
00142 inline f32 getLineLineDistance(
00143 const dim::line3df &LineA, const dim::line3df &LineB, dim::vector3df &PointP, dim::vector3df &PointQ)
00144 {
00145 return sqrt(getLineLineDistanceSq(LineA, LineB, PointP, PointQ));
00146 }
00147
00155 SP_EXPORT bool getLineLineIntersection(
00156 const dim::line3df &LineA, const dim::line3df &LineB, dim::vector3df &Intersection
00157 );
00158
00167 SP_EXPORT dim::point2df get2DLineLineIntersectionStraight(
00168 const dim::point2df &A, const dim::point2df &B, const dim::point2df &C, const dim::point2df &D
00169 );
00170
00171
00172
00180 SP_EXPORT bool checkLineTriangleIntersection(
00181 const dim::triangle3df &Triangle, const dim::line3df &Line, dim::vector3df &Intersection
00182 );
00183
00193 SP_EXPORT bool checkLineSphereIntersection(
00194 const dim::line3df &Line, const dim::vector3df &SpherePosition, const f32 SphereRadius, dim::vector3df &Intersection, bool MakeRayTest = false
00195 );
00196
00207 SP_EXPORT bool checkLineBoxIntersection(
00208 const dim::line3df &Line, const dim::aabbox3df &Box, dim::vector3df &Intersection, bool MakeRayTest = false
00209 );
00210
00218 SP_EXPORT bool checkTriangleTriangleIntersection(
00219 const dim::triangle3df &TriangleA, const dim::triangle3df &TriangleB, dim::line3df &Intersection
00220 );
00221
00222
00223
00225 SP_EXPORT bool checkLineBoxOverlap(
00226 const dim::line3df &Line, const dim::aabbox3df &Box
00227 );
00228
00230 SP_EXPORT bool checkPlaneBoxOverlap(
00231 const dim::plane3df &Plane, const dim::aabbox3df &Box
00232 );
00233
00235 SP_EXPORT bool checkTriangleBoxOverlap(
00236 const dim::triangle3df &Triangle, const dim::aabbox3df &Box
00237 );
00238
00245 SP_EXPORT bool checkOBBoxOBBoxOverlap(
00246 const dim::obbox3df &BoxA, const dim::obbox3df &BoxB
00247 );
00248
00253 bool checkPyramidPyramidOverlap(
00254 const dim::vector3df &OriginA, const scene::ViewFrustum &FrustumA,
00255 const dim::vector3df &OriginB, const scene::ViewFrustum &FrustumB
00256 );
00257
00258
00259
00260 template <typename T, typename C> bool getLinePlaneIntersection(
00261 const dim::plane3d<T> &Plane, const C &LineStart, const C &LineEnd, C &Intersection)
00262 {
00263 C Direction(LineEnd);
00264 Direction -= LineStart;
00265
00266 const T t = (Plane.Distance - Plane.Normal.dot(LineStart.getCoord())) / Plane.Normal.dot(Direction.getCoord());
00267
00268 if (t >= T(0) && t <= T(1))
00269 {
00270
00271 Intersection = Direction;
00272 Intersection *= t;
00273 Intersection += LineStart;
00274 return true;
00275 }
00276
00277 return false;
00278 }
00279
00292 template <typename T, typename C> bool clipPolygon(
00293 const dim::polygon<C> &Poly, const dim::plane3d<T> &Plane, dim::polygon<C> &FrontPoly, dim::polygon<C> &BackPoly)
00294 {
00295 if (Poly.getCount() < 3)
00296 {
00297 #ifdef SP_DEBUGMODE
00298 io::Log::debug("CollisionLibrary::clipPolygon", "Polygon has not enough points to be cliped");
00299 #endif
00300 return false;
00301 }
00302
00303
00304 const u32 PointCount = Poly.getCount();
00305 C a = Poly.Points.back();
00306
00307 dim::EPlanePointRelations aSide = Plane.getPointRelation(a.getCoord());
00308
00309
00310 for (u32 i = 0; i < PointCount; ++i)
00311 {
00312 C b = Poly[i];
00313
00314 dim::EPlanePointRelations bSide = Plane.getPointRelation(b.getCoord());
00315
00316 if (bSide == dim::POINT_INFRONTOF_PLANE)
00317 {
00318 if (aSide == dim::POINT_BEHIND_PLANE)
00319 {
00320
00321 C Intersection;
00322 getLinePlaneIntersection(Plane, a, b, Intersection);
00323
00324
00325
00326
00327 FrontPoly.push(Intersection);
00328 BackPoly.push(Intersection);
00329 }
00330
00331
00332 FrontPoly.push(b);
00333 }
00334 else if (bSide == dim::POINT_BEHIND_PLANE)
00335 {
00336 if (aSide == dim::POINT_INFRONTOF_PLANE)
00337 {
00338
00339 C Intersection;
00340 getLinePlaneIntersection(Plane, a, b, Intersection);
00341
00342
00343
00344
00345 FrontPoly.push(Intersection);
00346 BackPoly.push(Intersection);
00347 }
00348 else if (aSide == dim::POINT_ON_PLANE)
00349 {
00350
00351 BackPoly.push(a);
00352 }
00353
00354
00355 BackPoly.push(b);
00356 }
00357 else
00358 {
00359
00360 FrontPoly.push(b);
00361
00362
00363 if (aSide == dim::POINT_BEHIND_PLANE)
00364 BackPoly.push(b);
00365 }
00366
00367
00368 a = b;
00369 aSide = bSide;
00370 }
00371
00372 return true;
00373 }
00374
00375 }
00376
00377
00378 }
00379
00380 }
00381
00382
00383 #endif
00384
00385
00386
00387