first commit
[blok] / Box2D / Source / Dynamics / Contacts / b2Contact.h
diff --git a/Box2D/Source/Dynamics/Contacts/b2Contact.h b/Box2D/Source/Dynamics/Contacts/b2Contact.h
new file mode 100644 (file)
index 0000000..25cee8e
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+*
+* 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 CONTACT_H
+#define CONTACT_H
+
+#include "../../Common/b2Math.h"
+#include "../../Collision/b2Collision.h"
+#include "../../Collision/Shapes/b2Shape.h"
+
+class b2Body;
+class b2Contact;
+class b2World;
+class b2BlockAllocator;
+class b2StackAllocator;
+class b2ContactListener;
+
+typedef b2Contact* b2ContactCreateFcn(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
+typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
+
+struct b2ContactRegister
+{
+       b2ContactCreateFcn* createFcn;
+       b2ContactDestroyFcn* destroyFcn;
+       bool primary;
+};
+
+/// A contact edge is used to connect bodies and contacts together
+/// in a contact graph where each body is a node and each contact
+/// is an edge. A contact edge belongs to a doubly linked list
+/// maintained in each attached body. Each contact has two contact
+/// nodes, one for each attached body.
+struct b2ContactEdge
+{
+       b2Body* other;                  ///< provides quick access to the other body attached.
+       b2Contact* contact;             ///< the contact
+       b2ContactEdge* prev;    ///< the previous contact edge in the body's contact list
+       b2ContactEdge* next;    ///< the next contact edge in the body's contact list
+};
+
+/// This structure is used to report contact points.
+struct b2ContactPoint
+{
+       b2Shape* shape1;                ///< the first shape
+       b2Shape* shape2;                ///< the second shape
+       b2Vec2 position;                ///< position in world coordinates
+       b2Vec2 velocity;                ///< velocity of point on body2 relative to point on body1 (pre-solver)
+       b2Vec2 normal;                  ///< points from shape1 to shape2
+       float32 separation;             ///< the separation is negative when shapes are touching
+       float32 friction;               ///< the combined friction coefficient
+       float32 restitution;    ///< the combined restitution coefficient
+       b2ContactID id;                 ///< the contact id identifies the features in contact
+};
+
+/// This structure is used to report contact point results.
+struct b2ContactResult
+{
+       b2Shape* shape1;                ///< the first shape
+       b2Shape* shape2;                ///< the second shape
+       b2Vec2 position;                ///< position in world coordinates
+       b2Vec2 normal;                  ///< points from shape1 to shape2
+       float32 normalImpulse;  ///< the normal impulse applied to body2
+       float32 tangentImpulse; ///< the tangent impulse applied to body2
+       b2ContactID id;                 ///< the contact id identifies the features in contact
+};
+
+/// The class manages contact between two shapes. A contact exists for each overlapping
+/// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
+/// that has no contact points.
+class b2Contact
+{
+public:
+
+       /// Get the manifold array.
+       virtual b2Manifold* GetManifolds() = 0;
+
+       /// Get the number of manifolds. This is 0 or 1 between convex shapes.
+       /// This may be greater than 1 for convex-vs-concave shapes. Each
+       /// manifold holds up to two contact points with a shared contact normal.
+       int32 GetManifoldCount() const;
+
+       /// Is this contact solid?
+       /// @return true if this contact should generate a response.
+       bool IsSolid() const;
+
+       /// Get the next contact in the world's contact list.
+       b2Contact* GetNext();
+
+       /// Get the first shape in this contact.
+       b2Shape* GetShape1();
+
+       /// Get the second shape in this contact.
+       b2Shape* GetShape2();
+
+       //--------------- Internals Below -------------------
+public:
+
+       // m_flags
+       enum
+       {
+               e_nonSolidFlag  = 0x0001,
+               e_slowFlag              = 0x0002,
+               e_islandFlag    = 0x0004,
+               e_toiFlag               = 0x0008,
+       };
+
+       static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
+                                               b2ShapeType type1, b2ShapeType type2);
+       static void InitializeRegisters();
+       static b2Contact* Create(b2Shape* shape1, b2Shape* shape2, b2BlockAllocator* allocator);
+       static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+       b2Contact() : m_shape1(NULL), m_shape2(NULL) {}
+       b2Contact(b2Shape* shape1, b2Shape* shape2);
+       virtual ~b2Contact() {}
+
+       void Update(b2ContactListener* listener);
+       virtual void Evaluate(b2ContactListener* listener) = 0;
+       static b2ContactRegister s_registers[e_shapeTypeCount][e_shapeTypeCount];
+       static bool s_initialized;
+
+       uint32 m_flags;
+       int32 m_manifoldCount;
+
+       // World pool and list pointers.
+       b2Contact* m_prev;
+       b2Contact* m_next;
+
+       // Nodes for connecting bodies.
+       b2ContactEdge m_node1;
+       b2ContactEdge m_node2;
+
+       b2Shape* m_shape1;
+       b2Shape* m_shape2;
+
+       // Combined friction
+       float32 m_friction;
+       float32 m_restitution;
+
+       float32 m_toi;
+};
+
+inline int32 b2Contact::GetManifoldCount() const
+{
+       return m_manifoldCount;
+}
+
+inline bool b2Contact::IsSolid() const
+{
+       return (m_flags & e_nonSolidFlag) == 0;
+}
+
+inline b2Contact* b2Contact::GetNext()
+{
+       return m_next;
+}
+
+inline b2Shape* b2Contact::GetShape1()
+{
+       return m_shape1;
+}
+
+inline b2Shape* b2Contact::GetShape2()
+{
+       return m_shape2;
+}
+
+#endif