1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests.bullet; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.graphics.Color; 21 import com.badlogic.gdx.graphics.g3d.Model; 22 import com.badlogic.gdx.math.Matrix4; 23 import com.badlogic.gdx.math.Vector3; 24 import com.badlogic.gdx.physics.bullet.collision.btCollisionDispatcher; 25 import com.badlogic.gdx.physics.bullet.collision.btCollisionObject; 26 import com.badlogic.gdx.physics.bullet.collision.btCollisionObjectWrapper; 27 import com.badlogic.gdx.physics.bullet.collision.btCollisionWorld; 28 import com.badlogic.gdx.physics.bullet.collision.ContactResultCallback; 29 import com.badlogic.gdx.physics.bullet.collision.btDbvtBroadphase; 30 import com.badlogic.gdx.physics.bullet.collision.btDefaultCollisionConfiguration; 31 import com.badlogic.gdx.physics.bullet.collision.btManifoldPoint; 32 33 /** @author xoppa */ 34 public class CollisionWorldTest extends BaseBulletTest { 35 BulletEntity movingBox; 36 boolean hit = false; 37 Color normalColor = new Color(); 38 btCollisionObject other; 39 40 public class TestContactResultCallback extends ContactResultCallback { 41 @Override addSingleResult(btManifoldPoint cp, btCollisionObjectWrapper colObj0Wrap, int partId0, int index0, btCollisionObjectWrapper colObj1Wrap, int partId1, int index1)42 public float addSingleResult (btManifoldPoint cp, btCollisionObjectWrapper colObj0Wrap, int partId0, int index0, 43 btCollisionObjectWrapper colObj1Wrap, int partId1, int index1) { 44 hit = true; 45 other = colObj0Wrap.getCollisionObject() == movingBox.body ? colObj1Wrap.getCollisionObject() : colObj0Wrap 46 .getCollisionObject(); 47 48 return 0f; 49 } 50 } 51 52 TestContactResultCallback contactCB; 53 54 @Override createWorld()55 public BulletWorld createWorld () { 56 btDefaultCollisionConfiguration collisionConfig = new btDefaultCollisionConfiguration(); 57 btCollisionDispatcher dispatcher = new btCollisionDispatcher(collisionConfig); 58 btDbvtBroadphase broadphase = new btDbvtBroadphase(); 59 btCollisionWorld collisionWorld = new btCollisionWorld(dispatcher, broadphase, collisionConfig); 60 return new BulletWorld(collisionConfig, dispatcher, broadphase, null, collisionWorld); 61 } 62 63 @Override create()64 public void create () { 65 super.create(); 66 67 instructions = "Long press to toggle debug mode\nSwipe for next test\nCtrl+drag to rotate\nScroll to zoom"; 68 69 contactCB = new TestContactResultCallback(); 70 71 Model groundModel = world.getConstructor("ground").model; 72 Model boxModel = world.getConstructor("box").model; 73 74 world.addConstructor("collisionGround", new BulletConstructor(groundModel)); 75 world.addConstructor("collisionBox", new BulletConstructor(boxModel)); 76 77 world.add("collisionGround", 0f, 0f, 0f).setColor(0.25f + 0.5f * (float)Math.random(), 0.25f + 0.5f * (float)Math.random(), 78 0.25f + 0.5f * (float)Math.random(), 1f); 79 80 world.add("collisionBox", 0f, 1f, 5f).setColor(0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 81 0.5f + 0.5f * (float)Math.random(), 1f); 82 world.add("collisionBox", 0f, 1f, -5f).setColor(0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 83 0.5f + 0.5f * (float)Math.random(), 1f); 84 world.add("collisionBox", 5f, 1f, 0f).setColor(0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 85 0.5f + 0.5f * (float)Math.random(), 1f); 86 world.add("collisionBox", -5f, 1f, 0f).setColor(0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 87 0.5f + 0.5f * (float)Math.random(), 1f); 88 movingBox = world.add("collisionBox", -5f, 1f, 0f); 89 normalColor.set(0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 0.5f + 0.5f * (float)Math.random(), 90 1f); 91 } 92 93 Color tmpColor = new Color(); 94 95 @Override render()96 public void render () { 97 movingBox.transform.val[Matrix4.M03] = movingBox.transform.val[Matrix4.M13] = movingBox.transform.val[Matrix4.M23] = 0f; 98 movingBox.transform.rotate(Vector3.Y, Gdx.graphics.getDeltaTime() * 45f); 99 movingBox.transform.translate(-5f, 1f, 0f); 100 movingBox.body.setWorldTransform(movingBox.transform); 101 102 super.render(); 103 } 104 105 @Override update()106 public void update () { 107 super.update(); 108 // Not using dynamics, so update the collision world manually 109 if (world.performanceCounter != null) world.performanceCounter.start(); 110 world.collisionWorld.performDiscreteCollisionDetection(); 111 if (world.performanceCounter != null) world.performanceCounter.stop(); 112 } 113 114 @Override renderWorld()115 protected void renderWorld () { 116 hit = false; 117 other = null; 118 world.collisionWorld.contactTest(movingBox.body, contactCB); 119 movingBox.setColor(hit ? Color.RED : normalColor); 120 121 BulletEntity e = null; 122 if (other != null && other.userData != null && other.userData instanceof BulletEntity) { 123 e = (BulletEntity)(other.userData); 124 tmpColor.set(e.getColor()); 125 e.setColor(Color.RED); 126 } 127 128 super.renderWorld(); 129 130 if (e != null) e.setColor(tmpColor); 131 } 132 133 @Override dispose()134 public void dispose () { 135 super.dispose(); 136 movingBox = null; 137 } 138 } 139