|
|
@@ -46,6 +46,21 @@ static const Vector2 DEFAULT_GRAVITY(0.0f, -9.81f);
|
|
|
static const int DEFAULT_VELOCITY_ITERATIONS = 8;
|
|
|
static const int DEFAULT_POSITION_ITERATIONS = 3;
|
|
|
|
|
|
+// Helper function to write contact info into buffer.
|
|
|
+const PODVector<unsigned char>& WriteContactInfo(VectorBuffer& buffer, b2Contact* contact)
|
|
|
+{
|
|
|
+ buffer.Clear();
|
|
|
+ b2WorldManifold worldManifold;
|
|
|
+ contact->GetWorldManifold(&worldManifold);
|
|
|
+ for (int i = 0; i < contact->GetManifold()->pointCount; ++i)
|
|
|
+ {
|
|
|
+ buffer.WriteVector2(Vector2(worldManifold.points[i].x, worldManifold.points[i].y));
|
|
|
+ buffer.WriteVector2(Vector2(worldManifold.normal.x, worldManifold.normal.y));
|
|
|
+ buffer.WriteFloat(worldManifold.separations[i]);
|
|
|
+ }
|
|
|
+ return buffer.GetBuffer();
|
|
|
+}
|
|
|
+
|
|
|
PhysicsWorld2D::PhysicsWorld2D(Context* context) :
|
|
|
Component(context),
|
|
|
gravity_(DEFAULT_GRAVITY),
|
|
|
@@ -135,6 +150,63 @@ void PhysicsWorld2D::EndContact(b2Contact* contact)
|
|
|
endContactInfos_.Push(ContactInfo(contact));
|
|
|
}
|
|
|
|
|
|
+void PhysicsWorld2D::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
|
|
|
+{
|
|
|
+ b2Fixture* fixtureA = contact->GetFixtureA();
|
|
|
+ b2Fixture* fixtureB = contact->GetFixtureB();
|
|
|
+ if (!fixtureA || !fixtureB)
|
|
|
+ return;
|
|
|
+
|
|
|
+ ContactInfo contactInfo(contact);
|
|
|
+
|
|
|
+ // Send global event
|
|
|
+ VariantMap& eventData = GetEventDataMap();
|
|
|
+ eventData[PhysicsUpdateContact2D::P_WORLD] = this;
|
|
|
+ eventData[PhysicsUpdateContact2D::P_ENABLED] = contact->IsEnabled();
|
|
|
+
|
|
|
+ eventData[PhysicsUpdateContact2D::P_BODYA] = contactInfo.bodyA_.Get();
|
|
|
+ eventData[PhysicsUpdateContact2D::P_BODYB] = contactInfo.bodyB_.Get();
|
|
|
+ eventData[PhysicsUpdateContact2D::P_NODEA] = contactInfo.nodeA_.Get();
|
|
|
+ eventData[PhysicsUpdateContact2D::P_NODEB] = contactInfo.nodeB_.Get();
|
|
|
+ eventData[PhysicsUpdateContact2D::P_CONTACT] = (void*)contactInfo.contact_;
|
|
|
+ eventData[PhysicsUpdateContact2D::P_CONTACTPOINTS] = WriteContactInfo(contacts_, contactInfo.contact_);
|
|
|
+ eventData[PhysicsUpdateContact2D::P_SHAPEA] = contactInfo.shapeA_.Get();
|
|
|
+ eventData[PhysicsUpdateContact2D::P_SHAPEB] = contactInfo.shapeB_.Get();
|
|
|
+
|
|
|
+ SendEvent(E_PHYSICSUPDATECONTACT2D, eventData);
|
|
|
+ contact->SetEnabled(eventData[PhysicsUpdateContact2D::P_ENABLED].GetBool());
|
|
|
+ eventData.Clear();
|
|
|
+
|
|
|
+ // Send node event
|
|
|
+ eventData[NodeUpdateContact2D::P_ENABLED] = contact->IsEnabled();
|
|
|
+ eventData[NodeUpdateContact2D::P_CONTACT] = (void*)contactInfo.contact_;
|
|
|
+ eventData[NodeUpdateContact2D::P_CONTACTPOINTS] = WriteContactInfo(contacts_, contactInfo.contact_);
|
|
|
+
|
|
|
+ if (contactInfo.nodeA_)
|
|
|
+ {
|
|
|
+ eventData[NodeUpdateContact2D::P_BODY] = contactInfo.bodyA_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_OTHERNODE] = contactInfo.nodeB_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_OTHERBODY] = contactInfo.bodyB_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_SHAPE] = contactInfo.shapeA_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_OTHERSHAPE] = contactInfo.shapeB_.Get();
|
|
|
+
|
|
|
+ contactInfo.nodeA_->SendEvent(E_NODEUPDATECONTACT2D, eventData);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (contactInfo.nodeB_)
|
|
|
+ {
|
|
|
+ eventData[NodeUpdateContact2D::P_BODY] = contactInfo.bodyB_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_OTHERNODE] = contactInfo.nodeA_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_OTHERBODY] = contactInfo.bodyA_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_SHAPE] = contactInfo.shapeB_.Get();
|
|
|
+ eventData[NodeUpdateContact2D::P_OTHERSHAPE] = contactInfo.shapeA_.Get();
|
|
|
+
|
|
|
+ contactInfo.nodeB_->SendEvent(E_NODEUPDATECONTACT2D, eventData);
|
|
|
+ }
|
|
|
+
|
|
|
+ contact->SetEnabled(eventData[NodeUpdateContact2D::P_ENABLED].GetBool());
|
|
|
+}
|
|
|
+
|
|
|
void PhysicsWorld2D::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
|
|
|
{
|
|
|
if (!debugRenderer_)
|
|
|
@@ -687,12 +759,14 @@ void PhysicsWorld2D::SendBeginContactEvents()
|
|
|
eventData[P_NODEA] = contactInfo.nodeA_.Get();
|
|
|
eventData[P_NODEB] = contactInfo.nodeB_.Get();
|
|
|
eventData[P_CONTACT] = (void*)contactInfo.contact_;
|
|
|
+ eventData[P_CONTACTPOINTS] = WriteContactInfo(contacts_, contactInfo.contact_);
|
|
|
eventData[P_SHAPEA] = contactInfo.shapeA_.Get();
|
|
|
eventData[P_SHAPEB] = contactInfo.shapeB_.Get();
|
|
|
|
|
|
SendEvent(E_PHYSICSBEGINCONTACT2D, eventData);
|
|
|
|
|
|
nodeEventData[NodeBeginContact2D::P_CONTACT] = (void*)contactInfo.contact_;
|
|
|
+ nodeEventData[NodeBeginContact2D::P_CONTACTPOINTS] = WriteContactInfo(contacts_, contactInfo.contact_);
|
|
|
|
|
|
if (contactInfo.nodeA_)
|
|
|
{
|
|
|
@@ -738,20 +812,22 @@ void PhysicsWorld2D::SendEndContactEvents()
|
|
|
eventData[P_NODEA] = contactInfo.nodeA_.Get();
|
|
|
eventData[P_NODEB] = contactInfo.nodeB_.Get();
|
|
|
eventData[P_CONTACT] = (void*)contactInfo.contact_;
|
|
|
+ eventData[P_CONTACTPOINTS] = WriteContactInfo(contacts_, contactInfo.contact_);
|
|
|
eventData[P_SHAPEA] = contactInfo.shapeA_.Get();
|
|
|
eventData[P_SHAPEB] = contactInfo.shapeB_.Get();
|
|
|
|
|
|
SendEvent(E_PHYSICSENDCONTACT2D, eventData);
|
|
|
|
|
|
nodeEventData[NodeEndContact2D::P_CONTACT] = (void*)contactInfo.contact_;
|
|
|
+ nodeEventData[NodeEndContact2D::P_CONTACTPOINTS] = WriteContactInfo(contacts_, contactInfo.contact_);
|
|
|
|
|
|
if (contactInfo.nodeA_)
|
|
|
{
|
|
|
nodeEventData[NodeEndContact2D::P_BODY] = contactInfo.bodyA_.Get();
|
|
|
nodeEventData[NodeEndContact2D::P_OTHERNODE] = contactInfo.nodeB_.Get();
|
|
|
nodeEventData[NodeEndContact2D::P_OTHERBODY] = contactInfo.bodyB_.Get();
|
|
|
- nodeEventData[NodeBeginContact2D::P_SHAPE] = contactInfo.shapeA_.Get();
|
|
|
- nodeEventData[NodeBeginContact2D::P_OTHERSHAPE] = contactInfo.shapeB_.Get();
|
|
|
+ nodeEventData[NodeEndContact2D::P_SHAPE] = contactInfo.shapeA_.Get();
|
|
|
+ nodeEventData[NodeEndContact2D::P_OTHERSHAPE] = contactInfo.shapeB_.Get();
|
|
|
|
|
|
contactInfo.nodeA_->SendEvent(E_NODEENDCONTACT2D, nodeEventData);
|
|
|
}
|
|
|
@@ -761,8 +837,8 @@ void PhysicsWorld2D::SendEndContactEvents()
|
|
|
nodeEventData[NodeEndContact2D::P_BODY] = contactInfo.bodyB_.Get();
|
|
|
nodeEventData[NodeEndContact2D::P_OTHERNODE] = contactInfo.nodeA_.Get();
|
|
|
nodeEventData[NodeEndContact2D::P_OTHERBODY] = contactInfo.bodyA_.Get();
|
|
|
- nodeEventData[NodeBeginContact2D::P_SHAPE] = contactInfo.shapeB_.Get();
|
|
|
- nodeEventData[NodeBeginContact2D::P_OTHERSHAPE] = contactInfo.shapeA_.Get();
|
|
|
+ nodeEventData[NodeEndContact2D::P_SHAPE] = contactInfo.shapeB_.Get();
|
|
|
+ nodeEventData[NodeEndContact2D::P_OTHERSHAPE] = contactInfo.shapeA_.Get();
|
|
|
|
|
|
contactInfo.nodeB_->SendEvent(E_NODEENDCONTACT2D, nodeEventData);
|
|
|
}
|