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