fix a lot of issues, add gyroscopic force integrator, add contact polygon winding, add some quaternion constraints, add more tests

This commit is contained in:
Irlan
2017-03-24 18:49:41 -03:00
parent dd6ca355e9
commit 8defab9945
103 changed files with 3840 additions and 3355 deletions

View File

@ -98,9 +98,9 @@ private :
u32 m_moveBufferCapacity;
// The buffer holding the unique overlapping AABB pairs.
b3Pair* m_pairBuffer;
u32 m_pairBufferCapacity;
u32 m_pairBufferCount;
b3Pair* m_pairs;
u32 m_pairCapacity;
u32 m_pairCount;
};
inline const b3AABB3& b3BroadPhase::GetAABB(i32 proxyId) const
@ -144,7 +144,7 @@ template<class T>
inline void b3BroadPhase::FindNewPairs(T* callback)
{
// Reset the overlapping pairs buffer count for the current step.
m_pairBufferCount = 0;
m_pairCount = 0;
// Notifying this class with QueryCallback(), gets the (duplicated) overlapping pair buffer.
for (u32 i = 0; i < m_moveBufferCount; ++i)
@ -164,22 +164,22 @@ inline void b3BroadPhase::FindNewPairs(T* callback)
m_moveBufferCount = 0;
// Sort the (duplicated) overlapping pair buffer to prune duplicated pairs.
std::sort(m_pairBuffer, m_pairBuffer + m_pairBufferCount);
std::sort(m_pairs, m_pairs + m_pairCount);
// Skip duplicated overlapping pairs.
u32 index = 0;
while (index < m_pairBufferCount)
while (index < m_pairCount)
{
const b3Pair* primaryPair = m_pairBuffer + index;
const b3Pair* primaryPair = m_pairs + 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)
while (index < m_pairCount)
{
const b3Pair* secondaryPair = m_pairBuffer + index;
const b3Pair* secondaryPair = m_pairs + index;
if (secondaryPair->proxy1 != primaryPair->proxy1 || secondaryPair->proxy2 != primaryPair->proxy2)
{
break;

View File

@ -16,42 +16,12 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_DISTANCE_H
#define B3_DISTANCE_H
#ifndef B3_COLLISION_H
#define B3_COLLISION_H
#include <bounce/common/geometry.h>
#include <bounce/collision/shapes/aabb3.h>
///////////////////////////////////////////////////////////////////////////////////////////////////
// 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.
void b3ClosestPointsOnSegments(b3Vec3* C1, b3Vec3* C2,
const b3Vec3& P1, const b3Vec3& Q1,
const b3Vec3& P2, const b3Vec3& Q2);
///////////////////////////////////////////////////////////////////////////////////////////////////
// Input for a ray cast.
struct b3RayCastInput
{

View File

@ -26,12 +26,12 @@ struct b3SimplexCache;
struct b3SimplexVertex
{
b3Vec3 pointA; // support vertex on proxy A
b3Vec3 pointB; // support vertex on proxy B
b3Vec3 point1; // support vertex on proxy 1
b3Vec3 point2; // support vertex on proxy 2
b3Vec3 point; // minkowski vertex
float32 weight; // barycentric coordinate for point
u32 indexA; // support A vertex index
u32 indexB; // support B vertex index
u32 index1; // support 1 vertex index
u32 index2; // support 2 vertex index
};
struct b3Simplex
@ -41,7 +41,7 @@ struct b3Simplex
b3Vec3 GetSearchDirection(const b3Vec3& Q) const;
b3Vec3 GetClosestPoint() const;
void GetClosestPoints(b3Vec3* pA, b3Vec3* pB) const;
void GetClosestPoints(b3Vec3* p1, b3Vec3* p2) const;
void Solve2(const b3Vec3& Q);
void Solve3(const b3Vec3& Q);
@ -49,9 +49,11 @@ struct b3Simplex
// Cache
void ReadCache(const b3SimplexCache* cache,
const b3Transform& xfA, const b3GJKProxy& proxyA,
const b3Transform& xfB, const b3GJKProxy& proxyB);
const b3Transform& xf1, const b3GJKProxy& proxy1,
const b3Transform& xf2, const b3GJKProxy& proxy2);
void WriteCache(b3SimplexCache* cache) const;
float32 GetMetric() const;
};
@ -61,14 +63,14 @@ struct b3Simplex
// If the distance is zero then the proxies are overlapping.
struct b3GJKOutput
{
b3Vec3 pointA; // closest point on proxy A
b3Vec3 pointB; // closest point on proxy B
b3Vec3 point1; // closest point on proxy 1
b3Vec3 point2; // closest point on proxy 2
float32 distance; // euclidean distance between the closest points
u32 iterations; // number of GJK iterations
};
// Find the closest points and distance between two proxies.
b3GJKOutput b3GJK(const b3Transform& xfA, const b3GJKProxy& proxyA,
const b3Transform& xfB, const b3GJKProxy& proxyB);
b3GJKOutput b3GJK(const b3Transform& xf1, const b3GJKProxy& proxy1,
const b3Transform& xf2, const b3GJKProxy& proxy2);
#endif

View File

@ -31,25 +31,25 @@ struct b3SimplexCache
float32 metric; // distance 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
u8 index1[4]; // support vertices on proxy 1
u8 index2[4]; // support vertices on proxy 2
};
// Find the closest points and distance between two proxies.
// Assumes a simplex is given for increasing the performance of
// the algorithm when called more than once.
b3GJKOutput b3GJK(const b3Transform& xfA, const b3GJKProxy& proxyA,
const b3Transform& xfB, const b3GJKProxy& proxyB,
b3GJKOutput b3GJK(const b3Transform& xf1, const b3GJKProxy& proxy1,
const b3Transform& xf2, const b3GJKProxy& proxy2,
bool applyRadius, b3SimplexCache* cache);
// A feature pair contains the vertices of the features associated
// with the closest points.
struct b3GJKFeaturePair
{
u32 indexA[3]; // vertices on proxy A
u32 countA; // number of vertices on proxy A
u32 indexB[3]; // vertices on proxy B
u32 countB; // number of vertices on proxy B
u32 index1[3]; // vertices on proxy 1
u32 count1; // number of vertices on proxy 1
u32 index2[3]; // vertices on proxy 2
u32 count2; // number of vertices on proxy 2
};
// Identify the vertices of the features that the closest points between two

View File

@ -33,15 +33,15 @@ struct b3FaceQuery
float32 b3Project(const b3Hull* hull, const b3Plane& plane);
b3FaceQuery b3QueryFaceSeparation(const b3Transform& xfA, const b3Hull* hullA,
const b3Transform& xfB, const b3Hull* hullB);
b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Hull* hull1,
const b3Transform& xf2, const b3Hull* hull2);
///////////////////////////////////////////////////////////////////////////////////////////////////
struct b3EdgeQuery
{
u32 indexA;
u32 indexB;
u32 index1;
u32 index2;
float32 separation;
};
@ -49,7 +49,7 @@ bool b3IsMinkowskiFace(const b3Vec3& A, const b3Vec3& B, const b3Vec3& B_x_A, co
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);
b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xf1, const b3Hull* hull1,
const b3Transform& xf2, const b3Hull* hull2);
#endif

View File

@ -21,20 +21,20 @@
#include <bounce/collision/sat/sat.h>
struct b3Capsule;
struct b3Segment;
///////////////////////////////////////////////////////////////////////////////////////////////////
float32 b3ProjectEdge(const b3Capsule* hull, const b3Plane& plane);
float32 b3ProjectEdge(const b3Segment* hull, const b3Plane& plane);
b3FaceQuery b3QueryFaceSeparation(const b3Transform& xfA, const b3Capsule* hullA,
const b3Transform& xfB, const b3Hull* hullB);
b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Segment* hull1,
const b3Transform& xf2, const b3Hull* hull2);
///////////////////////////////////////////////////////////////////////////////////////////////////
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);
b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xf1, const b3Segment* hull1,
const b3Transform& xf2, const b3Hull* hull2);
#endif

View File

@ -21,13 +21,11 @@
#include <bounce/collision/sat/sat.h>
struct b3Sphere;
///////////////////////////////////////////////////////////////////////////////////////////////////
float32 b3ProjectVertex(const b3Sphere* hull, const b3Plane& plane);
float32 b3ProjectVertex(const b3Vec3& hull, const b3Plane& plane);
b3FaceQuery b3QueryFaceSeparation(const b3Transform& xfA, const b3Sphere* hullA,
const b3Transform& xfB, const b3Hull* hullB);
b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Vec3& hull1,
const b3Transform& xf2, const b3Hull* hull2);
#endif

View File

@ -90,6 +90,8 @@ struct b3BoxHull : public b3Hull
faces = boxFaces;
planes = boxPlanes;
faceCount = 6;
Validate();
}
// Set this box from three extents and centered at the origin.
@ -102,8 +104,6 @@ struct b3BoxHull : public b3Hull
}
// Set this box to the unit box and transform it.
// Warning: The transform must not contain non-uniform
// scaling!
void SetTransform(const b3Transform& T)
{
boxVertices[0] = b3Vec3(1.0f, 1.0f, -1.0f);
@ -169,6 +169,8 @@ struct b3BoxHull : public b3Hull
faceCount = 6;
centroid = T * centroid;
Validate();
}
};

View File

@ -21,21 +21,20 @@
#include <bounce/common/math/vec3.h>
struct b3Capsule
struct b3Segment
{
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
inline const b3Vec3& b3Segment::GetVertex(u32 index) const
{
return vertices[index];
}
inline u32 b3Capsule::GetSupportVertex(const b3Vec3& d) const
inline u32 b3Segment::GetSupportVertex(const b3Vec3& d) const
{
if (b3Dot(d, vertices[0]) > b3Dot(d, vertices[1]))
{

View File

@ -51,7 +51,9 @@ struct b3Hull
const b3Plane& GetPlane(u32 index) const;
u32 GetSupportVertex(const b3Vec3& direction) const;
//u32 GetSupportEdge(const b3Vec3& direction) const;
u32 GetSupportFace(const b3Vec3& direction) const;
b3Plane GetEdgeSidePlane(u32 index) const;
u32 GetSize() const;

View File

@ -22,7 +22,7 @@
#include <bounce/common/draw.h>
#include <bounce/common/template/stack.h>
#include <bounce/collision/shapes/aabb3.h>
#include <bounce/collision/distance.h>
#include <bounce/collision/collision.h>
#define NULL_NODE (-1)

View File

@ -22,7 +22,7 @@
#include <bounce/common/draw.h>
#include <bounce/common/template/stack.h>
#include <bounce/collision/shapes/aabb3.h>
#include <bounce/collision/distance.h>
#include <bounce/collision/collision.h>
#define NULL_NODE_S (0xFFFFFFFF)