I am trying to create program of bouncing balls uisng libgdx in 3d.I am complete beginner just started getting hands on libgdx. I am able to detect the collision between the bat and ball but unable to get it bounced back
Here is my complete code
public class Main implements ApplicationListener {
final static short GROUND_FLAG = 1 << 8;
final static short OBJECT_FLAG = 1 << 9;
final static short ALL_FLAG = -1;
class MyContactListener extends ContactListener {
@Override
public boolean onContactAdded(int userValue0, int partId0, int index0,
int userValue1, int partId1, int index1) {
//instances.get(userValue0).moving = false;
//instances.get(userValue1).moving = false;
return true;
}
}
static class MyMotionState extends btMotionState {
Matrix4 transform;
@Override
public void getWorldTransform(Matrix4 worldTrans) {
worldTrans.set(transform);
}
@Override
public void setWorldTransform(Matrix4 worldTrans) {
transform.set(worldTrans);
}
}
static class GameObject extends ModelInstance implements Disposable {
public final btRigidBody body;
public boolean moving;
public final MyMotionState motionState;
public GameObject(Model model, String node,
btRigidBody.btRigidBodyConstructionInfo constructionInfo) {
super(model, node);
motionState = new MyMotionState();
motionState.transform = transform;
body = new btRigidBody(constructionInfo);
body.setMotionState(motionState);
}
@Override
public void dispose() {
// TODO Auto-generated method stub
body.dispose();
motionState.dispose();
}
static class Constructor implements Disposable {
public final Model model;
public final String node;
public final btCollisionShape shape;
public final btRigidBody.btRigidBodyConstructionInfo constructionInfo;
public static Vector3 inertia = new Vector3();
public Constructor(Model model, String node,
btCollisionShape shape, float mass) {
this.model = model;
this.node = node;
this.shape = shape;
if (mass > 0f) {
shape.calculateLocalInertia(mass, inertia);
} else {
inertia.set(0, 0, 0);
}
this.constructionInfo = new btRigidBody.btRigidBodyConstructionInfo(
mass, null, shape, inertia);
}
public GameObject construct() {
return new GameObject(model, node, constructionInfo);
}
@Override
public void dispose() {
shape.dispose();
constructionInfo.dispose();
}
}
}
PerspectiveCamera camera;
Environment environment;
ModelBatch modelBatch;
Model model;
Array<GameObject> instances;
ArrayMap<String, GameObject.Constructor> constructors;
btCollisionConfiguration configuration;
btDispatcher dispatcher;
btBroadphaseInterface broadphaseInterface;
btDynamicsWorld dynamicWorld;
btConstraintSolver solver;
MyContactListener contactListener;
float spawTimer;
@Override
public void create() {
// TODO Auto-generated method stub
Bullet.init();
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f,
0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f,
-0.8f, -0.2f));
camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
camera.position.set(3f, 7f, 10f);
camera.lookAt(0, 4f, 0);
camera.near = 1f;
camera.far = 300f;
camera.update();
ModelBuilder builder = new ModelBuilder();
builder.begin();
builder.node().id = "ground";
builder.part("ground", GL20.GL_TRIANGLES,
Usage.Position | Usage.Normal,
new Material(ColorAttribute.createDiffuse(Color.RED))).box(5f,
1f, 5f);
builder.node().id = "sphere";
builder.part("sphere", GL20.GL_TRIANGLES,
Usage.Position | Usage.Normal,
new Material(ColorAttribute.createDiffuse(Color.GREEN)))
.sphere(1f, 1f, 1f, 10, 10);
model = builder.end();
constructors = new ArrayMap<String, Main.GameObject.Constructor>(
String.class, GameObject.Constructor.class);
constructors.put("ground", new GameObject.Constructor(model, "ground",
new btBoxShape(new Vector3(2.5f, .5f, 2.5f)), 0f));
constructors.put("ball", new GameObject.Constructor(model, "sphere",
new btSphereShape(0.5f), 3f));
configuration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(configuration);
solver = new btSequentialImpulseConstraintSolver();
broadphaseInterface = new btDbvtBroadphase();
dynamicWorld = new btDiscreteDynamicsWorld(dispatcher,
broadphaseInterface, solver, configuration);
dynamicWorld.setGravity(new Vector3(0, -10, 0));
contactListener = new MyContactListener();
instances = new Array<Main.GameObject>();
GameObject object = constructors.get("ground").construct();
object.body.setCollisionFlags(object.body.getCollisionFlags()
| btCollisionObject.CollisionFlags.CF_KINEMATIC_OBJECT);
instances.add(object);
dynamicWorld.addRigidBody(object.body);
object.body.setActivationState(Collision.DISABLE_DEACTIVATION);
createBall();
}
public void createBall() {
GameObject obj = constructors.get("ball").construct();
//obj.moving = true;
obj.transform.setFromEulerAngles(MathUtils.random(360f),
MathUtils.random(360f), MathUtils.random(360f));
obj.transform.trn(0f, 9f, 0f);
//obj.body.proceedToTransform(obj.transform);
obj.body.setRestitution(1.0f);
obj.body.setFriction(1.0f);
obj.body.setWorldTransform(obj.transform);
obj.body.setUserValue(instances.size);
obj.body.setCollisionFlags(obj.body.getCollisionFlags()
| btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
instances.add(obj);
// dynamicWorld.addCollisionObject(obj.body, OBJECT_FLAG, GROUND_FLAG);
dynamicWorld.addRigidBody(obj.body);
}
@Override
public void resize(int width, int height) {
}
float angle, speed = 10f;
@Override
public void render() {
// TODO Auto-generated method stub
final float delta = Gdx.graphics.getDeltaTime();
angle = (angle + delta+speed) % 360;
instances.get(0).transform.setTranslation(0f,MathUtils.sinDeg(angle),0f);
//instances.get(0).body.setWorldTransform(instances.get(0).transform);
dynamicWorld.stepSimulation(delta, 5, 1 / 60f);
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1.f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(camera);
modelBatch.render(instances, environment);
modelBatch.end();
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
// TODO Auto-generated method stub
for (GameObject obj : instances)
obj.dispose();
instances.clear();
for (GameObject.Constructor ctor : constructors.values())
ctor.dispose();
constructors.clear();
dynamicWorld.dispose();
solver.dispose();
broadphaseInterface.dispose();
dispatcher.dispose();
configuration.dispose();
contactListener.dispose();
modelBatch.dispose();
model.dispose();
}
}
}
Here is my updated code right now I am able to bounce the ground which is not my objective but my objective is to bounce the ball when it hits the code applied for moving of the ground is unable to get appied to ball. Please help.
Here is the code.Finally the ball bounce
public class Main implements ApplicationListener {
final static short GROUND_FLAG = 1 << 8;
final static short OBJECT_FLAG = 1 << 9;
final static short ALL_FLAG = -1;
public float delta;
class MyContactListener extends ContactListener {
@Override
public boolean onContactAdded(int userValue0, int partId0, int index0,
int userValue1, int partId1, int index1) {
// Gdx.app.log("onContact", "onContact Added");
instances.get(1).body.setLinearVelocity(new Vector3(0, 10f, 0f));
return true;
}
}
static class MyMotionState extends btMotionState {
Matrix4 transform;
@Override
public void getWorldTransform(Matrix4 worldTrans) {
worldTrans.set(transform);
}
@Override
public void setWorldTransform(Matrix4 worldTrans) {
transform.set(worldTrans);
}
}
static class GameObject extends ModelInstance implements Disposable {
public final btRigidBody body;
public boolean moving;
public final MyMotionState motionState;
public GameObject(Model model, String node,
btRigidBody.btRigidBodyConstructionInfo constructionInfo) {
super(model, node);
motionState = new MyMotionState();
motionState.transform = transform;
body = new btRigidBody(constructionInfo);
body.setMotionState(motionState);
}
@Override
public void dispose() {
// TODO Auto-generated method stub
body.dispose();
motionState.dispose();
}
static class Constructor implements Disposable {
public final Model model;
public final String node;
public final btCollisionShape shape;
public final btRigidBody.btRigidBodyConstructionInfo constructionInfo;
public static Vector3 inertia = new Vector3();
public Constructor(Model model, String node,
btCollisionShape shape, float mass) {
this.model = model;
this.node = node;
this.shape = shape;
if (mass > 0f) {
shape.calculateLocalInertia(mass, inertia);
} else {
inertia.set(0, 0, 0);
}
this.constructionInfo = new btRigidBody.btRigidBodyConstructionInfo(
mass, null, shape, inertia);
}
public GameObject construct() {
return new GameObject(model, node, constructionInfo);
}
@Override
public void dispose() {
shape.dispose();
constructionInfo.dispose();
}
}
}
PerspectiveCamera camera;
Environment environment;
ModelBatch modelBatch;
Model model;
Array<GameObject> instances;
ArrayMap<String, GameObject.Constructor> constructors;
btCollisionConfiguration configuration;
btDispatcher dispatcher;
btBroadphaseInterface broadphaseInterface;
btDynamicsWorld dynamicWorld;
btConstraintSolver solver;
MyContactListener contactListener;
float spawTimer;
GameObject obj;
@Override
public void create() {
// TODO Auto-generated method stub
Bullet.init();
modelBatch = new ModelBatch();
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f,
0.4f, 0.4f, 1f));
environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f,
-0.8f, -0.2f));
camera = new PerspectiveCamera(67, Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
camera.position.set(3f, 7f, 10f);
camera.lookAt(0, 4f, 0);
camera.near = 1f;
camera.far = 300f;
camera.update();
ModelBuilder builder = new ModelBuilder();
builder.begin();
builder.node().id = "ground";
builder.part("ground", GL20.GL_TRIANGLES,
Usage.Position | Usage.Normal,
new Material(ColorAttribute.createDiffuse(Color.RED))).box(5f,
1f, 5f);
builder.node().id = "sphere";
builder.part("sphere", GL20.GL_TRIANGLES,
Usage.Position | Usage.Normal,
new Material(ColorAttribute.createDiffuse(Color.GREEN)))
.sphere(1f, 1f, 1f, 10, 10);
model = builder.end();
constructors = new ArrayMap<String, Main.GameObject.Constructor>(
String.class, GameObject.Constructor.class);
constructors.put("ground", new GameObject.Constructor(model, "ground",
new btBoxShape(new Vector3(2.5f, .5f, 2.5f)), 0f));
constructors.put("ball", new GameObject.Constructor(model, "sphere",
new btSphereShape(0.5f), 0.5f));
configuration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(configuration);
solver = new btSequentialImpulseConstraintSolver();
broadphaseInterface = new btDbvtBroadphase();
dynamicWorld = new btDiscreteDynamicsWorld(dispatcher,
broadphaseInterface, solver, configuration);
dynamicWorld.setGravity(new Vector3(0, -8f, 0));
contactListener = new MyContactListener();
instances = new Array<Main.GameObject>();
GameObject object = constructors.get("ground").construct();
object.body.setCollisionFlags(object.body.getCollisionFlags()
| btCollisionObject.CollisionFlags.CF_KINEMATIC_OBJECT);
instances.add(object);
dynamicWorld.addRigidBody(object.body);
object.body.setActivationState(Collision.DISABLE_DEACTIVATION);
createBall();
}
public void createBall() {
obj = constructors.get("ball").construct();
obj.transform.trn(0f, 11f, 0f);
obj.body.setWorldTransform(obj.transform);
obj.body.setUserValue(instances.size);
obj.body.setCollisionFlags(obj.body.getCollisionFlags()
| btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
obj.body.setFriction(1.0f);
obj.body.setRestitution(3.0f);
instances.add(obj);
dynamicWorld.addRigidBody(obj.body);
}
@Override
public void resize(int width, int height) {
}
float angle, speed = 10f, yTranslate = 0f, zAngle = 0f;
@Override
public void render() {
// TODO Auto-generated method stub
delta = Gdx.graphics.getDeltaTime();
angle = (angle + delta + speed) % 360;
if (Gdx.input.isTouched()) {
if (yTranslate > -60f) {
zAngle -= 0.2f;
} else {
// yTranslate = 30f;
}
instances.get(0).transform.setToRotation(0f, 0f, 2f, zAngle);
} else {
instances.get(0).transform.setToRotation(0f, 0f, 1f, 30f);
instances.get(0).transform.setTranslation(0f, 0f, 0f);
}
//instances.get(0).transform.setTranslation(0f,0f,0f);
dynamicWorld.stepSimulation(delta, 5, 1 / 60f);
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1.f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(camera);
modelBatch.render(instances, environment);
modelBatch.end();
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
// TODO Auto-generated method stub
for (GameObject obj : instances)
obj.dispose();
instances.clear();
for (GameObject.Constructor ctor : constructors.values())
ctor.dispose();
constructors.clear();
dynamicWorld.dispose();
solver.dispose();
broadphaseInterface.dispose();
dispatcher.dispose();
configuration.dispose();
contactListener.dispose();
modelBatch.dispose();
model.dispose();
}
}