167 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
		
		
			
		
	
	
			167 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
|  | 
 | ||
|  | /*
 | ||
|  | * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
 | ||
|  | * | ||
|  | * This software is provided 'as-is', without any express or implied | ||
|  | * warranty.  In no event will the authors be held liable for any damages | ||
|  | * arising from the use of this software. | ||
|  | * Permission is granted to anyone to use this software for any purpose, | ||
|  | * including commercial applications, and to alter it and redistribute it | ||
|  | * freely, subject to the following restrictions: | ||
|  | * 1. The origin of this software must not be misrepresented; you must not | ||
|  | * claim that you wrote the original software. If you use this software | ||
|  | * in a product, an acknowledgment in the product documentation would be | ||
|  | * appreciated but is not required. | ||
|  | * 2. Altered source versions must be plainly marked as such, and must not be | ||
|  | * misrepresented as being the original software. | ||
|  | * 3. This notice may not be removed or altered from any source distribution. | ||
|  | */ | ||
|  | 
 | ||
|  | #ifndef B2_DISTANCE_H
 | ||
|  | #define B2_DISTANCE_H
 | ||
|  | 
 | ||
|  | #include "Box2D/Common/b2Math.h"
 | ||
|  | 
 | ||
|  | class b2Shape; | ||
|  | 
 | ||
|  | /// A distance proxy is used by the GJK algorithm.
 | ||
|  | /// It encapsulates any shape.
 | ||
|  | struct b2DistanceProxy | ||
|  | { | ||
|  | 	b2DistanceProxy() : m_vertices(nullptr), m_count(0), m_radius(0.0f) {} | ||
|  | 
 | ||
|  | 	/// Initialize the proxy using the given shape. The shape
 | ||
|  | 	/// must remain in scope while the proxy is in use.
 | ||
|  | 	void Set(const b2Shape* shape, int32 index); | ||
|  | 
 | ||
|  |     /// Initialize the proxy using a vertex cloud and radius. The vertices
 | ||
|  |     /// must remain in scope while the proxy is in use.
 | ||
|  |     void Set(const b2Vec2* vertices, int32 count, float32 radius); | ||
|  | 
 | ||
|  | 	/// Get the supporting vertex index in the given direction.
 | ||
|  | 	int32 GetSupport(const b2Vec2& d) const; | ||
|  | 
 | ||
|  | 	/// Get the supporting vertex in the given direction.
 | ||
|  | 	const b2Vec2& GetSupportVertex(const b2Vec2& d) const; | ||
|  | 
 | ||
|  | 	/// Get the vertex count.
 | ||
|  | 	int32 GetVertexCount() const; | ||
|  | 
 | ||
|  | 	/// Get a vertex by index. Used by b2Distance.
 | ||
|  | 	const b2Vec2& GetVertex(int32 index) const; | ||
|  | 
 | ||
|  | 	b2Vec2 m_buffer[2]; | ||
|  | 	const b2Vec2* m_vertices; | ||
|  | 	int32 m_count; | ||
|  | 	float32 m_radius; | ||
|  | }; | ||
|  | 
 | ||
|  | /// Used to warm start b2Distance.
 | ||
|  | /// Set count to zero on first call.
 | ||
|  | struct b2SimplexCache | ||
|  | { | ||
|  | 	float32 metric;		///< length or area
 | ||
|  | 	uint16 count; | ||
|  | 	uint8 indexA[3];	///< vertices on shape A
 | ||
|  | 	uint8 indexB[3];	///< vertices on shape B
 | ||
|  | }; | ||
|  | 
 | ||
|  | /// Input for b2Distance.
 | ||
|  | /// You have to option to use the shape radii
 | ||
|  | /// in the computation. Even 
 | ||
|  | struct b2DistanceInput | ||
|  | { | ||
|  | 	b2DistanceProxy proxyA; | ||
|  | 	b2DistanceProxy proxyB; | ||
|  | 	b2Transform transformA; | ||
|  | 	b2Transform transformB; | ||
|  | 	bool useRadii; | ||
|  | }; | ||
|  | 
 | ||
|  | /// Output for b2Distance.
 | ||
|  | struct b2DistanceOutput | ||
|  | { | ||
|  | 	b2Vec2 pointA;		///< closest point on shapeA
 | ||
|  | 	b2Vec2 pointB;		///< closest point on shapeB
 | ||
|  | 	float32 distance; | ||
|  | 	int32 iterations;	///< number of GJK iterations used
 | ||
|  | }; | ||
|  | 
 | ||
|  | /// Compute the closest points between two shapes. Supports any combination of:
 | ||
|  | /// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.
 | ||
|  | /// On the first call set b2SimplexCache.count to zero.
 | ||
|  | void b2Distance(b2DistanceOutput* output, | ||
|  | 				b2SimplexCache* cache,  | ||
|  | 				const b2DistanceInput* input); | ||
|  | 
 | ||
|  | /// Input parameters for b2ShapeCast
 | ||
|  | struct b2ShapeCastInput | ||
|  | { | ||
|  | 	b2DistanceProxy proxyA; | ||
|  | 	b2DistanceProxy proxyB; | ||
|  | 	b2Transform transformA; | ||
|  | 	b2Transform transformB; | ||
|  | 	b2Vec2 translationB; | ||
|  | }; | ||
|  | 
 | ||
|  | /// Output results for b2ShapeCast
 | ||
|  | struct b2ShapeCastOutput | ||
|  | { | ||
|  | 	b2Vec2 point; | ||
|  | 	b2Vec2 normal; | ||
|  | 	float32 lambda; | ||
|  | 	int32 iterations; | ||
|  | }; | ||
|  | 
 | ||
|  | /// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
 | ||
|  | bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input); | ||
|  | 
 | ||
|  | //////////////////////////////////////////////////////////////////////////
 | ||
|  | 
 | ||
|  | inline int32 b2DistanceProxy::GetVertexCount() const | ||
|  | { | ||
|  | 	return m_count; | ||
|  | } | ||
|  | 
 | ||
|  | inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const | ||
|  | { | ||
|  | 	b2Assert(0 <= index && index < m_count); | ||
|  | 	return m_vertices[index]; | ||
|  | } | ||
|  | 
 | ||
|  | inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const | ||
|  | { | ||
|  | 	int32 bestIndex = 0; | ||
|  | 	float32 bestValue = b2Dot(m_vertices[0], d); | ||
|  | 	for (int32 i = 1; i < m_count; ++i) | ||
|  | 	{ | ||
|  | 		float32 value = b2Dot(m_vertices[i], d); | ||
|  | 		if (value > bestValue) | ||
|  | 		{ | ||
|  | 			bestIndex = i; | ||
|  | 			bestValue = value; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return bestIndex; | ||
|  | } | ||
|  | 
 | ||
|  | inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const | ||
|  | { | ||
|  | 	int32 bestIndex = 0; | ||
|  | 	float32 bestValue = b2Dot(m_vertices[0], d); | ||
|  | 	for (int32 i = 1; i < m_count; ++i) | ||
|  | 	{ | ||
|  | 		float32 value = b2Dot(m_vertices[i], d); | ||
|  | 		if (value > bestValue) | ||
|  | 		{ | ||
|  | 			bestIndex = i; | ||
|  | 			bestValue = value; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return m_vertices[bestIndex]; | ||
|  | } | ||
|  | 
 | ||
|  | #endif
 |