162 lines
5.5 KiB
Java
162 lines
5.5 KiB
Java
package electrosphere.collision;
|
|
|
|
import java.nio.IntBuffer;
|
|
|
|
import org.joml.Vector3d;
|
|
import org.lwjgl.PointerBuffer;
|
|
import org.lwjgl.assimp.AIFace;
|
|
import org.lwjgl.assimp.AIMesh;
|
|
import org.lwjgl.assimp.AIScene;
|
|
import org.lwjgl.assimp.AIVector3D;
|
|
import org.ode4j.ode.DBody;
|
|
import org.ode4j.ode.DBox;
|
|
import org.ode4j.ode.DCylinder;
|
|
import org.ode4j.ode.DSphere;
|
|
import org.ode4j.ode.DTriMesh;
|
|
|
|
import electrosphere.entity.types.terrain.TerrainChunkData;
|
|
|
|
/**
|
|
* Utilities for creating types of rigid bodies
|
|
*/
|
|
public class CollisionBodyCreation {
|
|
|
|
|
|
|
|
//The width of a plane rigid body
|
|
//It's really a box under the hood
|
|
static final double PLANE_WIDTH = 0.3;
|
|
|
|
/**
|
|
* Creates a plane DBody. Dimensions x and z control the length and width of the plane;
|
|
* @param dimensions The dimensions of the plane
|
|
* @return The DBody
|
|
*/
|
|
public static DBody createPlaneBody(CollisionEngine collisionEngine, Vector3d dimensions){
|
|
DBox geom = collisionEngine.createCubeGeom(new Vector3d(dimensions.x,PLANE_WIDTH,dimensions.z));
|
|
return collisionEngine.createDBody(geom);
|
|
}
|
|
|
|
/**
|
|
* Creates a cube DBody. Dimensions controlled by the dimensions vector.
|
|
* @param collisionEngine The collision engine to create the body inside of
|
|
* @param dimensions The dimensions of the cube
|
|
* @return The DBody
|
|
*/
|
|
public static DBody createCubeBody(CollisionEngine collisionEngine, Vector3d dimensions){
|
|
DBox geom = collisionEngine.createCubeGeom(new Vector3d(dimensions));
|
|
return collisionEngine.createDBody(geom);
|
|
}
|
|
|
|
/**
|
|
* Creates a cylinder DBody. Dimensions controlled by the dimensions vector.
|
|
* @param collisionEngine The collision engine to create the body inside of
|
|
* @param dimensions The dimensions of the cube
|
|
* @return The DBody
|
|
*/
|
|
public static DBody createCylinderBody(CollisionEngine collisionEngine, double radius, double length){
|
|
DCylinder geom = collisionEngine.createCylinderGeom(radius,length);
|
|
return collisionEngine.createDBody(geom);
|
|
}
|
|
|
|
/**
|
|
* Creates a sphere body in the collision engine
|
|
* @param collisionEngine The collision engine
|
|
* @param radius The radius of the sphere
|
|
* @return The DBody
|
|
*/
|
|
public static DBody createSphereBody(CollisionEngine collisionEngine, double radius){
|
|
DSphere geom = collisionEngine.createSphereGeom(radius);
|
|
return collisionEngine.createDBody(geom);
|
|
}
|
|
|
|
|
|
/**
|
|
* Creates an ode DBody from a terrain chunk data object
|
|
* @param data The terrain data
|
|
* @return The DBody
|
|
*/
|
|
public static DBody generateBodyFromTerrainData(CollisionEngine collisionEngine, TerrainChunkData data){
|
|
DBody body = null;
|
|
|
|
//create data
|
|
int numberTriangles = data.getFaceElements().size() / 3;
|
|
int numberVertices = data.getVertices().size() / 3;
|
|
|
|
float[] vertices = new float[numberVertices * 3];
|
|
int vertexInserterPos = 0;
|
|
int[] indices = new int[numberTriangles * 3];
|
|
int indexInserterPos = 0;
|
|
|
|
for(float vertexValue : data.getVertices()){
|
|
vertices[vertexInserterPos] = vertexValue;
|
|
vertexInserterPos++;
|
|
}
|
|
|
|
for(int element : data.getFaceElements()){
|
|
indices[indexInserterPos] = element;
|
|
indexInserterPos++;
|
|
}
|
|
|
|
//create trimesh
|
|
if(vertices.length > 0){
|
|
DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices);
|
|
body = collisionEngine.createDBody(triMesh);
|
|
}
|
|
|
|
return body;
|
|
}
|
|
|
|
/**
|
|
* Generates a body from an AIScene
|
|
* @param scene The AIScene to generate a rigid body off of
|
|
* @return A rigid body based on the AIScene
|
|
*/
|
|
public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene){
|
|
|
|
DBody body = collisionEngine.createDBody(null);
|
|
|
|
PointerBuffer meshesBuffer = scene.mMeshes();
|
|
while(meshesBuffer.hasRemaining()){
|
|
float[] verts;
|
|
int numVertices;
|
|
int[] indices;
|
|
int numTriangles;
|
|
|
|
AIMesh aiMesh = AIMesh.create(meshesBuffer.get());
|
|
//allocate array for vertices
|
|
numVertices = aiMesh.mNumVertices();
|
|
verts = new float[numVertices * 3];
|
|
//read vertices
|
|
AIVector3D.Buffer vertexBuffer = aiMesh.mVertices();
|
|
int vertPos = 0;
|
|
while(vertexBuffer.hasRemaining()){
|
|
AIVector3D vector = vertexBuffer.get();
|
|
verts[vertPos+0] = vector.x();
|
|
verts[vertPos+1] = vector.y();
|
|
verts[vertPos+2] = vector.z();
|
|
vertPos = vertPos + 3;
|
|
}
|
|
numTriangles = aiMesh.mNumFaces();
|
|
indices = new int[numTriangles * 3];
|
|
int indicesPos = 0;
|
|
//read faces
|
|
AIFace.Buffer faceBuffer = aiMesh.mFaces();
|
|
while(faceBuffer.hasRemaining()){
|
|
AIFace currentFace = faceBuffer.get();
|
|
IntBuffer indexBuffer = currentFace.mIndices();
|
|
while(indexBuffer.hasRemaining()){
|
|
int index = indexBuffer.get();
|
|
indices[indicesPos] = index;
|
|
indicesPos++;
|
|
}
|
|
}
|
|
DTriMesh meshGeom = collisionEngine.createTrimeshGeom(verts, indices);
|
|
meshGeom.setBody(body);
|
|
}
|
|
|
|
return body;
|
|
}
|
|
|
|
}
|