![]() |
Box2D
2.2.1
A 2D Physics Engine for Games
|
00001 /* 00002 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org 00003 * 00004 * This software is provided 'as-is', without any express or implied 00005 * warranty. In no event will the authors be held liable for any damages 00006 * arising from the use of this software. 00007 * Permission is granted to anyone to use this software for any purpose, 00008 * including commercial applications, and to alter it and redistribute it 00009 * freely, subject to the following restrictions: 00010 * 1. The origin of this software must not be misrepresented; you must not 00011 * claim that you wrote the original software. If you use this software 00012 * in a product, an acknowledgment in the product documentation would be 00013 * appreciated but is not required. 00014 * 2. Altered source versions must be plainly marked as such, and must not be 00015 * misrepresented as being the original software. 00016 * 3. This notice may not be removed or altered from any source distribution. 00017 */ 00018 00019 #ifndef B2_COLLISION_H 00020 #define B2_COLLISION_H 00021 00022 #include <Box2D/Common/b2Math.h> 00023 #include <climits> 00024 00028 00029 class b2Shape; 00030 class b2CircleShape; 00031 class b2EdgeShape; 00032 class b2PolygonShape; 00033 00034 const uint8 b2_nullFeature = UCHAR_MAX; 00035 00038 struct b2ContactFeature 00039 { 00040 enum Type 00041 { 00042 e_vertex = 0, 00043 e_face = 1 00044 }; 00045 00046 uint8 indexA; 00047 uint8 indexB; 00048 uint8 typeA; 00049 uint8 typeB; 00050 }; 00051 00053 union b2ContactID 00054 { 00055 b2ContactFeature cf; 00056 uint32 key; 00057 }; 00058 00069 struct b2ManifoldPoint 00070 { 00071 b2Vec2 localPoint; 00072 float32 normalImpulse; 00073 float32 tangentImpulse; 00074 b2ContactID id; 00075 }; 00076 00093 struct b2Manifold 00094 { 00095 enum Type 00096 { 00097 e_circles, 00098 e_faceA, 00099 e_faceB 00100 }; 00101 00102 b2ManifoldPoint points[b2_maxManifoldPoints]; 00103 b2Vec2 localNormal; 00104 b2Vec2 localPoint; 00105 Type type; 00106 int32 pointCount; 00107 }; 00108 00110 struct b2WorldManifold 00111 { 00116 void Initialize(const b2Manifold* manifold, 00117 const b2Transform& xfA, float32 radiusA, 00118 const b2Transform& xfB, float32 radiusB); 00119 00120 b2Vec2 normal; 00121 b2Vec2 points[b2_maxManifoldPoints]; 00122 }; 00123 00125 enum b2PointState 00126 { 00127 b2_nullState, 00128 b2_addState, 00129 b2_persistState, 00130 b2_removeState 00131 }; 00132 00135 void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints], 00136 const b2Manifold* manifold1, const b2Manifold* manifold2); 00137 00139 struct b2ClipVertex 00140 { 00141 b2Vec2 v; 00142 b2ContactID id; 00143 }; 00144 00146 struct b2RayCastInput 00147 { 00148 b2Vec2 p1, p2; 00149 float32 maxFraction; 00150 }; 00151 00154 struct b2RayCastOutput 00155 { 00156 b2Vec2 normal; 00157 float32 fraction; 00158 }; 00159 00161 struct b2AABB 00162 { 00164 bool IsValid() const; 00165 00167 b2Vec2 GetCenter() const 00168 { 00169 return 0.5f * (lowerBound + upperBound); 00170 } 00171 00173 b2Vec2 GetExtents() const 00174 { 00175 return 0.5f * (upperBound - lowerBound); 00176 } 00177 00179 float32 GetPerimeter() const 00180 { 00181 float32 wx = upperBound.x - lowerBound.x; 00182 float32 wy = upperBound.y - lowerBound.y; 00183 return 2.0f * (wx + wy); 00184 } 00185 00187 void Combine(const b2AABB& aabb) 00188 { 00189 lowerBound = b2Min(lowerBound, aabb.lowerBound); 00190 upperBound = b2Max(upperBound, aabb.upperBound); 00191 } 00192 00194 void Combine(const b2AABB& aabb1, const b2AABB& aabb2) 00195 { 00196 lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound); 00197 upperBound = b2Max(aabb1.upperBound, aabb2.upperBound); 00198 } 00199 00201 bool Contains(const b2AABB& aabb) const 00202 { 00203 bool result = true; 00204 result = result && lowerBound.x <= aabb.lowerBound.x; 00205 result = result && lowerBound.y <= aabb.lowerBound.y; 00206 result = result && aabb.upperBound.x <= upperBound.x; 00207 result = result && aabb.upperBound.y <= upperBound.y; 00208 return result; 00209 } 00210 00211 bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const; 00212 00213 b2Vec2 lowerBound; 00214 b2Vec2 upperBound; 00215 }; 00216 00218 void b2CollideCircles(b2Manifold* manifold, 00219 const b2CircleShape* circleA, const b2Transform& xfA, 00220 const b2CircleShape* circleB, const b2Transform& xfB); 00221 00223 void b2CollidePolygonAndCircle(b2Manifold* manifold, 00224 const b2PolygonShape* polygonA, const b2Transform& xfA, 00225 const b2CircleShape* circleB, const b2Transform& xfB); 00226 00228 void b2CollidePolygons(b2Manifold* manifold, 00229 const b2PolygonShape* polygonA, const b2Transform& xfA, 00230 const b2PolygonShape* polygonB, const b2Transform& xfB); 00231 00233 void b2CollideEdgeAndCircle(b2Manifold* manifold, 00234 const b2EdgeShape* polygonA, const b2Transform& xfA, 00235 const b2CircleShape* circleB, const b2Transform& xfB); 00236 00238 void b2CollideEdgeAndPolygon(b2Manifold* manifold, 00239 const b2EdgeShape* edgeA, const b2Transform& xfA, 00240 const b2PolygonShape* circleB, const b2Transform& xfB); 00241 00243 int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], 00244 const b2Vec2& normal, float32 offset, int32 vertexIndexA); 00245 00247 bool b2TestOverlap( const b2Shape* shapeA, int32 indexA, 00248 const b2Shape* shapeB, int32 indexB, 00249 const b2Transform& xfA, const b2Transform& xfB); 00250 00251 // ---------------- Inline Functions ------------------------------------------ 00252 00253 inline bool b2AABB::IsValid() const 00254 { 00255 b2Vec2 d = upperBound - lowerBound; 00256 bool valid = d.x >= 0.0f && d.y >= 0.0f; 00257 valid = valid && lowerBound.IsValid() && upperBound.IsValid(); 00258 return valid; 00259 } 00260 00261 inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b) 00262 { 00263 b2Vec2 d1, d2; 00264 d1 = b.lowerBound - a.upperBound; 00265 d2 = a.lowerBound - b.upperBound; 00266 00267 if (d1.x > 0.0f || d1.y > 0.0f) 00268 return false; 00269 00270 if (d2.x > 0.0f || d2.y > 0.0f) 00271 return false; 00272 00273 return true; 00274 } 00275 00276 #endif