use of com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactEdge in project FXGL by AlmasB.
the class Fixture method refilter.
/**
* Call this if you want to establish collision that was previously disabled by
* ContactFilter::ShouldCollide.
*/
public void refilter() {
// Flag associated contacts for filtering.
ContactEdge edge = body.getContactList();
while (edge != null) {
Contact contact = edge.contact;
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
if (fixtureA == this || fixtureB == this) {
contact.flagForFiltering();
}
edge = edge.next;
}
World world = body.getWorld();
if (world == null) {
return;
}
// Touch each proxy so that new pairs may be created
BroadPhase broadPhase = world.getContactManager().broadPhase;
for (int i = 0; i < proxyCount; ++i) {
broadPhase.touchProxy(proxies[i].proxyId);
}
}
use of com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactEdge in project FXGL by AlmasB.
the class World method destroyJoint.
/**
* Destroy a joint. This may cause the connected bodies to begin colliding.
* This function is locked during callbacks.
*
* @param j joint
*/
public void destroyJoint(Joint j) {
assertNotLocked();
boolean collideConnected = j.getCollideConnected();
// Remove from the doubly linked list.
if (j.m_prev != null) {
j.m_prev.m_next = j.m_next;
}
if (j.m_next != null) {
j.m_next.m_prev = j.m_prev;
}
if (j == m_jointList) {
m_jointList = j.m_next;
}
// Disconnect from island graph.
Body bodyA = j.getBodyA();
Body bodyB = j.getBodyB();
// Wake up connected bodies.
bodyA.setAwake(true);
bodyB.setAwake(true);
// Remove from body 1.
if (j.m_edgeA.prev != null) {
j.m_edgeA.prev.next = j.m_edgeA.next;
}
if (j.m_edgeA.next != null) {
j.m_edgeA.next.prev = j.m_edgeA.prev;
}
if (j.m_edgeA == bodyA.m_jointList) {
bodyA.m_jointList = j.m_edgeA.next;
}
j.m_edgeA.prev = null;
j.m_edgeA.next = null;
// Remove from body 2
if (j.m_edgeB.prev != null) {
j.m_edgeB.prev.next = j.m_edgeB.next;
}
if (j.m_edgeB.next != null) {
j.m_edgeB.next.prev = j.m_edgeB.prev;
}
if (j.m_edgeB == bodyB.m_jointList) {
bodyB.m_jointList = j.m_edgeB.next;
}
j.m_edgeB.prev = null;
j.m_edgeB.next = null;
Joint.destroy(j);
assert (jointCount > 0);
--jointCount;
// If the joint prevents collisions, then flag any contacts for filtering.
if (!collideConnected) {
ContactEdge edge = bodyB.getContactList();
while (edge != null) {
if (edge.other == bodyA) {
// Flag the contact for filtering at the next time step (where either body is awake).
edge.contact.flagForFiltering();
}
edge = edge.next;
}
}
}
use of com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactEdge in project FXGL by AlmasB.
the class World method solve.
private void solve(TimeStep step) {
// update previous transforms
for (Body b : bodies) {
b.m_xf0.set(b.m_xf);
}
// Size the island for the worst case.
island.init(getBodyCount(), contactManager.contactCount, jointCount, contactManager.getContactListener());
// Clear all the island flags.
for (Body b : bodies) {
b.m_flags &= ~Body.e_islandFlag;
}
for (Contact c = contactManager.contactList; c != null; c = c.m_next) {
c.m_flags &= ~Contact.ISLAND_FLAG;
}
for (Joint j = m_jointList; j != null; j = j.m_next) {
j.m_islandFlag = false;
}
// Build and simulate all awake islands.
int stackSize = getBodyCount();
if (stack.length < stackSize) {
stack = new Body[stackSize];
}
for (Body seed : bodies) {
if ((seed.m_flags & Body.e_islandFlag) == Body.e_islandFlag) {
continue;
}
if (!seed.isAwake() || !seed.isActive()) {
continue;
}
// The seed can be dynamic or kinematic.
if (seed.getType() == BodyType.STATIC) {
continue;
}
// Reset island and stack.
island.clear();
int stackCount = 0;
stack[stackCount++] = seed;
seed.m_flags |= Body.e_islandFlag;
// Perform a depth first search (DFS) on the constraint graph.
while (stackCount > 0) {
// Grab the next body off the stack and add it to the island.
Body b = stack[--stackCount];
assert (b.isActive());
island.add(b);
// Make sure the body is awake.
b.setAwake(true);
// propagate islands across static bodies.
if (b.getType() == BodyType.STATIC) {
continue;
}
// Search all contacts connected to this body.
for (ContactEdge ce = b.m_contactList; ce != null; ce = ce.next) {
Contact contact = ce.contact;
// Has this contact already been added to an island?
if ((contact.m_flags & Contact.ISLAND_FLAG) == Contact.ISLAND_FLAG) {
continue;
}
// Is this contact solid and touching?
if (!contact.isEnabled() || !contact.isTouching()) {
continue;
}
// Skip sensors.
boolean sensorA = contact.m_fixtureA.isSensor();
boolean sensorB = contact.m_fixtureB.isSensor();
if (sensorA || sensorB) {
continue;
}
island.add(contact);
contact.m_flags |= Contact.ISLAND_FLAG;
Body other = ce.other;
// Was the other body already added to this island?
if ((other.m_flags & Body.e_islandFlag) == Body.e_islandFlag) {
continue;
}
assert (stackCount < stackSize);
stack[stackCount++] = other;
other.m_flags |= Body.e_islandFlag;
}
// Search all joints connect to this body.
for (JointEdge je = b.m_jointList; je != null; je = je.next) {
if (je.joint.m_islandFlag) {
continue;
}
Body other = je.other;
// Don't simulate joints connected to inactive bodies.
if (!other.isActive()) {
continue;
}
island.add(je.joint);
je.joint.m_islandFlag = true;
if ((other.m_flags & Body.e_islandFlag) == Body.e_islandFlag) {
continue;
}
assert (stackCount < stackSize);
stack[stackCount++] = other;
other.m_flags |= Body.e_islandFlag;
}
}
island.solve(step, gravity, allowSleep);
// Post solve cleanup.
for (int i = 0; i < island.m_bodyCount; ++i) {
// Allow static bodies to participate in other islands.
Body b = island.m_bodies[i];
if (b.getType() == BodyType.STATIC) {
b.m_flags &= ~Body.e_islandFlag;
}
}
}
// Synchronize fixtures, check for out of range bodies.
for (Body b : bodies) {
// If a body was not in an island then it did not move.
if ((b.m_flags & Body.e_islandFlag) == 0) {
continue;
}
if (b.getType() == BodyType.STATIC) {
continue;
}
// Update fixtures (for broad-phase).
b.synchronizeFixtures();
}
// Look for new contacts.
contactManager.findNewContacts();
}
use of com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactEdge in project FXGL by AlmasB.
the class Body method destroyAttachedContacts.
private void destroyAttachedContacts() {
// Delete the attached contacts.
ContactEdge ce = m_contactList;
while (ce != null) {
ContactEdge ce0 = ce;
ce = ce.next;
world.getContactManager().destroy(ce0.contact);
}
m_contactList = null;
}
use of com.almasb.fxgl.physics.box2d.dynamics.contacts.ContactEdge in project FXGL by AlmasB.
the class World method destroyBody.
/**
* Destroy a rigid body.
* This automatically deletes all associated shapes and joints.
* This function is locked during callbacks.
*
* @param body body to destroy
*/
public void destroyBody(Body body) {
assert bodies.contains(body, true);
assertNotLocked();
// Delete the attached joints.
JointEdge je = body.m_jointList;
while (je != null) {
JointEdge je0 = je;
je = je.next;
if (destructionListener != null) {
destructionListener.onDestroy(je0.joint);
}
destroyJoint(je0.joint);
body.m_jointList = je;
}
body.m_jointList = null;
// Delete the attached contacts.
ContactEdge ce = body.m_contactList;
while (ce != null) {
ContactEdge ce0 = ce;
ce = ce.next;
contactManager.destroy(ce0.contact);
}
body.m_contactList = null;
for (Fixture f : body.getFixtures()) {
if (destructionListener != null) {
destructionListener.onDestroy(f);
}
f.destroyProxies(contactManager.broadPhase);
f.destroy();
// jbox2dTODO djm recycle fixtures (here or in that destroy method)
}
body.getFixtures().clear();
bodies.removeValueByIdentity(body);
// jbox2dTODO djm recycle body
}
Aggregations