bullet3/Bullet/NarrowPhaseCollision/Hull.h
2006-05-25 19:18:29 +00:00

174 lines
5.3 KiB
C++

// Bullet Continuous Collision Detection and Physics Library
// Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
//
//
// Hull.h
//
// Copyright (c) 2006 Simon Hobbs
//
// 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 SAT_HULL_H
#define SAT_HULL_H
#include "Maths.h"
#include "Shape.h"
class DynWorld;
class HullContactCollector;
/// Hull implements a convex collision detection algorithm based on Separating Axis Theorem (SAT). It is an alternative to GJK.
/// It calculates the separating axis, and based on that it calculates the contact manifold (points) in one go.
/// The separating axis calculation is approximated, not all edge-edge calculations are performed (performance reasons).
/// Future idea is to combine this with GJK for polyhedra: GJK to calculate the separating axis, and Hull clipping code to calculate the full set of contacts.
class Hull : public Shape
{
friend class ShapeCollider;
public:
struct Edge
{
short m_verts[2];
short m_faces[2];
short m_nextEdge[2]; // for each m_face
};
struct Face
{
short m_numEdges;
short m_firstEdge;
};
private:
static const int kMaxVerts = 256;
static const int kMaxFaces = 256;
static const int kMaxEdges = 256;
short m_numVerts;
short m_numFaces;
short m_numEdges;
Point3* m_pVerts;
Face* m_pFaces;
Edge* m_pEdges;
Plane* m_pPlanes;
// hull construction stuff
static const int kTmpFaceMaxVerts = 64;
struct TmpFace
{
short m_index;
short m_next;
short m_numVerts;
short m_verts[kTmpFaceMaxVerts];
short m_edges[kTmpFaceMaxVerts];
Plane m_plane;
};
struct TmpEdge
{
short m_index;
short m_next;
short m_verts[2];
short m_faces[2];
};
static short s_firstFreeTmpFace;
static short s_firstUsedTmpFace;
static TmpFace* s_pTmpFaces;
static short s_firstFreeTmpEdge;
static short s_firstUsedTmpEdge;
static TmpEdge* s_pTmpEdges;
static const Point3* s_pPoints;
static short AllocTmpFace();
static void FreeTmpFace(short face);
static TmpFace* GetTmpFace(short index) {if (index < 0) return 0; return s_pTmpFaces + index;}
static short AllocTmpEdge();
static void FreeTmpEdge(short edge);
static TmpEdge* GetTmpEdge(short index) {if (index < 0) return 0; return s_pTmpEdges + index;}
static short MatchOrAddEdge(short vert0, short vert1, short face);
static void UnmatchOrRemoveEdge(short edge, short face);
static short AddTmpFace(short vert0, short vert1, short vert2);
static short AddTmpFace(short numVerts, short* pVerts);
static short AddTmpFace(short vert0, short numOtherVerts, short* pVerts);
static void RemoveTmpFace(short face);
static bool TmpFaceAddPoint(short point, short face);
static int RemoveVisibleFaces(const Point3& point);
static void FillHole(short newVertex);
static Hull* MakeHullFromTemp();
public:
Hull();
~Hull();
// ObjectType GetObjectType() const {return kTypeHull;}
short GetNumVertices() const;
short GetNumFaces() const;
short GetNumEdges() const;
const Point3& GetVertex(short index) const;
const Face& GetFace(short index) const;
const Edge& GetEdge(short index) const;
const Plane& GetPlane(short index) const;
short GetFaceFirstEdge(short face) const;
short GetFaceNextEdge(short face, short prevEdge) const;
short GetEdgeVertex0(short face, short edge) const;
short GetEdgeVertex1(short face, short edge) const;
short GetEdgeOtherFace(short edge, short face) const;
Point3 GetFaceCentroid(short face) const;
//static void ProcessHullHull(Separation& sep);
static void ProcessHullHull(Separation& sep,const Hull& shapeA,const Hull& shapeB,const Transform& trA,const Transform& trB, HullContactCollector* collector);
virtual void ComputeInertia(const Transform& transform, Point3& centerOfMass, Matrix33& inertia, float totalMass) const;
virtual Bounds3 ComputeBounds(const Transform& transform) const;
static Hull* MakeHull(int numPoints, const Point3* pPoints);
//for contact generation
/// Clips a face to the back of a plane
static int ClipFace(int numVerts, Point3** ppVtxIn, Point3** ppVtxOut, const Plane& plane);
static bool GetSeparationHullHull(Separation& sep, const Point3* pVertsA, const Point3* pVertsB,
const Transform& trA, const Transform& trB,
const Hull& hullA,
const Hull& hullB
);
static int AddContactsHullHull(Separation& sep, const Point3* pVertsA, const Point3* pVertsB,
const Transform& trA, const Transform& trB,const Hull& hullA,const Hull& hullB,
HullContactCollector* hullContactCollector);
};
#include "hull.inl"
#endif //SAT_HULL_H