File indexing completed on 2024-05-19 14:56:21
0001 0002 /* 0003 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org 0004 * 0005 * This software is provided 'as-is', without any express or implied 0006 * warranty. In no event will the authors be held liable for any damages 0007 * arising from the use of this software. 0008 * Permission is granted to anyone to use this software for any purpose, 0009 * including commercial applications, and to alter it and redistribute it 0010 * freely, subject to the following restrictions: 0011 * 1. The origin of this software must not be misrepresented; you must not 0012 * claim that you wrote the original software. If you use this software 0013 * in a product, an acknowledgment in the product documentation would be 0014 * appreciated but is not required. 0015 * 2. Altered source versions must be plainly marked as such, and must not be 0016 * misrepresented as being the original software. 0017 * 3. This notice may not be removed or altered from any source distribution. 0018 */ 0019 0020 #ifndef B2_DISTANCE_H 0021 #define B2_DISTANCE_H 0022 0023 #include <Box2D/Common/b2Math.h> 0024 0025 class b2Shape; 0026 0027 /// A distance proxy is used by the GJK algorithm. 0028 /// It encapsulates any shape. 0029 struct b2DistanceProxy 0030 { 0031 b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {} 0032 0033 /// Initialize the proxy using the given shape. The shape 0034 /// must remain in scope while the proxy is in use. 0035 void Set(const b2Shape* shape, int32 index); 0036 0037 /// Get the supporting vertex index in the given direction. 0038 int32 GetSupport(const b2Vec2& d) const; 0039 0040 /// Get the supporting vertex in the given direction. 0041 const b2Vec2& GetSupportVertex(const b2Vec2& d) const; 0042 0043 /// Get the vertex count. 0044 int32 GetVertexCount() const; 0045 0046 /// Get a vertex by index. Used by b2Distance. 0047 const b2Vec2& GetVertex(int32 index) const; 0048 0049 b2Vec2 m_buffer[2]; 0050 const b2Vec2* m_vertices; 0051 int32 m_count; 0052 float32 m_radius; 0053 }; 0054 0055 /// Used to warm start b2Distance. 0056 /// Set count to zero on first call. 0057 struct b2SimplexCache 0058 { 0059 float32 metric; ///< length or area 0060 uint16 count; 0061 uint8 indexA[3]; ///< vertices on shape A 0062 uint8 indexB[3]; ///< vertices on shape B 0063 }; 0064 0065 /// Input for b2Distance. 0066 /// You have to option to use the shape radii 0067 /// in the computation. Even 0068 struct b2DistanceInput 0069 { 0070 b2DistanceProxy proxyA; 0071 b2DistanceProxy proxyB; 0072 b2Transform transformA; 0073 b2Transform transformB; 0074 bool useRadii; 0075 }; 0076 0077 /// Output for b2Distance. 0078 struct b2DistanceOutput 0079 { 0080 b2Vec2 pointA; ///< closest point on shapeA 0081 b2Vec2 pointB; ///< closest point on shapeB 0082 float32 distance; 0083 int32 iterations; ///< number of GJK iterations used 0084 }; 0085 0086 /// Compute the closest points between two shapes. Supports any combination of: 0087 /// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output. 0088 /// On the first call set b2SimplexCache.count to zero. 0089 void b2Distance(b2DistanceOutput* output, 0090 b2SimplexCache* cache, 0091 const b2DistanceInput* input); 0092 0093 0094 ////////////////////////////////////////////////////////////////////////// 0095 0096 inline int32 b2DistanceProxy::GetVertexCount() const 0097 { 0098 return m_count; 0099 } 0100 0101 inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const 0102 { 0103 b2Assert(0 <= index && index < m_count); 0104 return m_vertices[index]; 0105 } 0106 0107 inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const 0108 { 0109 int32 bestIndex = 0; 0110 float32 bestValue = b2Dot(m_vertices[0], d); 0111 for (int32 i = 1; i < m_count; ++i) 0112 { 0113 float32 value = b2Dot(m_vertices[i], d); 0114 if (value > bestValue) 0115 { 0116 bestIndex = i; 0117 bestValue = value; 0118 } 0119 } 0120 0121 return bestIndex; 0122 } 0123 0124 inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const 0125 { 0126 int32 bestIndex = 0; 0127 float32 bestValue = b2Dot(m_vertices[0], d); 0128 for (int32 i = 1; i < m_count; ++i) 0129 { 0130 float32 value = b2Dot(m_vertices[i], d); 0131 if (value > bestValue) 0132 { 0133 bestIndex = i; 0134 bestValue = value; 0135 } 0136 } 0137 0138 return m_vertices[bestIndex]; 0139 } 0140 0141 #endif