first commit
This commit is contained in:
		
							
								
								
									
										197
									
								
								include/bounce/collision/broad_phase.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								include/bounce/collision/broad_phase.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_BROAD_PHASE_H | ||||
| #define B3_BROAD_PHASE_H | ||||
|  | ||||
| #include <bounce\collision\trees\dynamic_tree.h> | ||||
| #include <algorithm> | ||||
|  | ||||
| // A pair of broad-phase proxies. | ||||
| struct b3Pair | ||||
| { | ||||
| 	i32 proxy1; | ||||
| 	i32 proxy2; | ||||
| }; | ||||
|  | ||||
| // The broad-phase collision interface.  | ||||
| // It is used to perform ray, AABB, and overlapping-pair queries  | ||||
| // against AABBs. | ||||
| class b3BroadPhase  | ||||
| { | ||||
| public: | ||||
| 	b3BroadPhase(); | ||||
| 	~b3BroadPhase(); | ||||
|  | ||||
| 	// Create a broad-phase proxy and return a proxy. | ||||
| 	i32 CreateProxy(const b3AABB3& aabb, void* userData); | ||||
| 	 | ||||
| 	// Destroy an existing proxy. | ||||
| 	void DestroyProxy(i32 proxyId); | ||||
|  | ||||
| 	// Update an existing proxy with a given AABB and a displacement. | ||||
| 	// displacement = int[a, b](dv/dt) dt = F(b) - F(a) = x(b) - x(a) ~= v * dt | ||||
| 	// Return true if the proxy has moved. | ||||
| 	bool MoveProxy(i32 proxyId, const b3AABB3& aabb, const b3Vec3& displacement); | ||||
|  | ||||
| 	// Get the AABB of a given proxy. | ||||
| 	const b3AABB3& GetAABB(i32 proxyId) const; | ||||
|  | ||||
| 	// Get the user data attached to a proxy. | ||||
| 	void* GetUserData(i32 proxyId) const; | ||||
|  | ||||
| 	// Test if two proxy AABBs are overlapping. | ||||
| 	bool TestOverlap(i32 proxy1, i32 proxy2) const; | ||||
| 	 | ||||
| 	// Notify the client callback the AABBs that are overlapping with the passed AABB. | ||||
| 	template<class T> | ||||
| 	void QueryAABB(T* callback, const b3AABB3& aabb) const; | ||||
| 	 | ||||
| 	// Notify the client callback the AABBs that are overlapping the  | ||||
| 	// passed ray. | ||||
| 	template<class T> | ||||
| 	void QueryRay(T* callback, const b3RayCastInput& input) const; | ||||
|  | ||||
| 	// Notify the client callback the AABB pairs that are overlapping. | ||||
| 	// The client must store the notified pairs. | ||||
| 	template<class T> | ||||
| 	void FindNewPairs(T* callback); | ||||
|  | ||||
| 	// Debug b3Draw the AABB proxies. | ||||
| 	void Draw(b3Draw* b3Draw) const; | ||||
| private : | ||||
| 	friend class b3DynamicTree; | ||||
| 	 | ||||
| 	// Add a proxy to the list of moved proxies. | ||||
| 	// Only moved proxies will be used as an AABB query reference object. | ||||
| 	void BufferMove(i32 proxyId); | ||||
|  | ||||
| 	// The client callback used to add a overlapping pair | ||||
| 	// to the overlapping pair buffer. | ||||
| 	bool Report(i32 proxyId); | ||||
| 	 | ||||
| 	// The dynamic tree. | ||||
| 	b3DynamicTree m_tree; | ||||
|  | ||||
| 	// The current proxy being queried for  | ||||
| 	// overlap witha another proxies. Is used to avoid a proxy overlap with itself. | ||||
| 	i32 m_queryProxyId; | ||||
|  | ||||
| 	// Keep a buffer of the objects that have moved in a step. | ||||
| 	i32* m_moveBuffer; | ||||
| 	u32 m_moveBufferCount; | ||||
| 	u32 m_moveBufferCapacity; | ||||
|  | ||||
| 	// The buffer holding the unique overlapping AABB pairs. | ||||
| 	b3Pair* m_pairBuffer; | ||||
| 	u32 m_pairBufferCapacity; | ||||
| 	u32 m_pairBufferCount; | ||||
| }; | ||||
|  | ||||
| inline const b3AABB3& b3BroadPhase::GetAABB(i32 proxyId) const  | ||||
| { | ||||
| 	return m_tree.GetAABB(proxyId); | ||||
| } | ||||
|  | ||||
| inline void* b3BroadPhase::GetUserData(i32 proxyId) const  | ||||
| { | ||||
| 	return m_tree.GetUserData(proxyId); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3BroadPhase::QueryAABB(T* callback, const b3AABB3& aabb) const  | ||||
| { | ||||
| 	return m_tree.QueryAABB(callback, aabb); | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3BroadPhase::QueryRay(T* callback, const b3RayCastInput& input) const  | ||||
| { | ||||
| 	return m_tree.QueryRay(callback, input); | ||||
| } | ||||
|  | ||||
| inline bool operator<(const b3Pair& pair1, const b3Pair& pair2)  | ||||
| { | ||||
| 	if (pair1.proxy1 < pair2.proxy1)  | ||||
| 	{ | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	if (pair1.proxy1 == pair2.proxy1)  | ||||
| 	{ | ||||
| 		return pair1.proxy2 < pair2.proxy2; | ||||
| 	} | ||||
|  | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3BroadPhase::FindNewPairs(T* callback)  | ||||
| { | ||||
| 	// Reset the overlapping pairs buffer count for the current step. | ||||
| 	m_pairBufferCount = 0; | ||||
|  | ||||
| 	// Notifying this class with QueryCallback(), gets the (duplicated) overlapping pair buffer. | ||||
| 	for (u32 i = 0; i < m_moveBufferCount; ++i)  | ||||
| 	{ | ||||
| 		// Keep the current queried proxy ID to avoid self overlapping. | ||||
| 		m_queryProxyId = m_moveBuffer[i]; | ||||
| 		if (m_queryProxyId == NULL_NODE)  | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		const b3AABB3& aabb = m_tree.GetAABB(m_queryProxyId); | ||||
| 		m_tree.QueryAABB(this, aabb); | ||||
| 	} | ||||
|  | ||||
| 	// Reset the move buffer for the next step. | ||||
| 	m_moveBufferCount = 0; | ||||
|  | ||||
| 	// Sort the (duplicated) overlapping pair buffer to prune duplicated pairs. | ||||
| 	std::sort(m_pairBuffer, m_pairBuffer + m_pairBufferCount); | ||||
|  | ||||
| 	// Skip duplicated overlapping pairs. | ||||
| 	u32 index = 0; | ||||
| 	while (index < m_pairBufferCount)  | ||||
| 	{ | ||||
| 		const b3Pair* primaryPair = m_pairBuffer + index; | ||||
|  | ||||
| 		// Report an unique overlapping pair to the client. | ||||
| 		callback->AddPair(m_tree.GetUserData(primaryPair->proxy1), m_tree.GetUserData(primaryPair->proxy2)); | ||||
|  | ||||
| 		// Skip all duplicated pairs until an unique pair is found. | ||||
| 		++index; | ||||
| 		while (index < m_pairBufferCount)  | ||||
| 		{ | ||||
| 			const b3Pair* secondaryPair = m_pairBuffer + index; | ||||
| 			if (secondaryPair->proxy1 != primaryPair->proxy1 || secondaryPair->proxy2 != primaryPair->proxy2)  | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
| 			++index; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| inline void b3BroadPhase::Draw(b3Draw* b3Draw) const | ||||
| { | ||||
| 	m_tree.Draw(b3Draw); | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										67
									
								
								include/bounce/collision/distance.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								include/bounce/collision/distance.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_COLLISION_H | ||||
| #define B3_COLLISION_H | ||||
|  | ||||
| #include <bounce\common\geometry.h> | ||||
| #include <bounce\collision\shapes\aabb3.h> | ||||
| #include <bounce\collision\shapes\capsule.h> | ||||
|  | ||||
| // Input for a ray cast query. | ||||
| struct b3RayCastInput | ||||
| { | ||||
| 	b3Vec3 p1; // first point on segment | ||||
| 	b3Vec3 p2; // second point on segment | ||||
| 	float32 maxFraction; // maximum intersection | ||||
| }; | ||||
|  | ||||
| // Output of ray cast query. | ||||
| struct b3RayCastOutput | ||||
| { | ||||
| 	float32 fraction; // time of intersection | ||||
| 	b3Vec3 normal; // surface normal of intersection | ||||
| }; | ||||
|  | ||||
| // Find the closest point for a point P to a normalized plane. | ||||
| b3Vec3 b3ClosestPointOnPlane(const b3Vec3& P, const b3Plane& plane); | ||||
|  | ||||
| // Find the closest point for a point P to a segment AB. | ||||
| b3Vec3 b3ClosestPointOnSegment(const b3Vec3& P, | ||||
| 	const b3Vec3& A, const b3Vec3& B); | ||||
|  | ||||
| // Find the closest point for a point P to a triangle ABC. | ||||
| b3Vec3 b3ClosestPointOnTriangle(const b3Vec3& P, | ||||
| 	const b3Vec3& A, const b3Vec3& B, const b3Vec3& C); | ||||
|  | ||||
| // Find the closest points of two lines. | ||||
| void b3ClosestPointsOnLines(b3Vec3* C1, b3Vec3* C2, | ||||
| 	const b3Vec3& P1, const b3Vec3& E1, | ||||
| 	const b3Vec3& P2, const b3Vec3& E2); | ||||
|  | ||||
| // Find the closest points of two normalized lines. | ||||
| void b3ClosestPointsOnNormalizedLines(b3Vec3* C1, b3Vec3* C2, | ||||
| 	const b3Vec3& P1, const b3Vec3& N1, | ||||
| 	const b3Vec3& P2, const b3Vec3& N2); | ||||
|  | ||||
| // Find the closest points of two segments P1-Q1 to a segment P2-Q2. | ||||
| void b3ClosestPointsOnSegments(b3Vec3* C1, b3Vec3* C2, | ||||
| 	const b3Vec3& P1, const b3Vec3& Q1, | ||||
| 	const b3Vec3& P2, const b3Vec3& Q2); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										74
									
								
								include/bounce/collision/gjk/gjk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								include/bounce/collision/gjk/gjk.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_GJK_H | ||||
| #define B3_GJK_H | ||||
|  | ||||
| #include <bounce\common\geometry.h> | ||||
|  | ||||
| class b3GJKProxy; | ||||
| struct b3SimplexCache; | ||||
|  | ||||
| struct b3SimplexVertex | ||||
| { | ||||
| 	b3Vec3 pointA; // support vertex on proxy A | ||||
| 	b3Vec3 pointB; // support vertex on proxy B | ||||
| 	b3Vec3 point; // minkowski vertex | ||||
| 	float32 weight; // barycentric coordinate for point | ||||
| 	u32 indexA; // support A index | ||||
| 	u32 indexB; // support B index | ||||
| }; | ||||
|  | ||||
| struct b3Simplex | ||||
| { | ||||
| 	b3SimplexVertex m_vertices[4]; | ||||
| 	u32 m_count; | ||||
|  | ||||
| 	b3Vec3 GetSearchDirection(const b3Vec3& Q) const; | ||||
| 	b3Vec3 GetClosestPoint() const; | ||||
| 	void GetClosestPoints(b3Vec3* pA, b3Vec3* pB) const; | ||||
|  | ||||
| 	void Solve2(const b3Vec3& Q); | ||||
| 	void Solve3(const b3Vec3& Q); | ||||
| 	void Solve4(const b3Vec3& Q); | ||||
|  | ||||
| 	// Cache | ||||
| 	void ReadCache(const b3SimplexCache* cache, | ||||
| 		const b3Transform& xfA, const b3GJKProxy& proxyA, | ||||
| 		const b3Transform& xfB, const b3GJKProxy& proxyB); | ||||
| 	void WriteCache(b3SimplexCache* cache) const; | ||||
| 	float32 GetMetric() const; | ||||
| }; | ||||
|  | ||||
| // The output of the GJK algorithm. | ||||
| // It contains the closest points between two proxies  | ||||
| // and their euclidean distance. | ||||
| struct b3GJKOutput  | ||||
| { | ||||
| 	b3Vec3 pointA; // closest point on proxy A | ||||
| 	b3Vec3 pointB; // closest point on proxy B | ||||
| 	float32 distance; // euclidean distance between the closest points | ||||
| 	u32 iterations; // number of GJK iterations | ||||
| }; | ||||
|  | ||||
| // Find the closest points and distance between two proxies. | ||||
| // If the distance is zero then the proxies are overlapping. | ||||
| b3GJKOutput b3GJK(const b3Transform& xfA, const b3GJKProxy& proxyA,  | ||||
| 	const b3Transform& xfB, const b3GJKProxy& proxyB); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										66
									
								
								include/bounce/collision/gjk/gjk_cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								include/bounce/collision/gjk/gjk_cache.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_GJK_CACHE_H | ||||
| #define B3_GJK_CACHE_H | ||||
|  | ||||
| #include <bounce\collision\gjk\gjk.h> | ||||
|  | ||||
| // A simplex used to improve the performance  | ||||
| // of the GJK when called more than once.  | ||||
| // Make sure to set cache.count to zero before  | ||||
| // calling the GJK for the first time. | ||||
| struct b3SimplexCache | ||||
| { | ||||
| 	float32 metric; // length or area or volume | ||||
| 	u32 iterations; // number of GJK iterations | ||||
| 	u16 count; // number of support vertices | ||||
| 	u8 indexA[4]; // support vertices on proxy A | ||||
| 	u8 indexB[4]; // support vertices on proxy B | ||||
| }; | ||||
|  | ||||
| // Find the closest points and distance between two proxies.  | ||||
| // Assumes a simplex is given for increasing the performance of  | ||||
| // the GJK when called more than once. | ||||
| b3GJKOutput b3GJK(const b3Transform& xfA, const b3GJKProxy& proxyA, | ||||
| 				  const b3Transform& xfB, const b3GJKProxy& proxyB, | ||||
| 				  bool applyRadius, b3SimplexCache* cache); | ||||
|  | ||||
| struct b3GJKFeaturePair | ||||
| { | ||||
| 	enum Type | ||||
| 	{ | ||||
| 		e_unknown = 0, | ||||
| 		e_vertex = 1, | ||||
| 		e_edge = 2, | ||||
| 		e_face = 3 | ||||
| 	}; | ||||
|  | ||||
| 	Type typeA; // number of vertices on proxy A | ||||
| 	Type typeB; // number of vertices on proxy B | ||||
| 	u32 indexA[3]; // vertices on proxy A | ||||
| 	u32 indexB[3]; // vertices on proxy B | ||||
| }; | ||||
|  | ||||
| // Get the vertices of the features that the closest points between two  | ||||
| // GJK proxies are contained on given a cached simplex. | ||||
| // The GJK must have been called using the pair of proxies and  | ||||
| // cache.count must be < 4, that is, the proxies must not be overlapping. | ||||
| b3GJKFeaturePair b3GetFeaturePair(const b3SimplexCache& cache); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										82
									
								
								include/bounce/collision/gjk/gjk_proxy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								include/bounce/collision/gjk/gjk_proxy.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_GJK_PROXY_H | ||||
| #define B3_GJK_PROXY_H | ||||
|  | ||||
| #include <bounce\common\math\vec3.h> | ||||
|  | ||||
| // A GJK proxy encapsulates any convex hull to be used by the GJK. | ||||
| class b3GJKProxy | ||||
| { | ||||
| public: | ||||
| 	b3GJKProxy() : m_vertices(nullptr), m_count(0), m_radius(0.0f) { } | ||||
|  | ||||
| 	// Get the number of vertices of this proxy. | ||||
| 	u32 GetVertexCount() const; | ||||
|  | ||||
| 	// Read an indexed vertex from this proxy. | ||||
| 	const b3Vec3& GetVertex(u32 index) const; | ||||
|  | ||||
| 	// Get the support vertex index in a given direction. | ||||
| 	u32 GetSupportIndex(const b3Vec3& d) const; | ||||
|  | ||||
| 	// Convenience function. | ||||
| 	// Get the support vertex in a given direction. | ||||
| 	const b3Vec3& GetSupportVertex(const b3Vec3& d) const; | ||||
|  | ||||
| 	b3Vec3 m_buffer[3]; // for childs | ||||
| 	const b3Vec3* m_vertices; | ||||
| 	u32 m_count; | ||||
| 	float32 m_radius; | ||||
| }; | ||||
|  | ||||
| inline u32 b3GJKProxy::GetVertexCount() const | ||||
| { | ||||
| 	return m_count; | ||||
| } | ||||
|  | ||||
| inline const b3Vec3& b3GJKProxy::GetVertex(u32 index) const | ||||
| { | ||||
| 	B3_ASSERT(0 <= index && index < m_count); | ||||
| 	return m_vertices[index]; | ||||
| } | ||||
|  | ||||
| inline u32 b3GJKProxy::GetSupportIndex(const b3Vec3& d) const | ||||
| { | ||||
| 	u32 maxIndex = 0; | ||||
| 	float32 maxProjection = b3Dot(d, m_vertices[maxIndex]); | ||||
| 	for (u32 i = 1; i < m_count; ++i) | ||||
| 	{ | ||||
| 		float32 projection = b3Dot(d, m_vertices[i]); | ||||
| 		if (projection > maxProjection) | ||||
| 		{ | ||||
| 			maxIndex = i; | ||||
| 			maxProjection = projection; | ||||
| 		} | ||||
| 	} | ||||
| 	return maxIndex; | ||||
| } | ||||
|  | ||||
| inline const b3Vec3& b3GJKProxy::GetSupportVertex(const b3Vec3& d) const | ||||
| { | ||||
| 	u32 index = GetSupportIndex(d); | ||||
| 	return m_vertices[index]; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										55
									
								
								include/bounce/collision/sat/sat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								include/bounce/collision/sat/sat.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_SAT_H | ||||
| #define B3_SAT_H | ||||
|  | ||||
| #include <bounce\common\geometry.h> | ||||
|  | ||||
| struct b3Hull; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| struct b3FaceQuery | ||||
| { | ||||
| 	u32 index; | ||||
| 	float32 separation; | ||||
| }; | ||||
|  | ||||
| float32 b3Project(const b3Hull* hull, const b3Plane& plane); | ||||
|  | ||||
| b3FaceQuery b3QueryFaceSeparation(const b3Transform& xfA, const b3Hull* hullA, | ||||
| 	const b3Transform& xfB, const b3Hull* hullB); | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| struct b3EdgeQuery | ||||
| { | ||||
| 	u32 indexA; | ||||
| 	u32 indexB; | ||||
| 	float32 separation; | ||||
| }; | ||||
|  | ||||
| bool b3IsMinkowskiFace(const b3Vec3& A, const b3Vec3& B, const b3Vec3& B_x_A, const b3Vec3& C, const b3Vec3& D, const b3Vec3& D_x_C); | ||||
|  | ||||
| float32 b3Project(const b3Vec3& P1, const b3Vec3& E1, const b3Vec3& P2, const b3Vec3& E2, const b3Vec3& C1); | ||||
|  | ||||
| b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xfA, const b3Hull* hullA, | ||||
| 	const b3Transform& xfB, const b3Hull* hullB); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										40
									
								
								include/bounce/collision/sat/sat_edge_and_hull.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								include/bounce/collision/sat/sat_edge_and_hull.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_EDGE_SAT_H | ||||
| #define B3_EDGE_SAT_H | ||||
|  | ||||
| #include <bounce\collision\sat\sat.h> | ||||
|  | ||||
| struct b3Capsule; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| float32 b3ProjectEdge(const b3Capsule* hull, const b3Plane& plane); | ||||
|  | ||||
| b3FaceQuery b3QueryFaceSeparation(const b3Transform& xfA, const b3Capsule* hullA, | ||||
| 	const b3Transform& xfB, const b3Hull* hullB); | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| float32 b3ProjectEdge(const b3Vec3& P1, const b3Vec3& E1, const b3Vec3& P2, const b3Vec3& E2, const b3Vec3& C2); | ||||
|  | ||||
| b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xfA, const b3Capsule* hullA,  | ||||
| 	const b3Transform& xfB, const b3Hull* hullB); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										33
									
								
								include/bounce/collision/sat/sat_vertex_and_hull.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								include/bounce/collision/sat/sat_vertex_and_hull.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_VERTEX_SAT_H | ||||
| #define B3_VERTEX_SAT_H | ||||
|  | ||||
| #include <bounce\collision\sat\sat.h> | ||||
|  | ||||
| struct b3Sphere; | ||||
|  | ||||
| /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| float32 b3ProjectVertex(const b3Sphere* hull, const b3Plane& plane); | ||||
|  | ||||
| b3FaceQuery b3QueryFaceSeparation(const b3Transform& xfA, const b3Sphere* hullA, | ||||
| 	const b3Transform& xfB, const b3Hull* hullB); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										239
									
								
								include/bounce/collision/shapes/aabb3.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								include/bounce/collision/shapes/aabb3.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,239 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_AABB_3_H | ||||
| #define B3_AABB_3_H | ||||
|  | ||||
| #include <bounce\common\math\transform.h> | ||||
|  | ||||
| // A min-max representation of a three-dimensional AABB. | ||||
| struct b3AABB3  | ||||
| { | ||||
| 	b3Vec3 GetSupportVertex(const b3Vec3& direction) const | ||||
| 	{ | ||||
| 		b3Vec3 support; | ||||
| 		support.x = direction.x < 0.0f ? m_lower.x : m_upper.x; | ||||
| 		support.y = direction.y < 0.0f ? m_lower.y : m_upper.y; | ||||
| 		support.z = direction.z < 0.0f ? m_lower.z : m_upper.z; | ||||
| 		return support; | ||||
| 	} | ||||
|  | ||||
| 	// Compute this AABB from a list of points. | ||||
| 	void Compute(const b3Vec3* points, u32 count) | ||||
| 	{ | ||||
| 		m_lower = m_upper = points[0]; | ||||
| 		for (u32 i = 1; i < count; ++i) | ||||
| 		{ | ||||
| 			m_lower = b3Min(m_lower, points[i]); | ||||
| 			m_upper = b3Max(m_upper, points[i]); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Compute this AABB from a list of points and a transform. | ||||
| 	void Compute(const b3Vec3* points, u32 count, const b3Transform& xf) | ||||
| 	{ | ||||
| 		m_lower = m_upper = b3Mul(xf, points[0]); | ||||
| 		for (u32 i = 1; i < count; ++i) | ||||
| 		{ | ||||
| 			b3Vec3 v = b3Mul(xf, points[i]); | ||||
| 			m_lower = b3Min(m_lower, v); | ||||
| 			m_upper = b3Max(m_upper, v); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Extend this AABB by a scalar. | ||||
| 	void Extend(float32 s)  | ||||
| 	{ | ||||
| 		b3Vec3 r(s, s, s); | ||||
| 		m_lower -= r; | ||||
| 		m_upper += r; | ||||
| 	} | ||||
| 	 | ||||
| 	// Extend this AABB by a radius vector. | ||||
| 	void Extend(const b3Vec3& r) | ||||
| 	{ | ||||
| 		m_lower -= r; | ||||
| 		m_upper += r; | ||||
| 	} | ||||
|  | ||||
| 	// Compute the centroid of this AABB. | ||||
| 	b3Vec3 Centroid() const  | ||||
| 	{ | ||||
| 		return  0.5f * (m_lower + m_upper); | ||||
| 	} | ||||
|  | ||||
| 	// Compute the width of this AABB. | ||||
| 	float32 Width() const  | ||||
| 	{ | ||||
| 		return m_upper.x - m_lower.x; | ||||
| 	} | ||||
|  | ||||
| 	// Compute the height of this AABB. | ||||
| 	float32 Height() const  | ||||
| 	{ | ||||
| 		return m_upper.y - m_lower.y; | ||||
| 	} | ||||
|  | ||||
| 	// Compute the depth of this AABB. | ||||
| 	float32 Depth() const  | ||||
| 	{ | ||||
| 		return m_upper.z - m_lower.z; | ||||
| 	} | ||||
|  | ||||
| 	// Compute the total of cubic units contained in this AABB. | ||||
| 	float32 Volume() const  | ||||
| 	{ | ||||
| 		return Width() * Height() * Depth(); | ||||
| 	} | ||||
|  | ||||
| 	// Compute the surface area of this AABB. | ||||
| 	float32 SurfaceArea() const  | ||||
| 	{ | ||||
| 		return 2.0f * (Width() * Depth() + Width() * Height() + Depth() * Height()); | ||||
| 	} | ||||
|  | ||||
| 	// Read the index of the longest axis of this AABB. | ||||
| 	u32 GetLongestAxisIndex() const | ||||
| 	{ | ||||
| 		b3Vec3 c = Centroid(); | ||||
| 		b3Vec3 r = m_upper - c; | ||||
| 		float32 max = r[0]; | ||||
| 		u32 i = 0; | ||||
| 		if (r[1] > max) | ||||
| 		{ | ||||
| 			max = r[1]; | ||||
| 			i = 1; | ||||
| 		} | ||||
| 		if (r[2] > max) | ||||
| 		{ | ||||
| 			max = r[2]; | ||||
| 			i = 2; | ||||
| 		} | ||||
| 		return i; | ||||
| 	} | ||||
|  | ||||
| 	// Test if this AABB contains a point. | ||||
| 	bool TestPoint(const b3Vec3& point) const | ||||
| 	{ | ||||
| 		return	m_lower.x <= point.x && point.x <= m_upper.x && | ||||
| 				m_lower.y <= point.y && point.y <= m_upper.y && | ||||
| 				m_lower.z <= point.z && point.z <= m_upper.z; | ||||
| 	} | ||||
|  | ||||
| 	// Test if this AABB contains another AABB. | ||||
| 	bool Contains(const b3AABB3& aabb) const | ||||
| 	{ | ||||
| 		return TestPoint(aabb.m_lower) && TestPoint(aabb.m_upper); | ||||
| 	} | ||||
|  | ||||
| 	// Test if a ray intersect this AABB. | ||||
| 	// Output the minimum fraction to derive the intersection point. | ||||
| 	bool TestRay(const b3Vec3& p1, const b3Vec3& p2, float32 maxFraction, float32& minFraction) const  | ||||
| 	{ | ||||
| 		// Solve segment to slab plane. | ||||
| 		// S = p1 + w * d | ||||
| 		// dot(S, n) = offset[i] | ||||
| 		// Solution: | ||||
| 		// dot(p1 + w * d, n) = offset[i] | ||||
| 		// dot(p1, n) + w * dot(d, n) = offset[i] | ||||
| 		// w * dot(d, n) = offset[i] - dot(p1, n) | ||||
| 		// w = (offset[i] - dot(p1, n)) / dot(d, n) | ||||
| 		b3Vec3 d = p2 - p1; | ||||
| 		float32 lower = 0.0f; | ||||
| 		float32 upper = maxFraction;		 | ||||
| 		for (u32 i = 0; i < 3; ++i)  | ||||
| 		{ | ||||
| 			float32 numerators[2], denominators[2]; | ||||
| 			//numerators[0] = (-m_lower[i]) - (-p1[i]); | ||||
| 			numerators[0] = p1[i] - m_lower[i]; | ||||
| 			numerators[1] = m_upper[i] - p1[i]; | ||||
| 			denominators[0] = -d[i]; | ||||
| 			denominators[1] = d[i]; | ||||
|  | ||||
| 			// For each orthogonal plane... | ||||
| 			for (u32 j = 0; j < 2; ++j)  | ||||
| 			{ | ||||
| 				float32 numerator = numerators[j]; | ||||
| 				float32 denominator = denominators[j]; | ||||
|  | ||||
| 				if (denominator == 0.0f)  | ||||
| 				{ | ||||
| 					// s is parallel to this half-space. | ||||
| 					if (numerator < 0.0f)  | ||||
| 					{ | ||||
| 						// s is outside of this half-space. | ||||
| 						// dot(n, p1) and dot(n, p2) < 0. | ||||
| 						return false; | ||||
| 					} | ||||
| 				} | ||||
| 				else  | ||||
| 				{ | ||||
| 					if (denominator < 0.0f)  | ||||
| 					{ | ||||
| 						// s enters this half-space. | ||||
| 						if (numerator < lower * denominator)  | ||||
| 						{ | ||||
| 							// Increase lower. | ||||
| 							lower = numerator / denominator; | ||||
| 						} | ||||
| 					} | ||||
| 					else  | ||||
| 					{ | ||||
| 						// s exits the half-space.	 | ||||
| 						if (numerator < upper * denominator)  | ||||
| 						{ | ||||
| 							// Decrease upper. | ||||
| 							upper = numerator / denominator; | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					// Exit if intersection becomes empty. | ||||
| 					if (upper < lower)  | ||||
| 					{ | ||||
| 						return false; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		B3_ASSERT(lower >= 0.0f && lower <= maxFraction); | ||||
| 		minFraction = lower; | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	b3Vec3 m_lower; // lower vertex | ||||
| 	b3Vec3 m_upper; // upper vertex | ||||
| }; | ||||
|  | ||||
| // Compute an AABB that encloses two AABBs. | ||||
| inline b3AABB3 b3Combine(const b3AABB3& a, const b3AABB3& b)  | ||||
| { | ||||
| 	b3AABB3 aabb; | ||||
| 	aabb.m_lower = b3Min(a.m_lower, b.m_lower); | ||||
| 	aabb.m_upper = b3Max(a.m_upper, b.m_upper); | ||||
| 	return aabb; | ||||
| } | ||||
|  | ||||
| // Test if two AABBs are overlapping. | ||||
| inline bool b3TestOverlap(const b3AABB3& a, const b3AABB3& b)  | ||||
| { | ||||
| 	return (a.m_lower.x <= b.m_upper.x) &&	(a.m_lower.y <= b.m_upper.y) &&	(a.m_lower.z <= b.m_upper.z) && | ||||
| 		(a.m_upper.x >= b.m_lower.x) && (a.m_upper.y >= b.m_lower.y) &&	(a.m_upper.z >= b.m_lower.z); | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										165
									
								
								include/bounce/collision/shapes/box_hull.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								include/bounce/collision/shapes/box_hull.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,165 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_BOX_HULL_H | ||||
| #define B3_BOX_HULL_H | ||||
|  | ||||
| #include <bounce\collision\shapes\hull.h> | ||||
|  | ||||
| struct b3BoxHull : public b3Hull | ||||
| { | ||||
| 	b3Vec3 boxVertices[8]; | ||||
| 	b3HalfEdge boxEdges[24]; | ||||
| 	b3Face boxFaces[6]; | ||||
| 	b3Plane boxPlanes[6]; | ||||
|  | ||||
| 	b3BoxHull() { } | ||||
|  | ||||
| 	// Set this box to the unit box. | ||||
| 	void SetIdentity() | ||||
| 	{ | ||||
| 		boxVertices[0] = b3Vec3(1.0f, 1.0f, -1.0f); | ||||
| 		boxVertices[1] = b3Vec3(-1.0f, 1.0f, -1.0f); | ||||
| 		boxVertices[2] = b3Vec3(-1.0f, -1.0f, -1.0f); | ||||
| 		boxVertices[3] = b3Vec3(1.0f, -1.0f, -1.0f); | ||||
| 		boxVertices[4] = b3Vec3(1.0f, 1.0f, 1.0f); | ||||
| 		boxVertices[5] = b3Vec3(-1.0f, 1.0f, 1.0f); | ||||
| 		boxVertices[6] = b3Vec3(-1.0f, -1.0f, 1.0f); | ||||
| 		boxVertices[7] = b3Vec3(1.0f, -1.0f, 1.0f); | ||||
|  | ||||
| 		boxEdges[0] = b3MakeEdge(1, 1, 0, 2); | ||||
| 		boxEdges[1] = b3MakeEdge(2, 0, 5, 21); | ||||
| 		boxEdges[2] = b3MakeEdge(2, 3, 0, 4); | ||||
| 		boxEdges[3] = b3MakeEdge(6, 2, 2, 18); | ||||
| 		boxEdges[4] = b3MakeEdge(6, 5, 0, 6); | ||||
| 		boxEdges[5] = b3MakeEdge(5, 4, 4, 17); | ||||
| 		boxEdges[6] = b3MakeEdge(5, 7, 0, 0); | ||||
| 		boxEdges[7] = b3MakeEdge(1, 6, 3, 22); | ||||
| 		boxEdges[8] = b3MakeEdge(4, 9, 1, 10); | ||||
| 		boxEdges[9] = b3MakeEdge(7, 8, 4, 23); | ||||
| 		boxEdges[10] = b3MakeEdge(7, 11, 1, 12); | ||||
| 		boxEdges[11] = b3MakeEdge(3, 10, 2, 16); | ||||
| 		boxEdges[12] = b3MakeEdge(3, 13, 1, 14); | ||||
| 		boxEdges[13] = b3MakeEdge(0, 12, 5, 19); | ||||
| 		boxEdges[14] = b3MakeEdge(0, 15, 1, 8); | ||||
| 		boxEdges[15] = b3MakeEdge(4, 14, 3, 20); | ||||
| 		boxEdges[16] = b3MakeEdge(7, 17, 2, 3); | ||||
| 		boxEdges[17] = b3MakeEdge(6, 16, 4, 9); | ||||
| 		boxEdges[18] = b3MakeEdge(2, 19, 2, 11); | ||||
| 		boxEdges[19] = b3MakeEdge(3, 18, 5, 1); | ||||
| 		boxEdges[20] = b3MakeEdge(0, 21, 3, 7); | ||||
| 		boxEdges[21] = b3MakeEdge(1, 20, 5, 13); | ||||
| 		boxEdges[22] = b3MakeEdge(5, 23, 3, 15); | ||||
| 		boxEdges[23] = b3MakeEdge(4, 22, 4, 5); | ||||
|  | ||||
| 		boxFaces[0].edge = 6; | ||||
| 		boxFaces[1].edge = 14; | ||||
| 		boxFaces[2].edge = 18; | ||||
| 		boxFaces[3].edge = 15; | ||||
| 		boxFaces[4].edge = 9; | ||||
| 		boxFaces[5].edge = 21; | ||||
|  | ||||
| 		boxPlanes[0] = b3Plane(b3Vec3(-1.0f, 0.0f, 0.0f), boxVertices[1]); | ||||
| 		boxPlanes[1] = b3Plane(b3Vec3(1.0f, 0.0f, 0.0f), boxVertices[0]); | ||||
| 		boxPlanes[2] = b3Plane(b3Vec3(0.0f, -1.0f, 0.0f), boxVertices[2]); | ||||
| 		boxPlanes[3] = b3Plane(b3Vec3(0.0f, 1.0f, 0.0f), boxVertices[1]); | ||||
| 		boxPlanes[4] = b3Plane(b3Vec3(0.0f, 0.0f, 1.0f), boxVertices[4]); | ||||
| 		boxPlanes[5] = b3Plane(b3Vec3(0.0f, 0.0f, -1.0f), boxVertices[0]); | ||||
|  | ||||
| 		centroid = b3Vec3(0.0f, 0.0f, 0.0f); | ||||
| 		vertices = boxVertices; | ||||
| 		vertexCount = 8; | ||||
| 		edges = boxEdges; | ||||
| 		edgeCount = 24; | ||||
| 		faces = boxFaces; | ||||
| 		planes = boxPlanes; | ||||
| 		faceCount = 6; | ||||
| 	} | ||||
|  | ||||
| 	// Set this box to the unit box and transform  | ||||
| 	// it. The transform must not contain non-uniform  | ||||
| 	// scaling! | ||||
| 	void SetTransform(const b3Transform& T) | ||||
| 	{ | ||||
| 		boxVertices[0] = b3Vec3(1.0f, 1.0f, -1.0f); | ||||
| 		boxVertices[1] = b3Vec3(-1.0f, 1.0f, -1.0f); | ||||
| 		boxVertices[2] = b3Vec3(-1.0f, -1.0f, -1.0f); | ||||
| 		boxVertices[3] = b3Vec3(1.0f, -1.0f, -1.0f); | ||||
| 		boxVertices[4] = b3Vec3(1.0f, 1.0f, 1.0f); | ||||
| 		boxVertices[5] = b3Vec3(-1.0f, 1.0f, 1.0f); | ||||
| 		boxVertices[6] = b3Vec3(-1.0f, -1.0f, 1.0f); | ||||
| 		boxVertices[7] = b3Vec3(1.0f, -1.0f, 1.0f); | ||||
|  | ||||
| 		for (u32 i = 0; i < 8; ++i) | ||||
| 		{ | ||||
| 			boxVertices[i] = T * boxVertices[i]; | ||||
| 		} | ||||
|  | ||||
| 		boxEdges[0] = b3MakeEdge(1, 1, 0, 2); | ||||
| 		boxEdges[1] = b3MakeEdge(2, 0, 5, 21); | ||||
| 		boxEdges[2] = b3MakeEdge(2, 3, 0, 4); | ||||
| 		boxEdges[3] = b3MakeEdge(6, 2, 2, 18); | ||||
| 		boxEdges[4] = b3MakeEdge(6, 5, 0, 6); | ||||
| 		boxEdges[5] = b3MakeEdge(5, 4, 4, 17); | ||||
| 		boxEdges[6] = b3MakeEdge(5, 7, 0, 0); | ||||
| 		boxEdges[7] = b3MakeEdge(1, 6, 3, 22); | ||||
| 		boxEdges[8] = b3MakeEdge(4, 9, 1, 10); | ||||
| 		boxEdges[9] = b3MakeEdge(7, 8, 4, 23); | ||||
| 		boxEdges[10] = b3MakeEdge(7, 11, 1, 12); | ||||
| 		boxEdges[11] = b3MakeEdge(3, 10, 2, 16); | ||||
| 		boxEdges[12] = b3MakeEdge(3, 13, 1, 14); | ||||
| 		boxEdges[13] = b3MakeEdge(0, 12, 5, 19); | ||||
| 		boxEdges[14] = b3MakeEdge(0, 15, 1, 8); | ||||
| 		boxEdges[15] = b3MakeEdge(4, 14, 3, 20); | ||||
| 		boxEdges[16] = b3MakeEdge(7, 17, 2, 3); | ||||
| 		boxEdges[17] = b3MakeEdge(6, 16, 4, 9); | ||||
| 		boxEdges[18] = b3MakeEdge(2, 19, 2, 11); | ||||
| 		boxEdges[19] = b3MakeEdge(3, 18, 5, 1); | ||||
| 		boxEdges[20] = b3MakeEdge(0, 21, 3, 7); | ||||
| 		boxEdges[21] = b3MakeEdge(1, 20, 5, 13); | ||||
| 		boxEdges[22] = b3MakeEdge(5, 23, 3, 15); | ||||
| 		boxEdges[23] = b3MakeEdge(4, 22, 4, 5); | ||||
|  | ||||
| 		boxFaces[0].edge = 6; | ||||
| 		boxFaces[1].edge = 14; | ||||
| 		boxFaces[2].edge = 18; | ||||
| 		boxFaces[3].edge = 15; | ||||
| 		boxFaces[4].edge = 9; | ||||
| 		boxFaces[5].edge = 21; | ||||
|  | ||||
| 		boxPlanes[0] = b3Plane(b3Vec3(-1.0f, 0.0f, 0.0f), boxVertices[1]); | ||||
| 		boxPlanes[1] = b3Plane(b3Vec3(1.0f, 0.0f, 0.0f), boxVertices[0]); | ||||
| 		boxPlanes[2] = b3Plane(b3Vec3(0.0f, -1.0f, 0.0f), boxVertices[2]); | ||||
| 		boxPlanes[3] = b3Plane(b3Vec3(0.0f, 1.0f, 0.0f), boxVertices[1]); | ||||
| 		boxPlanes[4] = b3Plane(b3Vec3(0.0f, 0.0f, 1.0f), boxVertices[4]); | ||||
| 		boxPlanes[5] = b3Plane(b3Vec3(0.0f, 0.0f, -1.0f), boxVertices[0]); | ||||
|  | ||||
| 		centroid = b3Vec3(0.0f, 0.0f, 0.0f); | ||||
| 		vertices = boxVertices; | ||||
| 		vertexCount = 8; | ||||
| 		edges = boxEdges; | ||||
| 		edgeCount = 24; | ||||
| 		faces = boxFaces; | ||||
| 		planes = boxPlanes; | ||||
| 		faceCount = 6; | ||||
|  | ||||
| 		centroid = T * centroid; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										48
									
								
								include/bounce/collision/shapes/capsule.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								include/bounce/collision/shapes/capsule.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_CAPSULE_H | ||||
| #define B3_CAPSULE_H | ||||
|  | ||||
| #include <bounce\common\math\vec3.h> | ||||
|  | ||||
| struct b3Capsule | ||||
| { | ||||
| 	b3Vec3 vertices[2]; | ||||
| 	float32 radius; | ||||
|  | ||||
| 	const b3Vec3& GetVertex(u32 index) const; | ||||
|  | ||||
| 	u32 GetSupportVertex(const b3Vec3& direction) const; | ||||
| }; | ||||
|  | ||||
| inline const b3Vec3& b3Capsule::GetVertex(u32 index) const | ||||
| { | ||||
| 	return vertices[index]; | ||||
| } | ||||
|  | ||||
| inline u32 b3Capsule::GetSupportVertex(const b3Vec3& direction) const | ||||
| { | ||||
| 	if (b3Dot(direction, vertices[0]) > b3Dot(direction, vertices[1])) | ||||
| 	{ | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										65
									
								
								include/bounce/collision/shapes/hull.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								include/bounce/collision/shapes/hull.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_HULL_H | ||||
| #define B3_HULL_H | ||||
|  | ||||
| #include <bounce\common\geometry.h> | ||||
|  | ||||
| struct b3Face | ||||
| { | ||||
| 	u8 edge; | ||||
| }; | ||||
|  | ||||
| struct b3HalfEdge | ||||
| { | ||||
| 	u8 origin; | ||||
| 	u8 twin; | ||||
| 	u8 face; | ||||
| 	u8 next; | ||||
| }; | ||||
|  | ||||
| struct b3Hull | ||||
| { | ||||
| 	b3Vec3 centroid; | ||||
| 	u32 vertexCount; | ||||
| 	b3Vec3* vertices; | ||||
| 	u32 edgeCount; | ||||
| 	b3HalfEdge* edges; | ||||
| 	u32 faceCount; | ||||
| 	b3Face* faces; | ||||
| 	b3Plane* planes; | ||||
|  | ||||
| 	const b3Vec3& GetVertex(u32 index) const; | ||||
| 	const b3HalfEdge* GetEdge(u32 index) const; | ||||
| 	const b3Face* GetFace(u32 index) const; | ||||
| 	const b3Plane& GetPlane(u32 index) const; | ||||
|  | ||||
| 	u32 GetSupportVertex(const b3Vec3& direction) const; | ||||
| 	u32 GetSupportFace(const b3Vec3& direction) const; | ||||
| 	 | ||||
| 	b3Plane GetEdgeSidePlane(u32 index) const; | ||||
| 	u32 GetSize() const; | ||||
| 	void Validate() const; | ||||
| 	void Validate(const b3Face* face) const; | ||||
| 	void Validate(const b3HalfEdge* edge) const; | ||||
| }; | ||||
|  | ||||
| #include <bounce\collision\shapes\hull.inl> | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										89
									
								
								include/bounce/collision/shapes/hull.inl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								include/bounce/collision/shapes/hull.inl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| inline b3HalfEdge b3MakeEdge(u32 origin, u32 twin, u32 face, u32 next) | ||||
| { | ||||
| 	b3HalfEdge edge; | ||||
| 	edge.origin = u8(origin); | ||||
| 	edge.twin = u8(twin); | ||||
| 	edge.face = u8(face); | ||||
| 	edge.next = u8(next); | ||||
| 	return edge; | ||||
| } | ||||
|  | ||||
| inline const b3Vec3& b3Hull::GetVertex(u32 index) const | ||||
| { | ||||
| 	return vertices[index]; | ||||
| } | ||||
|  | ||||
| inline const b3HalfEdge* b3Hull::GetEdge(u32 index) const | ||||
| { | ||||
| 	return edges + index; | ||||
| } | ||||
|  | ||||
| inline const b3Face* b3Hull::GetFace(u32 index) const | ||||
| { | ||||
| 	return faces + index; | ||||
| } | ||||
|  | ||||
| inline const b3Plane& b3Hull::GetPlane(u32 index) const | ||||
| { | ||||
| 	return planes[index]; | ||||
| } | ||||
|  | ||||
| inline u32 b3Hull::GetSupportVertex(const b3Vec3& direction) const | ||||
| { | ||||
| 	u32 maxIndex = 0; | ||||
| 	float32 maxProjection = b3Dot(direction, vertices[maxIndex]); | ||||
| 	for (u32 i = 1; i < vertexCount; ++i) | ||||
| 	{ | ||||
| 		float32 projection = b3Dot(direction, vertices[i]); | ||||
| 		if (projection > maxProjection) | ||||
| 		{ | ||||
| 			maxIndex = i; | ||||
| 			maxProjection = projection; | ||||
| 		} | ||||
| 	} | ||||
| 	return maxIndex; | ||||
| } | ||||
|  | ||||
| inline u32 b3Hull::GetSupportFace(const b3Vec3& direction) const | ||||
| { | ||||
| 	u32 maxIndex = 0; | ||||
| 	float32 maxProjection = b3Dot(direction, planes[maxIndex].normal); | ||||
| 	for (u32 i = 1; i < faceCount; ++i) | ||||
| 	{ | ||||
| 		float32 projection = b3Dot(direction, planes[i].normal); | ||||
| 		if (projection > maxProjection) | ||||
| 		{ | ||||
| 			maxIndex = i; | ||||
| 			maxProjection = projection; | ||||
| 		} | ||||
| 	} | ||||
| 	return maxIndex; | ||||
| } | ||||
|  | ||||
| inline b3Plane b3Hull::GetEdgeSidePlane(u32 index) const | ||||
| { | ||||
| 	const b3HalfEdge* edge = edges + index; | ||||
| 	const b3HalfEdge* twin = edges + edge->twin; | ||||
| 	const b3Plane* facePlane = planes + edge->face; | ||||
|  | ||||
| 	b3Vec3 P = vertices[edge->origin]; | ||||
| 	b3Vec3 Q = vertices[twin->origin]; | ||||
| 	b3Vec3 E = Q - P; | ||||
| 	b3Vec3 D = b3Cross(E, facePlane->normal); | ||||
|  | ||||
| 	b3Plane plane; | ||||
| 	plane.normal = b3Normalize(D); | ||||
| 	plane.offset = b3Dot(plane.normal, P); | ||||
| 	return plane; | ||||
| } | ||||
|  | ||||
| inline u32 b3Hull::GetSize() const | ||||
| { | ||||
| 	u32 size = 0; | ||||
| 	size += sizeof(b3Hull); | ||||
| 	size += vertexCount * sizeof(b3Vec3); | ||||
| 	size += edgeCount * sizeof(b3HalfEdge); | ||||
| 	size += faceCount * sizeof(b3Face); | ||||
| 	size += faceCount * sizeof(b3Plane); | ||||
| 	return size; | ||||
| } | ||||
							
								
								
									
										114
									
								
								include/bounce/collision/shapes/mesh.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								include/bounce/collision/shapes/mesh.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_MESH_H | ||||
| #define B3_MESH_H | ||||
|  | ||||
| #include <bounce\common\geometry.h> | ||||
| #include <bounce\collision\trees\static_tree.h> | ||||
|  | ||||
| struct b3Mesh  | ||||
| { | ||||
| 	u32 vertexCount; | ||||
| 	b3Vec3* vertices; | ||||
| 	u32 triangleCount; | ||||
| 	b3Triangle* triangles; | ||||
| 	b3StaticTree tree; | ||||
|  | ||||
| 	void BuildTree(); | ||||
| 	 | ||||
| 	const b3Vec3& GetVertex(u32 index) const; | ||||
| 	const b3Triangle& GetTriangle(u32 index) const; | ||||
| 	 | ||||
| 	void GetTriangleVertices(b3Vec3 out[3], u32 index) const; | ||||
| 	b3Plane GetTrianglePlane(u32 index) const; | ||||
| 	b3AABB3 GetTriangleAABB(u32 index) const; | ||||
| 	u32 GetSize() const; | ||||
| }; | ||||
|  | ||||
| inline void b3Mesh::BuildTree() | ||||
| { | ||||
| 	b3AABB3* aabbs = (b3AABB3*)b3Alloc(triangleCount * sizeof(b3AABB3)); | ||||
| 	u32* indices = (u32*)b3Alloc(triangleCount * sizeof(u32)); | ||||
| 	for (u32 i = 0; i < triangleCount; ++i) | ||||
| 	{ | ||||
| 		aabbs[i] = GetTriangleAABB(i); | ||||
| 		indices[i] = i; | ||||
| 	} | ||||
|  | ||||
| 	tree.Build(indices, aabbs, triangleCount); | ||||
|  | ||||
| 	b3Free(indices); | ||||
| 	b3Free(aabbs); | ||||
| } | ||||
|  | ||||
| inline const b3Vec3& b3Mesh::GetVertex(u32 index) const | ||||
| { | ||||
| 	return vertices[index]; | ||||
| } | ||||
|  | ||||
| inline const b3Triangle& b3Mesh::GetTriangle(u32 index) const | ||||
| { | ||||
| 	return triangles[index]; | ||||
| } | ||||
|  | ||||
| inline void b3Mesh::GetTriangleVertices(b3Vec3 out[3], u32 index) const | ||||
| { | ||||
| 	const b3Triangle* triangle = triangles + index; | ||||
| 	u32 i1 = triangle->v1; | ||||
| 	u32 i2 = triangle->v2; | ||||
| 	u32 i3 = triangle->v3; | ||||
| 	out[0] = vertices[i1]; | ||||
| 	out[1] = vertices[i2]; | ||||
| 	out[2] = vertices[i3]; | ||||
| } | ||||
|  | ||||
| inline b3Plane b3Mesh::GetTrianglePlane(u32 index) const | ||||
| { | ||||
| 	b3Vec3 vs[3]; | ||||
| 	GetTriangleVertices(vs, index); | ||||
| 	return b3Plane(vs[0], vs[1], vs[2]); | ||||
| } | ||||
|  | ||||
| inline b3AABB3 b3Mesh::GetTriangleAABB(u32 index) const | ||||
| { | ||||
| 	const b3Triangle* triangle = triangles + index; | ||||
| 	 | ||||
| 	u32 i1 = triangle->v1; | ||||
| 	u32 i2 = triangle->v2; | ||||
| 	u32 i3 = triangle->v3; | ||||
|  | ||||
| 	b3AABB3 aabb; | ||||
| 	aabb.m_lower = b3Min(b3Min(vertices[i1], vertices[i2]), vertices[i3]); | ||||
| 	aabb.m_upper = b3Max(b3Max(vertices[i1], vertices[i2]), vertices[i3]); | ||||
| 	 | ||||
| 	return aabb; | ||||
| } | ||||
|  | ||||
| inline u32 b3Mesh::GetSize() const | ||||
| { | ||||
| 	u32 memory = 0; | ||||
| 	memory += sizeof(b3Mesh); | ||||
| 	memory += sizeof(b3Vec3) * vertexCount; | ||||
| 	memory += sizeof(b3Triangle) * triangleCount; | ||||
| 	memory += sizeof(b3Plane) * triangleCount; | ||||
| 	memory += sizeof(b3StaticTree); | ||||
| 	return memory; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										44
									
								
								include/bounce/collision/shapes/sphere.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								include/bounce/collision/shapes/sphere.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_SPHERE_H | ||||
| #define B3_SPHERE_H | ||||
|  | ||||
| #include <bounce\common\math\vec3.h> | ||||
|  | ||||
| struct b3Sphere | ||||
| { | ||||
| 	b3Vec3 vertex; | ||||
| 	float32 radius; | ||||
| 	 | ||||
| 	const b3Vec3& GetVertex(u32 index) const; | ||||
|  | ||||
| 	u32 GetSupportVertex(const b3Vec3& direction) const; | ||||
| }; | ||||
|  | ||||
| inline const b3Vec3& b3Sphere::GetVertex(u32 index) const | ||||
| { | ||||
| 	return vertex; | ||||
| } | ||||
|  | ||||
| inline u32 b3Sphere::GetSupportVertex(const b3Vec3& direction) const | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										76
									
								
								include/bounce/collision/shapes/triangle_hull.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								include/bounce/collision/shapes/triangle_hull.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_TRIANGLE_HULL_H | ||||
| #define B3_TRIANGLE_HULL_H | ||||
|  | ||||
| #include <bounce\collision\shapes\hull.h> | ||||
|  | ||||
| struct b3TriangleHull : public b3Hull | ||||
| { | ||||
| 	b3Vec3 triangleVertices[3]; | ||||
| 	b3HalfEdge triangleEdges[6]; | ||||
| 	b3Face triangleFaces[2]; | ||||
| 	b3Plane trianglePlanes[2]; | ||||
|  | ||||
| 	b3TriangleHull() { } | ||||
|  | ||||
| 	b3TriangleHull(const b3Vec3& A, const b3Vec3& B, const b3Vec3& C) | ||||
| 	{ | ||||
| 		Set(A, B, C); | ||||
| 	} | ||||
|  | ||||
| 	void Set(const b3Vec3& A, const b3Vec3& B, const b3Vec3& C) | ||||
| 	{ | ||||
| 		const float32 kInv3 = 1.0f / 3.0f; | ||||
| 		 | ||||
| 		centroid = kInv3 * (A + B + C); | ||||
|  | ||||
| 		triangleVertices[0] = A; | ||||
| 		triangleVertices[1] = B; | ||||
| 		triangleVertices[2] = C; | ||||
|  | ||||
| 		// Each edge must be followed by its twin. | ||||
| 		triangleEdges[0] = b3MakeEdge(0, 1, 0, 2); // Face 0 - Edge 0 | ||||
| 		triangleEdges[2] = b3MakeEdge(1, 3, 0, 4); // Face 0 - Edge 1 | ||||
| 		triangleEdges[4] = b3MakeEdge(2, 5, 0, 0); // Face 0 - Edge 2 | ||||
| 		 | ||||
| 		triangleEdges[1] = b3MakeEdge(1, 0, 1, 3); // Face 1 - Edge 0 | ||||
| 		triangleEdges[3] = b3MakeEdge(2, 2, 1, 5); // Face 1 - Edge 1 | ||||
| 		triangleEdges[5] = b3MakeEdge(0, 4, 1, 1); // Face 1 - Edge 2 | ||||
| 				 | ||||
| 		triangleFaces[0].edge = 0; | ||||
| 		triangleFaces[1].edge = 1; | ||||
| 		 | ||||
| 		b3Vec3 N = b3Cross(B - A, C - A); | ||||
| 		N = b3Normalize(N); | ||||
|  | ||||
| 		trianglePlanes[0] = b3Plane(N, centroid); | ||||
| 		trianglePlanes[1] = b3Plane(-N, centroid); | ||||
| 		 | ||||
| 		vertices = triangleVertices; | ||||
| 		vertexCount = 3; | ||||
| 		edges = triangleEdges; | ||||
| 		edgeCount = 6; | ||||
| 		faces = triangleFaces; | ||||
| 		planes = trianglePlanes; | ||||
| 		faceCount = 2; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										240
									
								
								include/bounce/collision/trees/dynamic_tree.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								include/bounce/collision/trees/dynamic_tree.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_DYNAMIC_TREE_H | ||||
| #define B3_DYNAMIC_TREE_H | ||||
|  | ||||
| #include <bounce\common\draw.h> | ||||
| #include <bounce\common\template\stack.h> | ||||
| #include <bounce\collision\shapes\aabb3.h> | ||||
| #include <bounce\collision\distance.h> | ||||
|  | ||||
| #define NULL_NODE (-1) | ||||
|  | ||||
| // An AABB tree for dynamic AABBs. | ||||
| class b3DynamicTree  | ||||
| { | ||||
| public : | ||||
| 	b3DynamicTree(); | ||||
| 	~b3DynamicTree(); | ||||
|  | ||||
| 	// Insert a node to the tree and return its ID. | ||||
| 	i32 InsertNode(const b3AABB3& aabb, void* userData); | ||||
| 	 | ||||
| 	// Remove a node from the tree. | ||||
| 	void RemoveNode(i32 proxyId); | ||||
|  | ||||
| 	// Update a node AABB. | ||||
| 	void UpdateNode(i32 proxyId, const b3AABB3& aabb); | ||||
|  | ||||
| 	// Get the (fat) AABB of a given proxy. | ||||
| 	const b3AABB3& GetAABB(i32 proxyId) const; | ||||
|  | ||||
| 	// Get the data associated with a given proxy. | ||||
| 	void* GetUserData(i32 proxyId) const; | ||||
|  | ||||
| 	// Check if two aabbs of this tree are overlapping. | ||||
| 	bool TestOverlap(i32 proxy1, i32 proxy2) const; | ||||
|  | ||||
| 	// Keep reporting the client callback the AABBs that are overlapping with | ||||
| 	// the given AABB. The client callback must return true if the query  | ||||
| 	// must be stopped or false to continue looking for more overlapping pairs. | ||||
| 	template<class T>  | ||||
| 	void QueryAABB(T* callback, const b3AABB3& aabb) const; | ||||
|  | ||||
| 	// Keep reporting the client callback all AABBs that are overlapping with | ||||
| 	// the given ray. The client callback must return the new intersection fraction. | ||||
| 	// If the fraction == 0 then the query is cancelled immediately. | ||||
| 	template<class T> | ||||
| 	void QueryRay(T* callback, const b3RayCastInput& input) const; | ||||
|  | ||||
| 	// Validate a given node of this tree. | ||||
| 	void Validate(i32 node) const; | ||||
|  | ||||
| 	// Draw this tree. | ||||
| 	void Draw(b3Draw* b3Draw) const; | ||||
| private : | ||||
| 	struct b3Node  | ||||
| 	{ | ||||
| 		bool IsLeaf() const  | ||||
| 		{ | ||||
| 			return child1 == NULL_NODE; //or child 2 == NULL_NODE, or height == 0. | ||||
| 		} | ||||
|  | ||||
| 		// The (enlarged) AABB of this node. | ||||
| 		b3AABB3 aabb; | ||||
|  | ||||
| 		// The associated user data. | ||||
| 		void* userData; | ||||
|  | ||||
| 		union  | ||||
| 		{ | ||||
| 			i32 parent; | ||||
| 			i32 next; | ||||
| 		}; | ||||
|  | ||||
| 		i32 child1; | ||||
| 		i32 child2; | ||||
|  | ||||
| 		// leaf = 0, free node = -1 | ||||
| 		i32 height; | ||||
| 	}; | ||||
| 	 | ||||
| 	// Insert a allocated (leaf) node into the tree. | ||||
| 	void InsertLeaf(i32 node); | ||||
| 	 | ||||
| 	// Remove a allocated node from the tree. | ||||
| 	void RemoveLeaf(i32 node); | ||||
|  | ||||
| 	// Rebuild the tree hierarchy starting from the given node. | ||||
| 	void WalkBackNodeAndCombineVolumes(i32 node); | ||||
| 	 | ||||
| 	// Perform a basic surface area heuristic search to find the best | ||||
| 	// node that can be merged with a given AABB. | ||||
| 	i32 HeuristicSearch(const b3AABB3& leafAABB) const; | ||||
|  | ||||
| 	// Peel a node from the free list and insert into the node array.  | ||||
| 	// Allocate a new node if necessary. The function returns the new node index. | ||||
| 	i32 AllocateNode(); | ||||
|  | ||||
| 	// Free a node (not destroy) from the node pool and add it to the free list. | ||||
| 	void FreeNode(i32 node); | ||||
|  | ||||
| 	// Make a node available for the next allocation request. | ||||
| 	void AddToFreeList(i32 node); | ||||
|  | ||||
| 	// The root of this tree. | ||||
| 	i32 m_root; | ||||
|  | ||||
| 	// The nodes of this tree stored in an array. | ||||
| 	b3Node* m_nodes; | ||||
| 	i32 m_nodeCount; | ||||
| 	i32 m_nodeCapacity; | ||||
| 	i32 m_freeList; | ||||
| }; | ||||
|  | ||||
| inline bool b3DynamicTree::TestOverlap(i32 proxy1, i32 proxy2) const  | ||||
| { | ||||
| 	B3_ASSERT(proxy1 < m_nodeCount); | ||||
| 	B3_ASSERT(proxy2 < m_nodeCount); | ||||
| 	return b3TestOverlap(m_nodes[proxy1].aabb, m_nodes[proxy2].aabb); | ||||
| } | ||||
|  | ||||
| inline const b3AABB3& b3DynamicTree::GetAABB(i32 proxyId) const  | ||||
| { | ||||
| 	B3_ASSERT(proxyId < m_nodeCount); | ||||
| 	return m_nodes[proxyId].aabb; | ||||
| } | ||||
|  | ||||
| inline void* b3DynamicTree::GetUserData(i32 proxyId) const  | ||||
| { | ||||
| 	B3_ASSERT(proxyId < m_nodeCount); | ||||
| 	return m_nodes[proxyId].userData; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3DynamicTree::QueryAABB(T* callback, const b3AABB3& aabb) const  | ||||
| { | ||||
| 	b3Stack<i32, 256> stack; | ||||
| 	stack.Push(m_root); | ||||
|  | ||||
| 	while (stack.IsEmpty() == false)  | ||||
| 	{ | ||||
| 		i32 nodeIndex = stack.Top(); | ||||
| 		stack.Pop(); | ||||
|  | ||||
| 		if (nodeIndex == NULL_NODE)  | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		const b3Node* node = m_nodes + nodeIndex; | ||||
|  | ||||
| 		if (b3TestOverlap(node->aabb, aabb) == true)  | ||||
| 		{ | ||||
| 			if (node->IsLeaf() == true)  | ||||
| 			{ | ||||
| 				if (callback->Report(nodeIndex) == false)  | ||||
| 				{ | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 			else  | ||||
| 			{ | ||||
| 				stack.Push(node->child1); | ||||
| 				stack.Push(node->child2); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3DynamicTree::QueryRay(T* callback, const b3RayCastInput& input) const  | ||||
| { | ||||
| 	b3Vec3 p1 = input.p1; | ||||
| 	b3Vec3 p2 = input.p2; | ||||
| 	b3Vec3 d = p2 - p1; | ||||
| 	float32 maxFraction = input.maxFraction; | ||||
|  | ||||
| 	// Ensure non-degeneracy. | ||||
| 	B3_ASSERT(b3Dot(d, d) > B3_EPSILON * B3_EPSILON); | ||||
|  | ||||
| 	b3Stack<i32, 256> stack; | ||||
| 	stack.Push(m_root); | ||||
|  | ||||
| 	while (stack.IsEmpty() == false)  | ||||
| 	{ | ||||
| 		i32 nodeIndex = stack.Top(); | ||||
| 		 | ||||
| 		stack.Pop(); | ||||
|  | ||||
| 		if (nodeIndex == NULL_NODE)  | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		const b3Node* node = m_nodes + nodeIndex; | ||||
|  | ||||
| 		float32 minFraction = 0.0f; | ||||
| 		if (node->aabb.TestRay(p1, p2, maxFraction, minFraction) == true)  | ||||
| 		{ | ||||
| 			if (node->IsLeaf() == true)  | ||||
| 			{ | ||||
| 				b3RayCastInput subInput; | ||||
| 				subInput.p1 = input.p1; | ||||
| 				subInput.p2 = input.p2; | ||||
| 				subInput.maxFraction = maxFraction; | ||||
|  | ||||
| 				float32 newFraction = callback->Report(subInput, nodeIndex); | ||||
|  | ||||
| 				if (newFraction == 0.0f) | ||||
| 				{ | ||||
| 					// The client has stopped the query. | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 			else  | ||||
| 			{ | ||||
| 				stack.Push(node->child1); | ||||
| 				stack.Push(node->child2); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										195
									
								
								include/bounce/collision/trees/static_tree.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								include/bounce/collision/trees/static_tree.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,195 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * 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 B3_STATIC_TREE_H | ||||
| #define B3_STATIC_TREE_H | ||||
|  | ||||
| #include <bounce\common\draw.h> | ||||
| #include <bounce\common\template\stack.h> | ||||
| #include <bounce\collision\shapes\aabb3.h> | ||||
| #include <bounce\collision\distance.h> | ||||
|  | ||||
| #define NULL_NODE_S (0xFFFFFFFF) | ||||
|  | ||||
| // An AABB tree for static AABBs. | ||||
| class b3StaticTree  | ||||
| { | ||||
| public: | ||||
| 	b3StaticTree(); | ||||
| 	~b3StaticTree(); | ||||
|  | ||||
| 	// Build the tree. | ||||
| 	// Output a sorted index array. | ||||
| 	void Build(u32* indices, const b3AABB3* aabbs, u32 count); | ||||
|  | ||||
| 	// Get the AABB of a given proxy. | ||||
| 	const b3AABB3& GetAABB(u32 proxyId) const; | ||||
|  | ||||
| 	// Get the index associated of a given proxy. | ||||
| 	u32 GetUserData(u32 proxyId) const; | ||||
|  | ||||
| 	// Report the client callback all AABBs that are overlapping with | ||||
| 	// the given AABB. The client callback must return true if the query  | ||||
| 	// must be stopped or false to continue looking for more overlapping pairs. | ||||
| 	template<class T> | ||||
| 	void QueryAABB(T* callback, const b3AABB3& aabb) const; | ||||
|  | ||||
| 	// Report the client callback all AABBs that are overlapping with | ||||
| 	// the given ray. The client callback must return the new intersection fraction  | ||||
| 	// (real). If the fraction == 0 then the query is cancelled immediatly. | ||||
| 	template<class T> | ||||
| 	void QueryRay(T* callback, const b3RayCastInput& input) const; | ||||
|  | ||||
| 	// Draw the hierarchy. | ||||
| 	void Draw(b3Draw* b3Draw) const; | ||||
| private : | ||||
| 	// A node in a static tree. | ||||
| 	struct b3Node | ||||
| 	{ | ||||
| 		b3AABB3 aabb; | ||||
| 		u32 child1; | ||||
| 		union | ||||
| 		{ | ||||
| 			u32 child2; | ||||
| 			u32 index; | ||||
| 		}; | ||||
|  | ||||
| 		// Check if a node is a leaf node | ||||
| 		bool IsLeaf() const | ||||
| 		{ | ||||
| 			return child1 == NULL_NODE_S; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	u32 m_nodeCount; | ||||
| 	b3Node* m_nodes; | ||||
| }; | ||||
|  | ||||
| inline const b3AABB3& b3StaticTree::GetAABB(u32 proxyId) const | ||||
| { | ||||
| 	B3_ASSERT(proxyId < m_nodeCount); | ||||
| 	return m_nodes[proxyId].aabb; | ||||
| } | ||||
|  | ||||
| inline u32 b3StaticTree::GetUserData(u32 proxyId) const | ||||
| { | ||||
| 	B3_ASSERT(proxyId < m_nodeCount); | ||||
| 	B3_ASSERT(m_nodes[proxyId].IsLeaf()); | ||||
| 	return m_nodes[proxyId].index; | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3StaticTree::QueryAABB(T* callback, const b3AABB3& aabb) const | ||||
| { | ||||
| 	if (m_nodeCount == 0)  | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	u32 root = 0; | ||||
|  | ||||
| 	b3Stack<u32, 256> stack; | ||||
| 	stack.Push(root); | ||||
|  | ||||
| 	while (stack.IsEmpty() == false)  | ||||
| 	{ | ||||
| 		u32 nodeIndex = stack.Top(); | ||||
| 		 | ||||
| 		stack.Pop(); | ||||
|  | ||||
| 		const b3Node* node = m_nodes + nodeIndex; | ||||
|  | ||||
| 		if (b3TestOverlap(node->aabb, aabb) == true)  | ||||
| 		{ | ||||
| 			if (node->IsLeaf() == true)  | ||||
| 			{ | ||||
| 				if (callback->Report(nodeIndex) == false)  | ||||
| 				{ | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 			else  | ||||
| 			{ | ||||
| 				stack.Push(node->child1); | ||||
| 				stack.Push(node->child2); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| template<class T> | ||||
| inline void b3StaticTree::QueryRay(T* callback, const b3RayCastInput& input) const  | ||||
| { | ||||
| 	if (m_nodeCount == 0) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	b3Vec3 p1 = input.p1; | ||||
| 	b3Vec3 p2 = input.p2; | ||||
| 	b3Vec3 d = p2 - p1; | ||||
| 	float32 maxFraction = input.maxFraction; | ||||
|  | ||||
| 	// Ensure non-degeneracy. | ||||
| 	B3_ASSERT(b3Dot(d, d) > B3_EPSILON * B3_EPSILON); | ||||
|  | ||||
| 	u32 root = 0; | ||||
|  | ||||
| 	b3Stack<u32, 256> stack; | ||||
| 	stack.Push(root); | ||||
|  | ||||
| 	while (stack.IsEmpty() == false)  | ||||
| 	{ | ||||
| 		i32 nodeIndex = stack.Top();	 | ||||
| 		stack.Pop(); | ||||
|  | ||||
| 		if (nodeIndex == NULL_NODE_S) | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		const b3Node* node = m_nodes + nodeIndex; | ||||
|  | ||||
| 		float32 minFraction = 0.0f; | ||||
| 		if (node->aabb.TestRay(p1, p2, maxFraction, minFraction) == true)  | ||||
| 		{ | ||||
| 			if (node->IsLeaf() == true)  | ||||
| 			{ | ||||
| 				b3RayCastInput subInput; | ||||
| 				subInput.p1 = input.p1; | ||||
| 				subInput.p2 = input.p2; | ||||
| 				subInput.maxFraction = maxFraction; | ||||
|  | ||||
| 				float32 newFraction = callback->Report(subInput, nodeIndex); | ||||
|  | ||||
| 				if (newFraction == 0.0f)  | ||||
| 				{ | ||||
| 					// The client has stopped the query. | ||||
| 					return; | ||||
| 				} | ||||
| 			} | ||||
| 			else  | ||||
| 			{ | ||||
| 				stack.Push(node->child1); | ||||
| 				stack.Push(node->child2); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user