package se.rhel.model.physics;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.bullet.collision.*;
import com.badlogic.gdx.physics.bullet.dynamics.*;
import com.badlogic.gdx.physics.bullet.linearmath.btDefaultMotionState;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.PerformanceCounter;
import se.rhel.model.BaseModel;
import se.rhel.res.Resources;
/**
* Group: Logic
*
* Created by Emil on 2014-02-20.
* assigned to libgdx-gradle-template in se.rhel.model
*/
public class BulletWorld implements BaseModel {
private static PerformanceCounter PERFORMANCE_COUNTER = new PerformanceCounter("BulletWorld");
public static String PERFORMANCE;
private btCollisionConfiguration mCollisionConfig;
private btCollisionDispatcher mDispatcher;
private btBroadphaseInterface mBroadphase;
private btConstraintSolver mSolver;
private btDynamicsWorld mCollisionWorld;
private Array<btCollisionShape> mShapes = new Array<>();
private Array<btRigidBodyConstructionInfo> mBodyInfos = new Array<>();
private Array<btRigidBody> mBodies = new Array<>();
private Array<btDefaultMotionState> mMotionStates = new Array<>();
private Vector3 mGravity = new Vector3(0, -9.87f, 0);
private final float FIXED_TIMESTEP = 1f/60f;
public BulletWorld() {
create();
}
@Override
public void create() {
// Create the bullet world
mCollisionConfig = new btDefaultCollisionConfiguration();
mDispatcher = new btCollisionDispatcher(mCollisionConfig);
mBroadphase = new btDbvtBroadphase();
mSolver = new btSequentialImpulseConstraintSolver();
mCollisionWorld = new btDiscreteDynamicsWorld(mDispatcher, mBroadphase, mSolver, mCollisionConfig);
mCollisionWorld.setGravity(mGravity);
// Level
btBvhTriangleMeshShape levelShape = new btBvhTriangleMeshShape(Resources.INSTANCE.levelModelPhysics.meshParts);
mShapes.add(levelShape);
btRigidBodyConstructionInfo levelInfo = new btRigidBodyConstructionInfo(0f, null, levelShape, Vector3.Zero);
levelInfo.setRestitution(5f);
levelInfo.setFriction(5f);
mBodyInfos.add(levelInfo);
btDefaultMotionState levelMotionState = new btDefaultMotionState();
mMotionStates.add(levelMotionState);
btRigidBody levelBody = new btRigidBody(levelInfo);
levelBody.setMotionState(levelMotionState);
mBodies.add(levelBody);
mCollisionWorld.addRigidBody(levelBody);
}
public void addToWorld(btCollisionShape shape, btRigidBodyConstructionInfo info, btDefaultMotionState motionState, btRigidBody body) {
mShapes.add(shape);
mBodyInfos.add(info);
mMotionStates.add(motionState);
mBodies.add(body);
mCollisionWorld.addRigidBody(body);
}
@Override
public void update(float delta) {
PERFORMANCE_COUNTER.tick();
PERFORMANCE_COUNTER.start();
mCollisionWorld.stepSimulation(delta, 8, FIXED_TIMESTEP);
PERFORMANCE_COUNTER.stop();
PERFORMANCE = "Bullet: " + (int)(PERFORMANCE_COUNTER.load.value*100f) + " %";
}
@Override
public void dispose() {
mCollisionWorld.dispose();
mSolver.dispose();
mBroadphase.dispose();
mDispatcher.dispose();
mCollisionConfig.dispose();
for(btRigidBody body : mBodies)
body.dispose();
mBodies.clear();
for(btDefaultMotionState motionState : mMotionStates)
motionState.dispose();
mMotionStates.clear();
for(btCollisionShape shape : mShapes)
shape.dispose();
mShapes.clear();
for(btRigidBodyConstructionInfo info : mBodyInfos)
info.dispose();
mBodyInfos.clear();
}
public btCollisionWorld getCollisionWorld() {
return mCollisionWorld;
}
}