fix macOS build (following Projucer changes made in Windows, which removed /Applications/JUCE/modules from its headers). move JUCE headers under source control, so that Windows and macOS can both build against same version of JUCE. remove AUv3 target (I think it's an iOS thing, so it will never work with this macOS fluidsynth dylib).
This commit is contained in:
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2ChainAndCircleContact.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../b2Fixture.h"
|
||||
#include "../../Collision/Shapes/b2ChainShape.h"
|
||||
#include "../../Collision/Shapes/b2EdgeShape.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2ChainAndCircleContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2ChainAndCircleContact));
|
||||
return new (mem) b2ChainAndCircleContact(fixtureA, indexA, fixtureB, indexB);
|
||||
}
|
||||
|
||||
void b2ChainAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2ChainAndCircleContact*)contact)->~b2ChainAndCircleContact();
|
||||
allocator->Free(contact, sizeof(b2ChainAndCircleContact));
|
||||
}
|
||||
|
||||
b2ChainAndCircleContact::b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB)
|
||||
: b2Contact(fixtureA, indexA, fixtureB, indexB)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_chain);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
|
||||
}
|
||||
|
||||
void b2ChainAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2ChainShape* chain = (b2ChainShape*)m_fixtureA->GetShape();
|
||||
b2EdgeShape edge;
|
||||
chain->GetChildEdge(&edge, m_indexA);
|
||||
b2CollideEdgeAndCircle( manifold, &edge, xfA,
|
||||
(b2CircleShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_CHAIN_AND_CIRCLE_CONTACT_H
|
||||
#define B2_CHAIN_AND_CIRCLE_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2ChainAndCircleContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create( b2Fixture* fixtureA, int32 indexA,
|
||||
b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2ChainAndCircleContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
|
||||
~b2ChainAndCircleContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2ChainAndPolygonContact.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../b2Fixture.h"
|
||||
#include "../../Collision/Shapes/b2ChainShape.h"
|
||||
#include "../../Collision/Shapes/b2EdgeShape.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2ChainAndPolygonContact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2ChainAndPolygonContact));
|
||||
return new (mem) b2ChainAndPolygonContact(fixtureA, indexA, fixtureB, indexB);
|
||||
}
|
||||
|
||||
void b2ChainAndPolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2ChainAndPolygonContact*)contact)->~b2ChainAndPolygonContact();
|
||||
allocator->Free(contact, sizeof(b2ChainAndPolygonContact));
|
||||
}
|
||||
|
||||
b2ChainAndPolygonContact::b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB)
|
||||
: b2Contact(fixtureA, indexA, fixtureB, indexB)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_chain);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon);
|
||||
}
|
||||
|
||||
void b2ChainAndPolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2ChainShape* chain = (b2ChainShape*)m_fixtureA->GetShape();
|
||||
b2EdgeShape edge;
|
||||
chain->GetChildEdge(&edge, m_indexA);
|
||||
b2CollideEdgeAndPolygon( manifold, &edge, xfA,
|
||||
(b2PolygonShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_CHAIN_AND_POLYGON_CONTACT_H
|
||||
#define B2_CHAIN_AND_POLYGON_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2ChainAndPolygonContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create( b2Fixture* fixtureA, int32 indexA,
|
||||
b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2ChainAndPolygonContact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
|
||||
~b2ChainAndPolygonContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2CircleContact.h"
|
||||
#include "../b2Body.h"
|
||||
#include "../b2Fixture.h"
|
||||
#include "../b2WorldCallbacks.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../../Collision/b2TimeOfImpact.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2CircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2CircleContact));
|
||||
return new (mem) b2CircleContact(fixtureA, fixtureB);
|
||||
}
|
||||
|
||||
void b2CircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2CircleContact*)contact)->~b2CircleContact();
|
||||
allocator->Free(contact, sizeof(b2CircleContact));
|
||||
}
|
||||
|
||||
b2CircleContact::b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
|
||||
: b2Contact(fixtureA, 0, fixtureB, 0)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_circle);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
|
||||
}
|
||||
|
||||
void b2CircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2CollideCircles(manifold,
|
||||
(b2CircleShape*)m_fixtureA->GetShape(), xfA,
|
||||
(b2CircleShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
39
modules/juce_box2d/box2d/Dynamics/Contacts/b2CircleContact.h
Normal file
39
modules/juce_box2d/box2d/Dynamics/Contacts/b2CircleContact.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_CIRCLE_CONTACT_H
|
||||
#define B2_CIRCLE_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2CircleContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create( b2Fixture* fixtureA, int32 indexA,
|
||||
b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2CircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
|
||||
~b2CircleContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
240
modules/juce_box2d/box2d/Dynamics/Contacts/b2Contact.cpp
Normal file
240
modules/juce_box2d/box2d/Dynamics/Contacts/b2Contact.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2Contact.h"
|
||||
#include "b2CircleContact.h"
|
||||
#include "b2PolygonAndCircleContact.h"
|
||||
#include "b2PolygonContact.h"
|
||||
#include "b2EdgeAndCircleContact.h"
|
||||
#include "b2EdgeAndPolygonContact.h"
|
||||
#include "b2ChainAndCircleContact.h"
|
||||
#include "b2ChainAndPolygonContact.h"
|
||||
#include "b2ContactSolver.h"
|
||||
|
||||
#include "../../Collision/b2Collision.h"
|
||||
#include "../../Collision/b2TimeOfImpact.h"
|
||||
#include "../../Collision/Shapes/b2Shape.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../b2Body.h"
|
||||
#include "../b2Fixture.h"
|
||||
#include "../b2World.h"
|
||||
|
||||
b2ContactRegister b2Contact::s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
|
||||
bool b2Contact::s_initialized = false;
|
||||
|
||||
void b2Contact::InitializeRegisters()
|
||||
{
|
||||
AddType(b2CircleContact::Create, b2CircleContact::Destroy, b2Shape::e_circle, b2Shape::e_circle);
|
||||
AddType(b2PolygonAndCircleContact::Create, b2PolygonAndCircleContact::Destroy, b2Shape::e_polygon, b2Shape::e_circle);
|
||||
AddType(b2PolygonContact::Create, b2PolygonContact::Destroy, b2Shape::e_polygon, b2Shape::e_polygon);
|
||||
AddType(b2EdgeAndCircleContact::Create, b2EdgeAndCircleContact::Destroy, b2Shape::e_edge, b2Shape::e_circle);
|
||||
AddType(b2EdgeAndPolygonContact::Create, b2EdgeAndPolygonContact::Destroy, b2Shape::e_edge, b2Shape::e_polygon);
|
||||
AddType(b2ChainAndCircleContact::Create, b2ChainAndCircleContact::Destroy, b2Shape::e_chain, b2Shape::e_circle);
|
||||
AddType(b2ChainAndPolygonContact::Create, b2ChainAndPolygonContact::Destroy, b2Shape::e_chain, b2Shape::e_polygon);
|
||||
}
|
||||
|
||||
void b2Contact::AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destoryFcn,
|
||||
b2Shape::Type type1, b2Shape::Type type2)
|
||||
{
|
||||
b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount);
|
||||
b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount);
|
||||
|
||||
s_registers[type1][type2].createFcn = createFcn;
|
||||
s_registers[type1][type2].destroyFcn = destoryFcn;
|
||||
s_registers[type1][type2].primary = true;
|
||||
|
||||
if (type1 != type2)
|
||||
{
|
||||
s_registers[type2][type1].createFcn = createFcn;
|
||||
s_registers[type2][type1].destroyFcn = destoryFcn;
|
||||
s_registers[type2][type1].primary = false;
|
||||
}
|
||||
}
|
||||
|
||||
b2Contact* b2Contact::Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator)
|
||||
{
|
||||
if (s_initialized == false)
|
||||
{
|
||||
InitializeRegisters();
|
||||
s_initialized = true;
|
||||
}
|
||||
|
||||
b2Shape::Type type1 = fixtureA->GetType();
|
||||
b2Shape::Type type2 = fixtureB->GetType();
|
||||
|
||||
b2Assert(0 <= type1 && type1 < b2Shape::e_typeCount);
|
||||
b2Assert(0 <= type2 && type2 < b2Shape::e_typeCount);
|
||||
|
||||
b2ContactCreateFcn* createFcn = s_registers[type1][type2].createFcn;
|
||||
if (createFcn)
|
||||
{
|
||||
if (s_registers[type1][type2].primary)
|
||||
{
|
||||
return createFcn(fixtureA, indexA, fixtureB, indexB, allocator);
|
||||
}
|
||||
else
|
||||
{
|
||||
return createFcn(fixtureB, indexB, fixtureA, indexA, allocator);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void b2Contact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
b2Assert(s_initialized == true);
|
||||
|
||||
if (contact->m_manifold.pointCount > 0)
|
||||
{
|
||||
contact->GetFixtureA()->GetBody()->SetAwake(true);
|
||||
contact->GetFixtureB()->GetBody()->SetAwake(true);
|
||||
}
|
||||
|
||||
b2Shape::Type typeA = contact->GetFixtureA()->GetType();
|
||||
b2Shape::Type typeB = contact->GetFixtureB()->GetType();
|
||||
|
||||
b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount);
|
||||
b2Assert(0 <= typeA && typeB < b2Shape::e_typeCount);
|
||||
|
||||
b2ContactDestroyFcn* destroyFcn = s_registers[typeA][typeB].destroyFcn;
|
||||
destroyFcn(contact, allocator);
|
||||
}
|
||||
|
||||
b2Contact::b2Contact(b2Fixture* fA, int32 indexA, b2Fixture* fB, int32 indexB)
|
||||
{
|
||||
m_flags = e_enabledFlag;
|
||||
|
||||
m_fixtureA = fA;
|
||||
m_fixtureB = fB;
|
||||
|
||||
m_indexA = indexA;
|
||||
m_indexB = indexB;
|
||||
|
||||
m_manifold.pointCount = 0;
|
||||
|
||||
m_prev = NULL;
|
||||
m_next = NULL;
|
||||
|
||||
m_nodeA.contact = NULL;
|
||||
m_nodeA.prev = NULL;
|
||||
m_nodeA.next = NULL;
|
||||
m_nodeA.other = NULL;
|
||||
|
||||
m_nodeB.contact = NULL;
|
||||
m_nodeB.prev = NULL;
|
||||
m_nodeB.next = NULL;
|
||||
m_nodeB.other = NULL;
|
||||
|
||||
m_toiCount = 0;
|
||||
|
||||
m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
|
||||
m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
|
||||
}
|
||||
|
||||
// Update the contact manifold and touching status.
|
||||
// Note: do not assume the fixture AABBs are overlapping or are valid.
|
||||
void b2Contact::Update(b2ContactListener* listener)
|
||||
{
|
||||
b2Manifold oldManifold = m_manifold;
|
||||
|
||||
// Re-enable this contact.
|
||||
m_flags |= e_enabledFlag;
|
||||
|
||||
bool touching = false;
|
||||
bool wasTouching = (m_flags & e_touchingFlag) == e_touchingFlag;
|
||||
|
||||
bool sensorA = m_fixtureA->IsSensor();
|
||||
bool sensorB = m_fixtureB->IsSensor();
|
||||
bool sensor = sensorA || sensorB;
|
||||
|
||||
b2Body* bodyA = m_fixtureA->GetBody();
|
||||
b2Body* bodyB = m_fixtureB->GetBody();
|
||||
const b2Transform& xfA = bodyA->GetTransform();
|
||||
const b2Transform& xfB = bodyB->GetTransform();
|
||||
|
||||
// Is this contact a sensor?
|
||||
if (sensor)
|
||||
{
|
||||
const b2Shape* shapeA = m_fixtureA->GetShape();
|
||||
const b2Shape* shapeB = m_fixtureB->GetShape();
|
||||
touching = b2TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB);
|
||||
|
||||
// Sensors don't generate manifolds.
|
||||
m_manifold.pointCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Evaluate(&m_manifold, xfA, xfB);
|
||||
touching = m_manifold.pointCount > 0;
|
||||
|
||||
// Match old contact ids to new contact ids and copy the
|
||||
// stored impulses to warm start the solver.
|
||||
for (int32 i = 0; i < m_manifold.pointCount; ++i)
|
||||
{
|
||||
b2ManifoldPoint* mp2 = m_manifold.points + i;
|
||||
mp2->normalImpulse = 0.0f;
|
||||
mp2->tangentImpulse = 0.0f;
|
||||
b2ContactID id2 = mp2->id;
|
||||
|
||||
for (int32 j = 0; j < oldManifold.pointCount; ++j)
|
||||
{
|
||||
b2ManifoldPoint* mp1 = oldManifold.points + j;
|
||||
|
||||
if (mp1->id.key == id2.key)
|
||||
{
|
||||
mp2->normalImpulse = mp1->normalImpulse;
|
||||
mp2->tangentImpulse = mp1->tangentImpulse;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (touching != wasTouching)
|
||||
{
|
||||
bodyA->SetAwake(true);
|
||||
bodyB->SetAwake(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (touching)
|
||||
{
|
||||
m_flags |= e_touchingFlag;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags &= ~e_touchingFlag;
|
||||
}
|
||||
|
||||
if (wasTouching == false && touching == true && listener)
|
||||
{
|
||||
listener->BeginContact(this);
|
||||
}
|
||||
|
||||
if (wasTouching == true && touching == false && listener)
|
||||
{
|
||||
listener->EndContact(this);
|
||||
}
|
||||
|
||||
if (sensor == false && touching && listener)
|
||||
{
|
||||
listener->PreSolve(this, &oldManifold);
|
||||
}
|
||||
}
|
331
modules/juce_box2d/box2d/Dynamics/Contacts/b2Contact.h
Normal file
331
modules/juce_box2d/box2d/Dynamics/Contacts/b2Contact.h
Normal file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_CONTACT_H
|
||||
#define B2_CONTACT_H
|
||||
|
||||
#include "../../Common/b2Math.h"
|
||||
#include "../../Collision/b2Collision.h"
|
||||
#include "../../Collision/Shapes/b2Shape.h"
|
||||
#include "../b2Fixture.h"
|
||||
|
||||
class b2Body;
|
||||
class b2Contact;
|
||||
class b2Fixture;
|
||||
class b2World;
|
||||
class b2BlockAllocator;
|
||||
class b2StackAllocator;
|
||||
class b2ContactListener;
|
||||
|
||||
/// Friction mixing law. The idea is to allow either fixture to drive the restitution to zero.
|
||||
/// For example, anything slides on ice.
|
||||
inline float32 b2MixFriction(float32 friction1, float32 friction2)
|
||||
{
|
||||
return std::sqrt(friction1 * friction2);
|
||||
}
|
||||
|
||||
/// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.
|
||||
/// For example, a superball bounces on anything.
|
||||
inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
|
||||
{
|
||||
return restitution1 > restitution2 ? restitution1 : restitution2;
|
||||
}
|
||||
|
||||
typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, juce::int32 indexA,
|
||||
b2Fixture* fixtureB, juce::int32 indexB,
|
||||
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
|
||||
};
|
||||
|
||||
/// 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 contact manifold. Do not modify the manifold unless you understand the
|
||||
/// internals of Box2D.
|
||||
b2Manifold* GetManifold();
|
||||
const b2Manifold* GetManifold() const;
|
||||
|
||||
/// Get the world manifold.
|
||||
void GetWorldManifold(b2WorldManifold* worldManifold) const;
|
||||
|
||||
/// Is this contact touching?
|
||||
bool IsTouching() const;
|
||||
|
||||
/// Enable/disable this contact. This can be used inside the pre-solve
|
||||
/// contact listener. The contact is only disabled for the current
|
||||
/// time step (or sub-step in continuous collisions).
|
||||
void SetEnabled(bool flag);
|
||||
|
||||
/// Has this contact been disabled?
|
||||
bool IsEnabled() const;
|
||||
|
||||
/// Get the next contact in the world's contact list.
|
||||
b2Contact* GetNext();
|
||||
const b2Contact* GetNext() const;
|
||||
|
||||
/// Get fixture A in this contact.
|
||||
b2Fixture* GetFixtureA();
|
||||
const b2Fixture* GetFixtureA() const;
|
||||
|
||||
/// Get the child primitive index for fixture A.
|
||||
juce::int32 GetChildIndexA() const;
|
||||
|
||||
/// Get fixture B in this contact.
|
||||
b2Fixture* GetFixtureB();
|
||||
const b2Fixture* GetFixtureB() const;
|
||||
|
||||
/// Get the child primitive index for fixture B.
|
||||
juce::int32 GetChildIndexB() const;
|
||||
|
||||
/// Override the default friction mixture. You can call this in b2ContactListener::PreSolve.
|
||||
/// This value persists until set or reset.
|
||||
void SetFriction(float32 friction);
|
||||
|
||||
/// Get the friction.
|
||||
float32 GetFriction() const;
|
||||
|
||||
/// Reset the friction mixture to the default value.
|
||||
void ResetFriction();
|
||||
|
||||
/// Override the default restitution mixture. You can call this in b2ContactListener::PreSolve.
|
||||
/// The value persists until you set or reset.
|
||||
void SetRestitution(float32 restitution);
|
||||
|
||||
/// Get the restitution.
|
||||
float32 GetRestitution() const;
|
||||
|
||||
/// Reset the restitution to the default value.
|
||||
void ResetRestitution();
|
||||
|
||||
/// Evaluate this contact with your own manifold and transforms.
|
||||
virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
|
||||
|
||||
protected:
|
||||
friend class b2ContactManager;
|
||||
friend class b2World;
|
||||
friend class b2ContactSolver;
|
||||
friend class b2Body;
|
||||
friend class b2Fixture;
|
||||
|
||||
// Flags stored in m_flags
|
||||
enum
|
||||
{
|
||||
// Used when crawling contact graph when forming islands.
|
||||
e_islandFlag = 0x0001,
|
||||
|
||||
// Set when the shapes are touching.
|
||||
e_touchingFlag = 0x0002,
|
||||
|
||||
// This contact can be disabled (by user)
|
||||
e_enabledFlag = 0x0004,
|
||||
|
||||
// This contact needs filtering because a fixture filter was changed.
|
||||
e_filterFlag = 0x0008,
|
||||
|
||||
// This bullet contact had a TOI event
|
||||
e_bulletHitFlag = 0x0010,
|
||||
|
||||
// This contact has a valid TOI in m_toi
|
||||
e_toiFlag = 0x0020
|
||||
};
|
||||
|
||||
/// Flag this contact for filtering. Filtering will occur the next time step.
|
||||
void FlagForFiltering();
|
||||
|
||||
static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
|
||||
b2Shape::Type typeA, b2Shape::Type typeB);
|
||||
static void InitializeRegisters();
|
||||
static b2Contact* Create(b2Fixture* fixtureA, juce::int32 indexA, b2Fixture* fixtureB, juce::int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
|
||||
b2Contact(b2Fixture* fixtureA, juce::int32 indexA, b2Fixture* fixtureB, juce::int32 indexB);
|
||||
virtual ~b2Contact() {}
|
||||
|
||||
void Update(b2ContactListener* listener);
|
||||
|
||||
static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
|
||||
static bool s_initialized;
|
||||
|
||||
juce::uint32 m_flags;
|
||||
|
||||
// World pool and list pointers.
|
||||
b2Contact* m_prev;
|
||||
b2Contact* m_next;
|
||||
|
||||
// Nodes for connecting bodies.
|
||||
b2ContactEdge m_nodeA;
|
||||
b2ContactEdge m_nodeB;
|
||||
|
||||
b2Fixture* m_fixtureA;
|
||||
b2Fixture* m_fixtureB;
|
||||
|
||||
juce::int32 m_indexA;
|
||||
juce::int32 m_indexB;
|
||||
|
||||
b2Manifold m_manifold;
|
||||
|
||||
juce::int32 m_toiCount;
|
||||
float32 m_toi;
|
||||
|
||||
float32 m_friction;
|
||||
float32 m_restitution;
|
||||
};
|
||||
|
||||
inline b2Manifold* b2Contact::GetManifold()
|
||||
{
|
||||
return &m_manifold;
|
||||
}
|
||||
|
||||
inline const b2Manifold* b2Contact::GetManifold() const
|
||||
{
|
||||
return &m_manifold;
|
||||
}
|
||||
|
||||
inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
|
||||
{
|
||||
const b2Body* bodyA = m_fixtureA->GetBody();
|
||||
const b2Body* bodyB = m_fixtureB->GetBody();
|
||||
const b2Shape* shapeA = m_fixtureA->GetShape();
|
||||
const b2Shape* shapeB = m_fixtureB->GetShape();
|
||||
|
||||
worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
|
||||
}
|
||||
|
||||
inline void b2Contact::SetEnabled(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
m_flags |= e_enabledFlag;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flags &= ~((unsigned int) e_enabledFlag);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool b2Contact::IsEnabled() const
|
||||
{
|
||||
return (m_flags & e_enabledFlag) == e_enabledFlag;
|
||||
}
|
||||
|
||||
inline bool b2Contact::IsTouching() const
|
||||
{
|
||||
return (m_flags & e_touchingFlag) == e_touchingFlag;
|
||||
}
|
||||
|
||||
inline b2Contact* b2Contact::GetNext()
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
inline const b2Contact* b2Contact::GetNext() const
|
||||
{
|
||||
return m_next;
|
||||
}
|
||||
|
||||
inline b2Fixture* b2Contact::GetFixtureA()
|
||||
{
|
||||
return m_fixtureA;
|
||||
}
|
||||
|
||||
inline const b2Fixture* b2Contact::GetFixtureA() const
|
||||
{
|
||||
return m_fixtureA;
|
||||
}
|
||||
|
||||
inline b2Fixture* b2Contact::GetFixtureB()
|
||||
{
|
||||
return m_fixtureB;
|
||||
}
|
||||
|
||||
inline juce::int32 b2Contact::GetChildIndexA() const
|
||||
{
|
||||
return m_indexA;
|
||||
}
|
||||
|
||||
inline const b2Fixture* b2Contact::GetFixtureB() const
|
||||
{
|
||||
return m_fixtureB;
|
||||
}
|
||||
|
||||
inline juce::int32 b2Contact::GetChildIndexB() const
|
||||
{
|
||||
return m_indexB;
|
||||
}
|
||||
|
||||
inline void b2Contact::FlagForFiltering()
|
||||
{
|
||||
m_flags |= e_filterFlag;
|
||||
}
|
||||
|
||||
inline void b2Contact::SetFriction(float32 friction)
|
||||
{
|
||||
m_friction = friction;
|
||||
}
|
||||
|
||||
inline float32 b2Contact::GetFriction() const
|
||||
{
|
||||
return m_friction;
|
||||
}
|
||||
|
||||
inline void b2Contact::ResetFriction()
|
||||
{
|
||||
m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
|
||||
}
|
||||
|
||||
inline void b2Contact::SetRestitution(float32 restitution)
|
||||
{
|
||||
m_restitution = restitution;
|
||||
}
|
||||
|
||||
inline float32 b2Contact::GetRestitution() const
|
||||
{
|
||||
return m_restitution;
|
||||
}
|
||||
|
||||
inline void b2Contact::ResetRestitution()
|
||||
{
|
||||
m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
|
||||
}
|
||||
|
||||
#endif
|
832
modules/juce_box2d/box2d/Dynamics/Contacts/b2ContactSolver.cpp
Normal file
832
modules/juce_box2d/box2d/Dynamics/Contacts/b2ContactSolver.cpp
Normal file
@ -0,0 +1,832 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2ContactSolver.h"
|
||||
|
||||
#include "b2Contact.h"
|
||||
#include "../b2Body.h"
|
||||
#include "../b2Fixture.h"
|
||||
#include "../b2World.h"
|
||||
#include "../../Common/b2StackAllocator.h"
|
||||
|
||||
#define B2_DEBUG_SOLVER 0
|
||||
|
||||
struct b2ContactPositionConstraint
|
||||
{
|
||||
b2Vec2 localPoints[b2_maxManifoldPoints];
|
||||
b2Vec2 localNormal;
|
||||
b2Vec2 localPoint;
|
||||
int32 indexA;
|
||||
int32 indexB;
|
||||
float32 invMassA, invMassB;
|
||||
b2Vec2 localCenterA, localCenterB;
|
||||
float32 invIA, invIB;
|
||||
b2Manifold::Type type;
|
||||
float32 radiusA, radiusB;
|
||||
int32 pointCount;
|
||||
};
|
||||
|
||||
b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def)
|
||||
{
|
||||
m_step = def->step;
|
||||
m_allocator = def->allocator;
|
||||
m_count = def->count;
|
||||
m_positionConstraints = (b2ContactPositionConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactPositionConstraint));
|
||||
m_velocityConstraints = (b2ContactVelocityConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactVelocityConstraint));
|
||||
m_positions = def->positions;
|
||||
m_velocities = def->velocities;
|
||||
m_contacts = def->contacts;
|
||||
|
||||
// Initialize position independent portions of the constraints.
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2Contact* contact = m_contacts[i];
|
||||
|
||||
b2Fixture* fixtureA = contact->m_fixtureA;
|
||||
b2Fixture* fixtureB = contact->m_fixtureB;
|
||||
b2Shape* shapeA = fixtureA->GetShape();
|
||||
b2Shape* shapeB = fixtureB->GetShape();
|
||||
float32 radiusA = shapeA->m_radius;
|
||||
float32 radiusB = shapeB->m_radius;
|
||||
b2Body* bodyA = fixtureA->GetBody();
|
||||
b2Body* bodyB = fixtureB->GetBody();
|
||||
b2Manifold* manifold = contact->GetManifold();
|
||||
|
||||
int32 pointCount = manifold->pointCount;
|
||||
b2Assert(pointCount > 0);
|
||||
|
||||
b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
|
||||
vc->friction = contact->m_friction;
|
||||
vc->restitution = contact->m_restitution;
|
||||
vc->indexA = bodyA->m_islandIndex;
|
||||
vc->indexB = bodyB->m_islandIndex;
|
||||
vc->invMassA = bodyA->m_invMass;
|
||||
vc->invMassB = bodyB->m_invMass;
|
||||
vc->invIA = bodyA->m_invI;
|
||||
vc->invIB = bodyB->m_invI;
|
||||
vc->contactIndex = i;
|
||||
vc->pointCount = pointCount;
|
||||
vc->K.SetZero();
|
||||
vc->normalMass.SetZero();
|
||||
|
||||
b2ContactPositionConstraint* pc = m_positionConstraints + i;
|
||||
pc->indexA = bodyA->m_islandIndex;
|
||||
pc->indexB = bodyB->m_islandIndex;
|
||||
pc->invMassA = bodyA->m_invMass;
|
||||
pc->invMassB = bodyB->m_invMass;
|
||||
pc->localCenterA = bodyA->m_sweep.localCenter;
|
||||
pc->localCenterB = bodyB->m_sweep.localCenter;
|
||||
pc->invIA = bodyA->m_invI;
|
||||
pc->invIB = bodyB->m_invI;
|
||||
pc->localNormal = manifold->localNormal;
|
||||
pc->localPoint = manifold->localPoint;
|
||||
pc->pointCount = pointCount;
|
||||
pc->radiusA = radiusA;
|
||||
pc->radiusB = radiusB;
|
||||
pc->type = manifold->type;
|
||||
|
||||
for (int32 j = 0; j < pointCount; ++j)
|
||||
{
|
||||
b2ManifoldPoint* cp = manifold->points + j;
|
||||
b2VelocityConstraintPoint* vcp = vc->points + j;
|
||||
|
||||
if (m_step.warmStarting)
|
||||
{
|
||||
vcp->normalImpulse = m_step.dtRatio * cp->normalImpulse;
|
||||
vcp->tangentImpulse = m_step.dtRatio * cp->tangentImpulse;
|
||||
}
|
||||
else
|
||||
{
|
||||
vcp->normalImpulse = 0.0f;
|
||||
vcp->tangentImpulse = 0.0f;
|
||||
}
|
||||
|
||||
vcp->rA.SetZero();
|
||||
vcp->rB.SetZero();
|
||||
vcp->normalMass = 0.0f;
|
||||
vcp->tangentMass = 0.0f;
|
||||
vcp->velocityBias = 0.0f;
|
||||
|
||||
pc->localPoints[j] = cp->localPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b2ContactSolver::~b2ContactSolver()
|
||||
{
|
||||
m_allocator->Free(m_velocityConstraints);
|
||||
m_allocator->Free(m_positionConstraints);
|
||||
}
|
||||
|
||||
// Initialize position dependent portions of the velocity constraints.
|
||||
void b2ContactSolver::InitializeVelocityConstraints()
|
||||
{
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
|
||||
b2ContactPositionConstraint* pc = m_positionConstraints + i;
|
||||
|
||||
float32 radiusA = pc->radiusA;
|
||||
float32 radiusB = pc->radiusB;
|
||||
b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold();
|
||||
|
||||
int32 indexA = vc->indexA;
|
||||
int32 indexB = vc->indexB;
|
||||
|
||||
float32 mA = vc->invMassA;
|
||||
float32 mB = vc->invMassB;
|
||||
float32 iA = vc->invIA;
|
||||
float32 iB = vc->invIB;
|
||||
b2Vec2 localCenterA = pc->localCenterA;
|
||||
b2Vec2 localCenterB = pc->localCenterB;
|
||||
|
||||
b2Vec2 cA = m_positions[indexA].c;
|
||||
float32 aA = m_positions[indexA].a;
|
||||
b2Vec2 vA = m_velocities[indexA].v;
|
||||
float32 wA = m_velocities[indexA].w;
|
||||
|
||||
b2Vec2 cB = m_positions[indexB].c;
|
||||
float32 aB = m_positions[indexB].a;
|
||||
b2Vec2 vB = m_velocities[indexB].v;
|
||||
float32 wB = m_velocities[indexB].w;
|
||||
|
||||
b2Assert(manifold->pointCount > 0);
|
||||
|
||||
b2Transform xfA, xfB;
|
||||
xfA.q.Set(aA);
|
||||
xfB.q.Set(aB);
|
||||
xfA.p = cA - b2Mul(xfA.q, localCenterA);
|
||||
xfB.p = cB - b2Mul(xfB.q, localCenterB);
|
||||
|
||||
b2WorldManifold worldManifold;
|
||||
worldManifold.Initialize(manifold, xfA, radiusA, xfB, radiusB);
|
||||
|
||||
vc->normal = worldManifold.normal;
|
||||
|
||||
int32 pointCount = vc->pointCount;
|
||||
for (int32 j = 0; j < pointCount; ++j)
|
||||
{
|
||||
b2VelocityConstraintPoint* vcp = vc->points + j;
|
||||
|
||||
vcp->rA = worldManifold.points[j] - cA;
|
||||
vcp->rB = worldManifold.points[j] - cB;
|
||||
|
||||
float32 rnA = b2Cross(vcp->rA, vc->normal);
|
||||
float32 rnB = b2Cross(vcp->rB, vc->normal);
|
||||
|
||||
float32 kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
|
||||
|
||||
vcp->normalMass = kNormal > 0.0f ? 1.0f / kNormal : 0.0f;
|
||||
|
||||
b2Vec2 tangent = b2Cross(vc->normal, 1.0f);
|
||||
|
||||
float32 rtA = b2Cross(vcp->rA, tangent);
|
||||
float32 rtB = b2Cross(vcp->rB, tangent);
|
||||
|
||||
float32 kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;
|
||||
|
||||
vcp->tangentMass = kTangent > 0.0f ? 1.0f / kTangent : 0.0f;
|
||||
|
||||
// Setup a velocity bias for restitution.
|
||||
vcp->velocityBias = 0.0f;
|
||||
float32 vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA));
|
||||
if (vRel < -b2_velocityThreshold)
|
||||
{
|
||||
vcp->velocityBias = -vc->restitution * vRel;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have two points, then prepare the block solver.
|
||||
if (vc->pointCount == 2)
|
||||
{
|
||||
b2VelocityConstraintPoint* vcp1 = vc->points + 0;
|
||||
b2VelocityConstraintPoint* vcp2 = vc->points + 1;
|
||||
|
||||
float32 rn1A = b2Cross(vcp1->rA, vc->normal);
|
||||
float32 rn1B = b2Cross(vcp1->rB, vc->normal);
|
||||
float32 rn2A = b2Cross(vcp2->rA, vc->normal);
|
||||
float32 rn2B = b2Cross(vcp2->rB, vc->normal);
|
||||
|
||||
float32 k11 = mA + mB + iA * rn1A * rn1A + iB * rn1B * rn1B;
|
||||
float32 k22 = mA + mB + iA * rn2A * rn2A + iB * rn2B * rn2B;
|
||||
float32 k12 = mA + mB + iA * rn1A * rn2A + iB * rn1B * rn2B;
|
||||
|
||||
// Ensure a reasonable condition number.
|
||||
const float32 k_maxConditionNumber = 1000.0f;
|
||||
if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12))
|
||||
{
|
||||
// K is safe to invert.
|
||||
vc->K.ex.Set(k11, k12);
|
||||
vc->K.ey.Set(k12, k22);
|
||||
vc->normalMass = vc->K.GetInverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The constraints are redundant, just use one.
|
||||
// TODO_ERIN use deepest?
|
||||
vc->pointCount = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void b2ContactSolver::WarmStart()
|
||||
{
|
||||
// Warm start.
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
|
||||
|
||||
int32 indexA = vc->indexA;
|
||||
int32 indexB = vc->indexB;
|
||||
float32 mA = vc->invMassA;
|
||||
float32 iA = vc->invIA;
|
||||
float32 mB = vc->invMassB;
|
||||
float32 iB = vc->invIB;
|
||||
int32 pointCount = vc->pointCount;
|
||||
|
||||
b2Vec2 vA = m_velocities[indexA].v;
|
||||
float32 wA = m_velocities[indexA].w;
|
||||
b2Vec2 vB = m_velocities[indexB].v;
|
||||
float32 wB = m_velocities[indexB].w;
|
||||
|
||||
b2Vec2 normal = vc->normal;
|
||||
b2Vec2 tangent = b2Cross(normal, 1.0f);
|
||||
|
||||
for (int32 j = 0; j < pointCount; ++j)
|
||||
{
|
||||
b2VelocityConstraintPoint* vcp = vc->points + j;
|
||||
b2Vec2 P = vcp->normalImpulse * normal + vcp->tangentImpulse * tangent;
|
||||
wA -= iA * b2Cross(vcp->rA, P);
|
||||
vA -= mA * P;
|
||||
wB += iB * b2Cross(vcp->rB, P);
|
||||
vB += mB * P;
|
||||
}
|
||||
|
||||
m_velocities[indexA].v = vA;
|
||||
m_velocities[indexA].w = wA;
|
||||
m_velocities[indexB].v = vB;
|
||||
m_velocities[indexB].w = wB;
|
||||
}
|
||||
}
|
||||
|
||||
void b2ContactSolver::SolveVelocityConstraints()
|
||||
{
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
|
||||
|
||||
int32 indexA = vc->indexA;
|
||||
int32 indexB = vc->indexB;
|
||||
float32 mA = vc->invMassA;
|
||||
float32 iA = vc->invIA;
|
||||
float32 mB = vc->invMassB;
|
||||
float32 iB = vc->invIB;
|
||||
int32 pointCount = vc->pointCount;
|
||||
|
||||
b2Vec2 vA = m_velocities[indexA].v;
|
||||
float32 wA = m_velocities[indexA].w;
|
||||
b2Vec2 vB = m_velocities[indexB].v;
|
||||
float32 wB = m_velocities[indexB].w;
|
||||
|
||||
b2Vec2 normal = vc->normal;
|
||||
b2Vec2 tangent = b2Cross(normal, 1.0f);
|
||||
float32 friction = vc->friction;
|
||||
|
||||
b2Assert(pointCount == 1 || pointCount == 2);
|
||||
|
||||
// Solve tangent constraints first because non-penetration is more important
|
||||
// than friction.
|
||||
for (int32 j = 0; j < pointCount; ++j)
|
||||
{
|
||||
b2VelocityConstraintPoint* vcp = vc->points + j;
|
||||
|
||||
// Relative velocity at contact
|
||||
b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
|
||||
|
||||
// Compute tangent force
|
||||
float32 vt = b2Dot(dv, tangent);
|
||||
float32 lambda = vcp->tangentMass * (-vt);
|
||||
|
||||
// b2Clamp the accumulated force
|
||||
float32 maxFriction = friction * vcp->normalImpulse;
|
||||
float32 newImpulse = b2Clamp(vcp->tangentImpulse + lambda, -maxFriction, maxFriction);
|
||||
lambda = newImpulse - vcp->tangentImpulse;
|
||||
vcp->tangentImpulse = newImpulse;
|
||||
|
||||
// Apply contact impulse
|
||||
b2Vec2 P = lambda * tangent;
|
||||
|
||||
vA -= mA * P;
|
||||
wA -= iA * b2Cross(vcp->rA, P);
|
||||
|
||||
vB += mB * P;
|
||||
wB += iB * b2Cross(vcp->rB, P);
|
||||
}
|
||||
|
||||
// Solve normal constraints
|
||||
if (vc->pointCount == 1)
|
||||
{
|
||||
b2VelocityConstraintPoint* vcp = vc->points + 0;
|
||||
|
||||
// Relative velocity at contact
|
||||
b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
|
||||
|
||||
// Compute normal impulse
|
||||
float32 vn = b2Dot(dv, normal);
|
||||
float32 lambda = -vcp->normalMass * (vn - vcp->velocityBias);
|
||||
|
||||
// b2Clamp the accumulated impulse
|
||||
float32 newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f);
|
||||
lambda = newImpulse - vcp->normalImpulse;
|
||||
vcp->normalImpulse = newImpulse;
|
||||
|
||||
// Apply contact impulse
|
||||
b2Vec2 P = lambda * normal;
|
||||
vA -= mA * P;
|
||||
wA -= iA * b2Cross(vcp->rA, P);
|
||||
|
||||
vB += mB * P;
|
||||
wB += iB * b2Cross(vcp->rB, P);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Block solver developed in collaboration with Dirk Gregorius (back in 01/07 on Box2D_Lite).
|
||||
// Build the mini LCP for this contact patch
|
||||
//
|
||||
// vn = A * x + b, vn >= 0, , vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2
|
||||
//
|
||||
// A = J * W * JT and J = ( -n, -r1 x n, n, r2 x n )
|
||||
// b = vn0 - velocityBias
|
||||
//
|
||||
// The system is solved using the "Total enumeration method" (s. Murty). The complementary constraint vn_i * x_i
|
||||
// implies that we must have in any solution either vn_i = 0 or x_i = 0. So for the 2D contact problem the cases
|
||||
// vn1 = 0 and vn2 = 0, x1 = 0 and x2 = 0, x1 = 0 and vn2 = 0, x2 = 0 and vn1 = 0 need to be tested. The first valid
|
||||
// solution that satisfies the problem is chosen.
|
||||
//
|
||||
// In order to account of the accumulated impulse 'a' (because of the iterative nature of the solver which only requires
|
||||
// that the accumulated impulse is clamped and not the incremental impulse) we change the impulse variable (x_i).
|
||||
//
|
||||
// Substitute:
|
||||
//
|
||||
// x = a + d
|
||||
//
|
||||
// a := old total impulse
|
||||
// x := new total impulse
|
||||
// d := incremental impulse
|
||||
//
|
||||
// For the current iteration we extend the formula for the incremental impulse
|
||||
// to compute the new total impulse:
|
||||
//
|
||||
// vn = A * d + b
|
||||
// = A * (x - a) + b
|
||||
// = A * x + b - A * a
|
||||
// = A * x + b'
|
||||
// b' = b - A * a;
|
||||
|
||||
b2VelocityConstraintPoint* cp1 = vc->points + 0;
|
||||
b2VelocityConstraintPoint* cp2 = vc->points + 1;
|
||||
|
||||
b2Vec2 a(cp1->normalImpulse, cp2->normalImpulse);
|
||||
b2Assert(a.x >= 0.0f && a.y >= 0.0f);
|
||||
|
||||
// Relative velocity at contact
|
||||
b2Vec2 dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
|
||||
b2Vec2 dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
|
||||
|
||||
// Compute normal velocity
|
||||
float32 vn1 = b2Dot(dv1, normal);
|
||||
float32 vn2 = b2Dot(dv2, normal);
|
||||
|
||||
b2Vec2 b;
|
||||
b.x = vn1 - cp1->velocityBias;
|
||||
b.y = vn2 - cp2->velocityBias;
|
||||
|
||||
// Compute b'
|
||||
b -= b2Mul(vc->K, a);
|
||||
|
||||
const float32 k_errorTol = 1e-3f;
|
||||
B2_NOT_USED(k_errorTol);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
//
|
||||
// Case 1: vn = 0
|
||||
//
|
||||
// 0 = A * x + b'
|
||||
//
|
||||
// Solve for x:
|
||||
//
|
||||
// x = - inv(A) * b'
|
||||
//
|
||||
b2Vec2 x = - b2Mul(vc->normalMass, b);
|
||||
|
||||
if (x.x >= 0.0f && x.y >= 0.0f)
|
||||
{
|
||||
// Get the incremental impulse
|
||||
b2Vec2 d = x - a;
|
||||
|
||||
// Apply incremental impulse
|
||||
b2Vec2 P1 = d.x * normal;
|
||||
b2Vec2 P2 = d.y * normal;
|
||||
vA -= mA * (P1 + P2);
|
||||
wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
|
||||
|
||||
vB += mB * (P1 + P2);
|
||||
wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
|
||||
|
||||
// Accumulate
|
||||
cp1->normalImpulse = x.x;
|
||||
cp2->normalImpulse = x.y;
|
||||
|
||||
#if B2_DEBUG_SOLVER == 1
|
||||
// Postconditions
|
||||
dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
|
||||
dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
|
||||
|
||||
// Compute normal velocity
|
||||
vn1 = b2Dot(dv1, normal);
|
||||
vn2 = b2Dot(dv2, normal);
|
||||
|
||||
b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol);
|
||||
b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Case 2: vn1 = 0 and x2 = 0
|
||||
//
|
||||
// 0 = a11 * x1 + a12 * 0 + b1'
|
||||
// vn2 = a21 * x1 + a22 * 0 + b2'
|
||||
//
|
||||
x.x = - cp1->normalMass * b.x;
|
||||
x.y = 0.0f;
|
||||
//vn1 = 0.0f;
|
||||
vn2 = vc->K.ex.y * x.x + b.y;
|
||||
|
||||
if (x.x >= 0.0f && vn2 >= 0.0f)
|
||||
{
|
||||
// Get the incremental impulse
|
||||
b2Vec2 d = x - a;
|
||||
|
||||
// Apply incremental impulse
|
||||
b2Vec2 P1 = d.x * normal;
|
||||
b2Vec2 P2 = d.y * normal;
|
||||
vA -= mA * (P1 + P2);
|
||||
wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
|
||||
|
||||
vB += mB * (P1 + P2);
|
||||
wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
|
||||
|
||||
// Accumulate
|
||||
cp1->normalImpulse = x.x;
|
||||
cp2->normalImpulse = x.y;
|
||||
|
||||
#if B2_DEBUG_SOLVER == 1
|
||||
// Postconditions
|
||||
dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
|
||||
|
||||
// Compute normal velocity
|
||||
vn1 = b2Dot(dv1, normal);
|
||||
|
||||
b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Case 3: vn2 = 0 and x1 = 0
|
||||
//
|
||||
// vn1 = a11 * 0 + a12 * x2 + b1'
|
||||
// 0 = a21 * 0 + a22 * x2 + b2'
|
||||
//
|
||||
x.x = 0.0f;
|
||||
x.y = - cp2->normalMass * b.y;
|
||||
vn1 = vc->K.ey.x * x.y + b.x;
|
||||
//vn2 = 0.0f;
|
||||
|
||||
if (x.y >= 0.0f && vn1 >= 0.0f)
|
||||
{
|
||||
// Resubstitute for the incremental impulse
|
||||
b2Vec2 d = x - a;
|
||||
|
||||
// Apply incremental impulse
|
||||
b2Vec2 P1 = d.x * normal;
|
||||
b2Vec2 P2 = d.y * normal;
|
||||
vA -= mA * (P1 + P2);
|
||||
wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
|
||||
|
||||
vB += mB * (P1 + P2);
|
||||
wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
|
||||
|
||||
// Accumulate
|
||||
cp1->normalImpulse = x.x;
|
||||
cp2->normalImpulse = x.y;
|
||||
|
||||
#if B2_DEBUG_SOLVER == 1
|
||||
// Postconditions
|
||||
dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
|
||||
|
||||
// Compute normal velocity
|
||||
vn2 = b2Dot(dv2, normal);
|
||||
|
||||
b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Case 4: x1 = 0 and x2 = 0
|
||||
//
|
||||
// vn1 = b1
|
||||
// vn2 = b2;
|
||||
x.x = 0.0f;
|
||||
x.y = 0.0f;
|
||||
vn1 = b.x;
|
||||
vn2 = b.y;
|
||||
|
||||
if (vn1 >= 0.0f && vn2 >= 0.0f )
|
||||
{
|
||||
// Resubstitute for the incremental impulse
|
||||
b2Vec2 d = x - a;
|
||||
|
||||
// Apply incremental impulse
|
||||
b2Vec2 P1 = d.x * normal;
|
||||
b2Vec2 P2 = d.y * normal;
|
||||
vA -= mA * (P1 + P2);
|
||||
wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
|
||||
|
||||
vB += mB * (P1 + P2);
|
||||
wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
|
||||
|
||||
// Accumulate
|
||||
cp1->normalImpulse = x.x;
|
||||
cp2->normalImpulse = x.y;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// No solution, give up. This is hit sometimes, but it doesn't seem to matter.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_velocities[indexA].v = vA;
|
||||
m_velocities[indexA].w = wA;
|
||||
m_velocities[indexB].v = vB;
|
||||
m_velocities[indexB].w = wB;
|
||||
}
|
||||
}
|
||||
|
||||
void b2ContactSolver::StoreImpulses()
|
||||
{
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
|
||||
b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold();
|
||||
|
||||
for (int32 j = 0; j < vc->pointCount; ++j)
|
||||
{
|
||||
manifold->points[j].normalImpulse = vc->points[j].normalImpulse;
|
||||
manifold->points[j].tangentImpulse = vc->points[j].tangentImpulse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct b2PositionSolverManifold
|
||||
{
|
||||
void Initialize(b2ContactPositionConstraint* pc, const b2Transform& xfA, const b2Transform& xfB, int32 index)
|
||||
{
|
||||
b2Assert(pc->pointCount > 0);
|
||||
|
||||
switch (pc->type)
|
||||
{
|
||||
case b2Manifold::e_circles:
|
||||
{
|
||||
b2Vec2 pointA = b2Mul(xfA, pc->localPoint);
|
||||
b2Vec2 pointB = b2Mul(xfB, pc->localPoints[0]);
|
||||
normal = pointB - pointA;
|
||||
normal.Normalize();
|
||||
point = 0.5f * (pointA + pointB);
|
||||
separation = b2Dot(pointB - pointA, normal) - pc->radiusA - pc->radiusB;
|
||||
}
|
||||
break;
|
||||
|
||||
case b2Manifold::e_faceA:
|
||||
{
|
||||
normal = b2Mul(xfA.q, pc->localNormal);
|
||||
b2Vec2 planePoint = b2Mul(xfA, pc->localPoint);
|
||||
|
||||
b2Vec2 clipPoint = b2Mul(xfB, pc->localPoints[index]);
|
||||
separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB;
|
||||
point = clipPoint;
|
||||
}
|
||||
break;
|
||||
|
||||
case b2Manifold::e_faceB:
|
||||
{
|
||||
normal = b2Mul(xfB.q, pc->localNormal);
|
||||
b2Vec2 planePoint = b2Mul(xfB, pc->localPoint);
|
||||
|
||||
b2Vec2 clipPoint = b2Mul(xfA, pc->localPoints[index]);
|
||||
separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB;
|
||||
point = clipPoint;
|
||||
|
||||
// Ensure normal points from A to B
|
||||
normal = -normal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
b2Vec2 normal;
|
||||
b2Vec2 point;
|
||||
float32 separation;
|
||||
};
|
||||
|
||||
// Sequential solver.
|
||||
bool b2ContactSolver::SolvePositionConstraints()
|
||||
{
|
||||
float32 minSeparation = 0.0f;
|
||||
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2ContactPositionConstraint* pc = m_positionConstraints + i;
|
||||
|
||||
int32 indexA = pc->indexA;
|
||||
int32 indexB = pc->indexB;
|
||||
b2Vec2 localCenterA = pc->localCenterA;
|
||||
float32 mA = pc->invMassA;
|
||||
float32 iA = pc->invIA;
|
||||
b2Vec2 localCenterB = pc->localCenterB;
|
||||
float32 mB = pc->invMassB;
|
||||
float32 iB = pc->invIB;
|
||||
int32 pointCount = pc->pointCount;
|
||||
|
||||
b2Vec2 cA = m_positions[indexA].c;
|
||||
float32 aA = m_positions[indexA].a;
|
||||
|
||||
b2Vec2 cB = m_positions[indexB].c;
|
||||
float32 aB = m_positions[indexB].a;
|
||||
|
||||
// Solve normal constraints
|
||||
for (int32 j = 0; j < pointCount; ++j)
|
||||
{
|
||||
b2Transform xfA, xfB;
|
||||
xfA.q.Set(aA);
|
||||
xfB.q.Set(aB);
|
||||
xfA.p = cA - b2Mul(xfA.q, localCenterA);
|
||||
xfB.p = cB - b2Mul(xfB.q, localCenterB);
|
||||
|
||||
b2PositionSolverManifold psm;
|
||||
psm.Initialize(pc, xfA, xfB, j);
|
||||
b2Vec2 normal = psm.normal;
|
||||
|
||||
b2Vec2 point = psm.point;
|
||||
float32 separation = psm.separation;
|
||||
|
||||
b2Vec2 rA = point - cA;
|
||||
b2Vec2 rB = point - cB;
|
||||
|
||||
// Track max constraint error.
|
||||
minSeparation = b2Min(minSeparation, separation);
|
||||
|
||||
// Prevent large corrections and allow slop.
|
||||
float32 C = b2Clamp(b2_baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f);
|
||||
|
||||
// Compute the effective mass.
|
||||
float32 rnA = b2Cross(rA, normal);
|
||||
float32 rnB = b2Cross(rB, normal);
|
||||
float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
|
||||
|
||||
// Compute normal impulse
|
||||
float32 impulse = K > 0.0f ? - C / K : 0.0f;
|
||||
|
||||
b2Vec2 P = impulse * normal;
|
||||
|
||||
cA -= mA * P;
|
||||
aA -= iA * b2Cross(rA, P);
|
||||
|
||||
cB += mB * P;
|
||||
aB += iB * b2Cross(rB, P);
|
||||
}
|
||||
|
||||
m_positions[indexA].c = cA;
|
||||
m_positions[indexA].a = aA;
|
||||
|
||||
m_positions[indexB].c = cB;
|
||||
m_positions[indexB].a = aB;
|
||||
}
|
||||
|
||||
// We can't expect minSpeparation >= -b2_linearSlop because we don't
|
||||
// push the separation above -b2_linearSlop.
|
||||
return minSeparation >= -3.0f * b2_linearSlop;
|
||||
}
|
||||
|
||||
// Sequential position solver for position constraints.
|
||||
bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB)
|
||||
{
|
||||
float32 minSeparation = 0.0f;
|
||||
|
||||
for (int32 i = 0; i < m_count; ++i)
|
||||
{
|
||||
b2ContactPositionConstraint* pc = m_positionConstraints + i;
|
||||
|
||||
int32 indexA = pc->indexA;
|
||||
int32 indexB = pc->indexB;
|
||||
b2Vec2 localCenterA = pc->localCenterA;
|
||||
b2Vec2 localCenterB = pc->localCenterB;
|
||||
int32 pointCount = pc->pointCount;
|
||||
|
||||
float32 mA = 0.0f;
|
||||
float32 iA = 0.0f;
|
||||
if (indexA == toiIndexA || indexA == toiIndexB)
|
||||
{
|
||||
mA = pc->invMassA;
|
||||
iA = pc->invIA;
|
||||
}
|
||||
|
||||
float32 mB = pc->invMassB;
|
||||
float32 iB = pc->invIB;
|
||||
if (indexB == toiIndexA || indexB == toiIndexB)
|
||||
{
|
||||
mB = pc->invMassB;
|
||||
iB = pc->invIB;
|
||||
}
|
||||
|
||||
b2Vec2 cA = m_positions[indexA].c;
|
||||
float32 aA = m_positions[indexA].a;
|
||||
|
||||
b2Vec2 cB = m_positions[indexB].c;
|
||||
float32 aB = m_positions[indexB].a;
|
||||
|
||||
// Solve normal constraints
|
||||
for (int32 j = 0; j < pointCount; ++j)
|
||||
{
|
||||
b2Transform xfA, xfB;
|
||||
xfA.q.Set(aA);
|
||||
xfB.q.Set(aB);
|
||||
xfA.p = cA - b2Mul(xfA.q, localCenterA);
|
||||
xfB.p = cB - b2Mul(xfB.q, localCenterB);
|
||||
|
||||
b2PositionSolverManifold psm;
|
||||
psm.Initialize(pc, xfA, xfB, j);
|
||||
b2Vec2 normal = psm.normal;
|
||||
|
||||
b2Vec2 point = psm.point;
|
||||
float32 separation = psm.separation;
|
||||
|
||||
b2Vec2 rA = point - cA;
|
||||
b2Vec2 rB = point - cB;
|
||||
|
||||
// Track max constraint error.
|
||||
minSeparation = b2Min(minSeparation, separation);
|
||||
|
||||
// Prevent large corrections and allow slop.
|
||||
float32 C = b2Clamp(b2_toiBaugarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f);
|
||||
|
||||
// Compute the effective mass.
|
||||
float32 rnA = b2Cross(rA, normal);
|
||||
float32 rnB = b2Cross(rB, normal);
|
||||
float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
|
||||
|
||||
// Compute normal impulse
|
||||
float32 impulse = K > 0.0f ? - C / K : 0.0f;
|
||||
|
||||
b2Vec2 P = impulse * normal;
|
||||
|
||||
cA -= mA * P;
|
||||
aA -= iA * b2Cross(rA, P);
|
||||
|
||||
cB += mB * P;
|
||||
aB += iB * b2Cross(rB, P);
|
||||
}
|
||||
|
||||
m_positions[indexA].c = cA;
|
||||
m_positions[indexA].a = aA;
|
||||
|
||||
m_positions[indexB].c = cB;
|
||||
m_positions[indexB].a = aB;
|
||||
}
|
||||
|
||||
// We can't expect minSpeparation >= -b2_linearSlop because we don't
|
||||
// push the separation above -b2_linearSlop.
|
||||
return minSeparation >= -1.5f * b2_linearSlop;
|
||||
}
|
93
modules/juce_box2d/box2d/Dynamics/Contacts/b2ContactSolver.h
Normal file
93
modules/juce_box2d/box2d/Dynamics/Contacts/b2ContactSolver.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_CONTACT_SOLVER_H
|
||||
#define B2_CONTACT_SOLVER_H
|
||||
|
||||
#include "../../Common/b2Math.h"
|
||||
#include "../../Collision/b2Collision.h"
|
||||
#include "../b2TimeStep.h"
|
||||
|
||||
class b2Contact;
|
||||
class b2Body;
|
||||
class b2StackAllocator;
|
||||
struct b2ContactPositionConstraint;
|
||||
|
||||
struct b2VelocityConstraintPoint
|
||||
{
|
||||
b2Vec2 rA;
|
||||
b2Vec2 rB;
|
||||
float32 normalImpulse;
|
||||
float32 tangentImpulse;
|
||||
float32 normalMass;
|
||||
float32 tangentMass;
|
||||
float32 velocityBias;
|
||||
};
|
||||
|
||||
struct b2ContactVelocityConstraint
|
||||
{
|
||||
b2VelocityConstraintPoint points[b2_maxManifoldPoints];
|
||||
b2Vec2 normal;
|
||||
b2Mat22 normalMass;
|
||||
b2Mat22 K;
|
||||
int32 indexA;
|
||||
int32 indexB;
|
||||
float32 invMassA, invMassB;
|
||||
float32 invIA, invIB;
|
||||
float32 friction;
|
||||
float32 restitution;
|
||||
int32 pointCount;
|
||||
int32 contactIndex;
|
||||
};
|
||||
|
||||
struct b2ContactSolverDef
|
||||
{
|
||||
b2TimeStep step;
|
||||
b2Contact** contacts;
|
||||
int32 count;
|
||||
b2Position* positions;
|
||||
b2Velocity* velocities;
|
||||
b2StackAllocator* allocator;
|
||||
};
|
||||
|
||||
class b2ContactSolver
|
||||
{
|
||||
public:
|
||||
b2ContactSolver(b2ContactSolverDef* def);
|
||||
~b2ContactSolver();
|
||||
|
||||
void InitializeVelocityConstraints();
|
||||
|
||||
void WarmStart();
|
||||
void SolveVelocityConstraints();
|
||||
void StoreImpulses();
|
||||
|
||||
bool SolvePositionConstraints();
|
||||
bool SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB);
|
||||
|
||||
b2TimeStep m_step;
|
||||
b2Position* m_positions;
|
||||
b2Velocity* m_velocities;
|
||||
b2StackAllocator* m_allocator;
|
||||
b2ContactPositionConstraint* m_positionConstraints;
|
||||
b2ContactVelocityConstraint* m_velocityConstraints;
|
||||
b2Contact** m_contacts;
|
||||
int m_count;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2EdgeAndCircleContact.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../b2Fixture.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2EdgeAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2EdgeAndCircleContact));
|
||||
return new (mem) b2EdgeAndCircleContact(fixtureA, fixtureB);
|
||||
}
|
||||
|
||||
void b2EdgeAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2EdgeAndCircleContact*)contact)->~b2EdgeAndCircleContact();
|
||||
allocator->Free(contact, sizeof(b2EdgeAndCircleContact));
|
||||
}
|
||||
|
||||
b2EdgeAndCircleContact::b2EdgeAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
|
||||
: b2Contact(fixtureA, 0, fixtureB, 0)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_edge);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
|
||||
}
|
||||
|
||||
void b2EdgeAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2CollideEdgeAndCircle( manifold,
|
||||
(b2EdgeShape*)m_fixtureA->GetShape(), xfA,
|
||||
(b2CircleShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_EDGE_AND_CIRCLE_CONTACT_H
|
||||
#define B2_EDGE_AND_CIRCLE_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2EdgeAndCircleContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create( b2Fixture* fixtureA, int32 indexA,
|
||||
b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2EdgeAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
|
||||
~b2EdgeAndCircleContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2EdgeAndPolygonContact.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../b2Fixture.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2EdgeAndPolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2EdgeAndPolygonContact));
|
||||
return new (mem) b2EdgeAndPolygonContact(fixtureA, fixtureB);
|
||||
}
|
||||
|
||||
void b2EdgeAndPolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2EdgeAndPolygonContact*)contact)->~b2EdgeAndPolygonContact();
|
||||
allocator->Free(contact, sizeof(b2EdgeAndPolygonContact));
|
||||
}
|
||||
|
||||
b2EdgeAndPolygonContact::b2EdgeAndPolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
|
||||
: b2Contact(fixtureA, 0, fixtureB, 0)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_edge);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon);
|
||||
}
|
||||
|
||||
void b2EdgeAndPolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2CollideEdgeAndPolygon( manifold,
|
||||
(b2EdgeShape*)m_fixtureA->GetShape(), xfA,
|
||||
(b2PolygonShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_EDGE_AND_POLYGON_CONTACT_H
|
||||
#define B2_EDGE_AND_POLYGON_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2EdgeAndPolygonContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create( b2Fixture* fixtureA, int32 indexA,
|
||||
b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2EdgeAndPolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
|
||||
~b2EdgeAndPolygonContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2PolygonAndCircleContact.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../b2Fixture.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2PolygonAndCircleContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2PolygonAndCircleContact));
|
||||
return new (mem) b2PolygonAndCircleContact(fixtureA, fixtureB);
|
||||
}
|
||||
|
||||
void b2PolygonAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2PolygonAndCircleContact*)contact)->~b2PolygonAndCircleContact();
|
||||
allocator->Free(contact, sizeof(b2PolygonAndCircleContact));
|
||||
}
|
||||
|
||||
b2PolygonAndCircleContact::b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
|
||||
: b2Contact(fixtureA, 0, fixtureB, 0)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
|
||||
}
|
||||
|
||||
void b2PolygonAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2CollidePolygonAndCircle( manifold,
|
||||
(b2PolygonShape*)m_fixtureA->GetShape(), xfA,
|
||||
(b2CircleShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_POLYGON_AND_CIRCLE_CONTACT_H
|
||||
#define B2_POLYGON_AND_CIRCLE_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2PolygonAndCircleContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2PolygonAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
|
||||
~b2PolygonAndCircleContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "b2PolygonContact.h"
|
||||
#include "../../Common/b2BlockAllocator.h"
|
||||
#include "../../Collision/b2TimeOfImpact.h"
|
||||
#include "../b2Body.h"
|
||||
#include "../b2Fixture.h"
|
||||
#include "../b2WorldCallbacks.h"
|
||||
|
||||
#include <new>
|
||||
using namespace std;
|
||||
|
||||
b2Contact* b2PolygonContact::Create(b2Fixture* fixtureA, int32, b2Fixture* fixtureB, int32, b2BlockAllocator* allocator)
|
||||
{
|
||||
void* mem = allocator->Allocate(sizeof(b2PolygonContact));
|
||||
return new (mem) b2PolygonContact(fixtureA, fixtureB);
|
||||
}
|
||||
|
||||
void b2PolygonContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
|
||||
{
|
||||
((b2PolygonContact*)contact)->~b2PolygonContact();
|
||||
allocator->Free(contact, sizeof(b2PolygonContact));
|
||||
}
|
||||
|
||||
b2PolygonContact::b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
|
||||
: b2Contact(fixtureA, 0, fixtureB, 0)
|
||||
{
|
||||
b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon);
|
||||
b2Assert(m_fixtureB->GetType() == b2Shape::e_polygon);
|
||||
}
|
||||
|
||||
void b2PolygonContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
|
||||
{
|
||||
b2CollidePolygons( manifold,
|
||||
(b2PolygonShape*)m_fixtureA->GetShape(), xfA,
|
||||
(b2PolygonShape*)m_fixtureB->GetShape(), xfB);
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
|
||||
*
|
||||
* 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 B2_POLYGON_CONTACT_H
|
||||
#define B2_POLYGON_CONTACT_H
|
||||
|
||||
#include "b2Contact.h"
|
||||
|
||||
class b2BlockAllocator;
|
||||
|
||||
class b2PolygonContact : public b2Contact
|
||||
{
|
||||
public:
|
||||
static b2Contact* Create( b2Fixture* fixtureA, int32 indexA,
|
||||
b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
|
||||
static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
|
||||
|
||||
b2PolygonContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
|
||||
~b2PolygonContact() {}
|
||||
|
||||
void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user