/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.tests.bullet;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObjectWrapper;
import com.badlogic.gdx.physics.bullet.collision.ContactResultCallback;
import com.badlogic.gdx.physics.bullet.collision.btManifoldPoint;
import com.badlogic.gdx.physics.bullet.collision.btPersistentManifold;
import com.badlogic.gdx.tests.bullet.CollisionWorldTest.TestContactResultCallback;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
/** @author Xoppa */
public class CollisionTest extends ShootTest {
BulletEntity projectile;
Array<BulletEntity> hits = new Array<BulletEntity>();
Array<BulletEntity> contacts = new Array<BulletEntity>();
Array<Color> colors = new Array<Color>();
public class TestContactResultCallback extends ContactResultCallback {
@Override
public float addSingleResult (btManifoldPoint cp, btCollisionObjectWrapper colObj0Wrap, int partId0, int index0,
btCollisionObjectWrapper colObj1Wrap, int partId1, int index1) {
btCollisionObject other = colObj0Wrap.getCollisionObject() == projectile.body ? colObj1Wrap.getCollisionObject()
: colObj0Wrap.getCollisionObject();
if (other != null && other.userData != null && other.userData instanceof BulletEntity) {
BulletEntity ent = (BulletEntity)other.userData;
if (ent != ground && !hits.contains(ent, true)) hits.add((BulletEntity)other.userData);
}
return 0f;
}
}
TestContactResultCallback contactCB;
public void updateContactInfo () {
int n = world.dispatcher.getNumManifolds();
for (int i = 0; i < n; i++) {
btPersistentManifold manifold = world.dispatcher.getManifoldByIndexInternal(i);
btCollisionObject objA = manifold.getBody0();
btCollisionObject objB = manifold.getBody1();
if (objA != ground.body && objB != ground.body) {
if (objA.userData != null && objA.userData instanceof BulletEntity) {
BulletEntity ent = (BulletEntity)objA.userData;
if (ent != projectile && !contacts.contains(ent, true) && !hits.contains(ent, true)) contacts.add(ent);
}
if (objB.userData != null && objB.userData instanceof BulletEntity) {
BulletEntity ent = (BulletEntity)objB.userData;
if (ent != projectile && !contacts.contains(ent, true) && !hits.contains(ent, true)) contacts.add(ent);
}
}
}
}
@Override
public void create () {
super.create();
contactCB = new TestContactResultCallback();
}
@Override
public void render () {
process();
}
private Pool<Color> colorPool = new Pool<Color>() {
@Override
protected Color newObject () {
return new Color();
}
};
public void process () {
Color color = null;
update();
hits.clear();
contacts.clear();
// Note that this might miss collisions, use InternalTickCallback to check for collision on every tick.
// See InternalTickTest on how to implement it.
// Check what the projectile hits
if (projectile != null) {
color = projectile.getColor();
projectile.setColor(Color.RED);
world.collisionWorld.contactTest(projectile.body, contactCB);
}
// Check for other collisions
updateContactInfo();
if (hits.size > 0) {
for (int i = 0; i < hits.size; i++) {
colors.add(colorPool.obtain().set(hits.get(i).getColor()));
hits.get(i).setColor(Color.RED);
}
}
if (contacts.size > 0) {
for (int i = 0; i < contacts.size; i++) {
colors.add(colorPool.obtain().set(contacts.get(i).getColor()));
contacts.get(i).setColor(Color.BLUE);
}
}
render(false);
if (projectile != null) projectile.setColor(color);
for (int i = 0; i < hits.size; i++)
hits.get(i).setColor(colors.get(i));
for (int i = 0; i < contacts.size; i++)
contacts.get(i).setColor(colors.get(hits.size + i));
colorPool.freeAll(colors);
colors.clear();
}
@Override
public boolean tap (float x, float y, int count, int button) {
projectile = shoot(x, y);
return true;
}
@Override
public void dispose () {
super.dispose();
projectile = null;
}
}