package de.fau.cs.mad.fly.game;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.bullet.Bullet;
import com.badlogic.gdx.physics.bullet.collision.*;
import com.badlogic.gdx.utils.Disposable;
import java.util.HashMap;
import java.util.Map;
/**
* Manager for the btCollisionShapes.
* <p>
* Creates, stores and disposes all used collision shapes.
* <p>
* Available shape types: boxShape: if a simple box around the object is enough.
* sphereShape: if a simple sphere fits the object better a box. convexShape: if
* the object has a convex but not simple form. meshShape: if the object has
* holes and they have to be identified by the collision detector.
*
* @author Tobias Zangl
*/
public class CollisionShapeManager implements Disposable {
/**
* Maps to save the different shape types.
*/
Map<String, btCollisionShape> meshShapeMap, convexShapeMap, boxShapeMap, sphereShapeMap;
/**
* CollisionShapeManager
* <p>
* SHAPE TYPES: btSphereShape, btBoxShape, btCylinderShape, btCapsuleShape,
* btConeShape, btMultiSphereShape btConvexHullShape, btBvhTriangleMeshShape
* btCompoundShape
*/
public CollisionShapeManager() {
meshShapeMap = new HashMap<String, btCollisionShape>();
convexShapeMap = new HashMap<String, btCollisionShape>();
boxShapeMap = new HashMap<String, btCollisionShape>();
sphereShapeMap = new HashMap<String, btCollisionShape>();
}
/**
* Getter for a mesh shape with given shapeId.
*
* @param shapeId
* The id of the needed shape.
* @return btCollisionShape
*/
public btCollisionShape getMeshShape(String shapeId) {
return meshShapeMap.get(shapeId);
}
/**
* Getter for a convex shape with given shapeId.
*
* @param shapeId
* The id of the needed shape.
* @return btCollisionShape
*/
public btCollisionShape getConvexShape(String shapeId) {
return convexShapeMap.get(shapeId);
}
/**
* Getter for a box shape with given shapeId.
*
* @param shapeId
* The id of the needed shape.
* @return btCollisionShape
*/
public btCollisionShape getBoxShape(String shapeId) {
return boxShapeMap.get(shapeId);
}
/**
* Getter for a sphere shape with given shapeId.
*
* @param shapeId
* The id of the needed shape.
* @return btCollisionShape
*/
public btCollisionShape getSphereShape(String shapeId) {
return sphereShapeMap.get(shapeId);
}
/**
* Creates a new static mesh shape out of the instance if the shape is not
* already created.
*
* @param shapeId
* The id of the needed shape.
* @param box
* The game object to construct the shape.
* @return btCollisionShape
*/
public btCollisionShape createStaticMeshShape(String shapeId, final GameObject instance) {
btCollisionShape shape = meshShapeMap.get(shapeId);
if (shape != null) {
return shape;
}
btCollisionShape meshShape = Bullet.obtainStaticNodeShape(instance.model.nodes);
// Gdx.app.log("CollisionShapeManager", "Created static mesh shape: " +
// shapeId);
meshShapeMap.put(shapeId, meshShape);
return meshShape;
}
/**
* Creates a new btConvexHullShape out of the instance if the shape is not
* already created.
*
* @param shapeId
* The id of the needed shape.
* @param instance
* The game object to construct the shape.
* @return btCollisionShape
*/
public btCollisionShape createConvexShape(String shapeId, final GameObject instance) {
btCollisionShape shape = convexShapeMap.get(shapeId);
if (shape != null) {
return shape;
}
final Mesh mesh = instance.model.meshes.get(0);
final btConvexHullShape hullShape = new btConvexHullShape(mesh.getVerticesBuffer(), mesh.getNumVertices(), mesh.getVertexSize());
// now optimize the shape
final btShapeHull hull = new btShapeHull(hullShape);
hull.buildHull(hullShape.getMargin());
final btConvexHullShape convexShape = new btConvexHullShape(hull);
hullShape.dispose();
hull.dispose();
// Gdx.app.log("CollisionShapeManager", "Created convex shape: " +
// shapeId);
convexShapeMap.put(shapeId, convexShape);
return convexShape;
}
/**
* Creates a new btBoxShape with given box sizes if the shape is not already
* created.
*
* @param shapeId
* The id of the needed shape.
* @param box
* The size of the box shape.
* @return btCollisionShape
*/
public btCollisionShape createBoxShape(String shapeId, Vector3 box) {
btCollisionShape shape = boxShapeMap.get(shapeId);
if (shape != null) {
return shape;
}
btBoxShape boxShape = new btBoxShape(box);
// Gdx.app.log("CollisionShapeManager", "Created box shape: " +
// shapeId);
boxShapeMap.put(shapeId, boxShape);
return boxShape;
}
/**
* Creates a new btSphereShape with given radius if the shape is not already
* created.
*
* @param shapeId
* The id of the needed shape.
* @param radius
* The radius of the shape sphere.
* @return btCollisionShape
*/
public btCollisionShape createSphereShape(String shapeId, float radius) {
btCollisionShape shape = sphereShapeMap.get(shapeId);
if (shape != null) {
return shape;
}
btSphereShape sphereShape = new btSphereShape(radius);
// Gdx.app.log("CollisionShapeManager", "Created sphere shape: " +
// shapeId);
sphereShapeMap.put(shapeId, sphereShape);
return sphereShape;
}
@Override
public void dispose() {
meshShapeMap.clear();
convexShapeMap.clear();
boxShapeMap.clear();
sphereShapeMap.clear();
}
}