Back to project page flingbox.
The source code is released under:
GNU General Public License
If you think the Android project flingbox listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * Flingbox - An OpenSource physics sandbox for Google's Android * Copyright (C) 2009 Jon Ander Pealba & Endika Gutirrez *//from w w w . ja v a 2 s.c o m * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package edu.eside.flingbox.physics.collisions; import java.util.ArrayList; import java.util.Collections; import java.util.ConcurrentModificationException; import android.util.Log; import edu.eside.flingbox.physics.PhysicBody; import edu.eside.flingbox.utils.PositionComparator; /** * Arbiter manages the collisions between bodies */ public class Arbiter { /** List with all colliders on the scene */ private final ArrayList<Collider> mCollisionableBodies = new ArrayList<Collider>(); /** Adds new collider to the arbiter */ public void add(final Collider collider) { mCollisionableBodies.add(collider); } /** Removes a collider from the arbiter */ public boolean remove(final Collider collider) { return mCollisionableBodies.remove(collider); } /** * Checks collision between bodies that are managed by the arbiter. * * @return number of collisions */ public void checkCollisions() { final ArrayList<Collider> bodies = mCollisionableBodies; final ArrayList<Contact> contactsToSolve = new ArrayList<Contact>(); final int bodiesCount = bodies.size(); /* Start checking movable objects */ for (int i = bodiesCount - 1; i >= 0; i--) for (int j = i - 1; j >= 0; j--) { Contact[] contacts = bodies.get(i).checkContacts(bodies.get(j)); for (Contact contact : contacts) contactsToSolve.add(contact); } /* Sort contacts to solve those */ Collections.sort(contactsToSolve, PositionComparator.UPPER_COMPARATOR); final ArrayList<Contact> isolatedContactTree = new ArrayList<Contact>(); while (!contactsToSolve.isEmpty()) { isolatedContactTree.clear(); Contact treeRoot = contactsToSolve.get(0); // get top contact contactsToSolve.remove(0); isolatedContactTree.add(treeRoot); getIsolatedContactsTree(treeRoot.collidedBody, contactsToSolve, isolatedContactTree); getIsolatedContactsTree(treeRoot.collidingBody, contactsToSolve, isolatedContactTree); solveIsolatedContactTree(isolatedContactTree); } } private void solveIsolatedContactTree( final ArrayList<Contact> isolatedContacts) { // Vector2D totalImpulse = new Vector2D(); for (Contact contact : isolatedContacts) { ContactSolver.solveCollision(contact); ContactSolver.solvePenetration(contact); } for (int i = isolatedContacts.size() - 2; i >= 0; i--) { ContactSolver.solveCollision(isolatedContacts.get(i)); ContactSolver.solvePenetration(isolatedContacts.get(i)); } } private void getIsolatedContactsTree(final PhysicBody rootBody, final ArrayList<Contact> contacts, ArrayList<Contact> isolatedContacts) { try { for (int i = 0; i < contacts.size(); i++) { Contact contact = contacts.get(i); if (contact.concerns(rootBody)) { contacts.remove(contact); i--; isolatedContacts.add(contact); getIsolatedContactsTree(contact.otherBody(rootBody), contacts, isolatedContacts); } } } catch (ConcurrentModificationException ex) { Log .e( "flingbox", "ConcurrentModificationException getting isolated contacts tree", ex); } } }