1 /*******************************************************************************
\r
2 * Copyright 2011 See AUTHORS file.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
15 ******************************************************************************/
17 package com.badlogic.gdx.tests;
19 import com.badlogic.gdx.Gdx;
20 import com.badlogic.gdx.graphics.Color;
21 import com.badlogic.gdx.graphics.GL10;
22 import com.badlogic.gdx.graphics.PerspectiveCamera;
23 import com.badlogic.gdx.graphics.VertexAttributes.Usage;
24 import com.badlogic.gdx.graphics.g3d.Environment;
25 import com.badlogic.gdx.graphics.g3d.Material;
26 import com.badlogic.gdx.graphics.g3d.Model;
27 import com.badlogic.gdx.graphics.g3d.ModelBatch;
28 import com.badlogic.gdx.graphics.g3d.ModelInstance;
29 import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
30 import com.badlogic.gdx.graphics.g3d.attributes.FloatAttribute;
31 import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
32 import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
33 import com.badlogic.gdx.math.MathUtils;
34 import com.badlogic.gdx.math.Vector3;
35 import com.badlogic.gdx.physics.bullet.btBoxShape;
36 import com.badlogic.gdx.physics.bullet.btBroadphaseInterface;
37 import com.badlogic.gdx.physics.bullet.btCollisionConfiguration;
38 import com.badlogic.gdx.physics.bullet.btCollisionDispatcher;
39 import com.badlogic.gdx.physics.bullet.btCollisionShape;
40 import com.badlogic.gdx.physics.bullet.btConstraintSolver;
41 import com.badlogic.gdx.physics.bullet.btDbvtBroadphase;
42 import com.badlogic.gdx.physics.bullet.btDefaultCollisionConfiguration;
43 import com.badlogic.gdx.physics.bullet.btDefaultMotionState;
44 import com.badlogic.gdx.physics.bullet.btDiscreteDynamicsWorld;
45 import com.badlogic.gdx.physics.bullet.btDynamicsWorld;
46 import com.badlogic.gdx.physics.bullet.btRigidBody;
47 import com.badlogic.gdx.physics.bullet.btRigidBodyConstructionInfo;
48 import com.badlogic.gdx.physics.bullet.btSequentialImpulseConstraintSolver;
49 import com.badlogic.gdx.physics.bullet.btSphereShape;
50 import com.badlogic.gdx.tests.bullet.BaseBulletTest;
51 import com.badlogic.gdx.tests.bullet.BulletTest;
52 import com.badlogic.gdx.utils.Array;
55 public class BasicBulletTest extends BulletTest {
56 ModelBatch modelBatch;
58 ModelBuilder modelBuilder = new ModelBuilder();
60 btCollisionConfiguration collisionConfiguration;
61 btCollisionDispatcher dispatcher;
62 btBroadphaseInterface broadphase;
63 btConstraintSolver solver;
64 btDynamicsWorld collisionWorld;
65 Vector3 gravity = new Vector3(0, -9.81f, 0);
66 Vector3 tempVector = new Vector3();
68 Array<Model> models = new Array<Model>();
69 Array<ModelInstance> instances = new Array<ModelInstance>();
70 Array<btDefaultMotionState> motionStates = new Array<btDefaultMotionState>();
71 Array<btRigidBodyConstructionInfo> bodyInfos = new Array<btRigidBodyConstructionInfo>();
72 Array<btCollisionShape> shapes = new Array<btCollisionShape>();
73 Array<btRigidBody> bodies = new Array<btRigidBody>();
76 public void create () {
78 instructions = "Swipe for next test";
80 lights = new Environment();
81 lights.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.2f, 0.2f, 0.2f, 1.f));
82 lights.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -0.5f, -1f, -0.7f));
85 final float width = Gdx.graphics.getWidth();
86 final float height = Gdx.graphics.getHeight();
88 camera = new PerspectiveCamera(67f, 3f * width / height, 3f);
90 camera = new PerspectiveCamera(67f, 3f, 3f * height / width);
91 camera.position.set(10f, 10f, 10f);
92 camera.lookAt(0, 0, 0);
94 // Create the model batch
95 modelBatch = new ModelBatch();
96 // Create some basic models
97 final Model groundModel = modelBuilder.createRect(20f, 0f, -20f, -20f, 0f, -20f, -20f, 0f, 20f, 20f, 0f, 20f, 0, 1, 0,
98 new Material(ColorAttribute.createDiffuse(Color.BLUE), ColorAttribute.createSpecular(Color.WHITE), FloatAttribute.createShininess(16f)),
99 Usage.Position | Usage.Normal);
100 models.add(groundModel);
101 final Model sphereModel = modelBuilder.createSphere(1f, 1f, 1f, 10, 10,
102 new Material(ColorAttribute.createDiffuse(Color.RED), ColorAttribute.createSpecular(Color.WHITE), FloatAttribute.createShininess(64f)),
103 Usage.Position | Usage.Normal);
104 models.add(sphereModel);
105 // Load the bullet library
106 BaseBulletTest.init(); // Normally use: Bullet.init();
107 // Create the bullet world
108 collisionConfiguration = new btDefaultCollisionConfiguration();
109 dispatcher = new btCollisionDispatcher(collisionConfiguration);
110 broadphase = new btDbvtBroadphase();
111 solver = new btSequentialImpulseConstraintSolver();
112 collisionWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
113 collisionWorld.setGravity(gravity);
114 // Create the shapes and body construction infos
115 btCollisionShape groundShape = new btBoxShape(tempVector.set(20, 0, 20));
116 shapes.add(groundShape);
117 btRigidBodyConstructionInfo groundInfo = new btRigidBodyConstructionInfo(0f, null, groundShape, Vector3.Zero);
118 bodyInfos.add(groundInfo);
119 btCollisionShape sphereShape = new btSphereShape(0.5f);
120 shapes.add(sphereShape);
121 sphereShape.calculateLocalInertia(1f, tempVector);
122 btRigidBodyConstructionInfo sphereInfo = new btRigidBodyConstructionInfo(1f, null, sphereShape, tempVector);
123 bodyInfos.add(sphereInfo);
125 ModelInstance ground = new ModelInstance(groundModel);
126 instances.add(ground);
127 btDefaultMotionState groundMotionState = new btDefaultMotionState();
128 groundMotionState.setWorldTransform(ground.transform);
129 motionStates.add(groundMotionState);
130 btRigidBody groundBody = new btRigidBody(groundInfo);
131 groundBody.setMotionState(groundMotionState);
132 bodies.add(groundBody);
133 collisionWorld.addRigidBody(groundBody);
134 // Create the spheres
135 for (float x = -10f; x <= 10f; x += 2f) {
136 for (float y = 5f; y <= 15f; y += 2f) {
137 for (float z = 0f; z <= 0f; z+= 2f) {
138 ModelInstance sphere = new ModelInstance(sphereModel);
139 instances.add(sphere);
140 sphere.transform.trn(x+0.1f*MathUtils.random(), y+0.1f*MathUtils.random(), z+0.1f*MathUtils.random());
141 btDefaultMotionState sphereMotionState = new btDefaultMotionState();
142 sphereMotionState.setWorldTransform(sphere.transform);
143 motionStates.add(sphereMotionState);
144 btRigidBody sphereBody = new btRigidBody(sphereInfo);
145 sphereBody.setMotionState(sphereMotionState);
146 bodies.add(sphereBody);
147 collisionWorld.addRigidBody(sphereBody);
154 public void render () {
155 Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
156 Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
158 fpsCounter.put(Gdx.graphics.getFramesPerSecond());
160 performanceCounter.tick();
161 performanceCounter.start();
162 ((btDynamicsWorld)collisionWorld).stepSimulation(Gdx.graphics.getDeltaTime(), 5);
163 performanceCounter.stop();
165 int c = motionStates.size;
166 for (int i = 0; i < c; i++) {
167 motionStates.get(i).getWorldTransform(instances.get(i).transform);
170 modelBatch.begin(camera);
171 modelBatch.render(instances, lights);
174 performance.setLength(0);
175 performance.append("FPS: ").append(fpsCounter.value).append(", Bullet: ")
176 .append((int)(performanceCounter.load.value*100f)).append("%");
180 public void dispose () {
181 collisionWorld.dispose();
183 broadphase.dispose();
184 dispatcher.dispose();
185 collisionConfiguration.dispose();
187 for (btRigidBody body : bodies)
190 for (btDefaultMotionState motionState : motionStates)
191 motionState.dispose();
192 motionStates.clear();
193 for (btCollisionShape shape : shapes)
196 for (btRigidBodyConstructionInfo info : bodyInfos)
200 modelBatch.dispose();
202 for (Model model : models)