mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-15 14:10:11 +00:00
174 lines
5.3 KiB
C++
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
|