Так что я потратил много времени, пытаясь с нуля поработать над системой обнаружения столкновений для собственного игрового движка, но безрезультатно из-за нехватки времени. В конце концов, я решил попробовать использовать Jbullet, чтобы ускорить процесс. Теперь документация в основном бесполезна, и у меня возникают некоторые трудности с попыткой передать код пули в java (или то, что я передаю, не работает). Я рвал на себе волосы, пытаясь найти код библиотеки, но затем экономия времени, на которую я надеялся, оказалась почти бесполезной. Итак, я собираюсь объяснить, что я делаю, может быть, вы, ребята, сможете мне помочь. Я ищу только простое обнаружение столкновений, например, вы ударили что-то, а пока просто печатаете строку. Остальное я, наверное, разберусь сам.
Итак, я создаю свой мир:
BroadphaseInterface broadphase = new DbvtBroadphase();
CollisionConfiguration collisionConfig = new DefaultCollisionConfiguration();
Dispatcher dispatcher = new CollisionDispatcher(collisionConfig);
ConstraintSolver solver = new SequentialImpulseConstraintSolver();
DynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfig);
return dynamicsWorld;
Итак, у меня есть свой класс сущности, и там у меня есть еще один класс, в котором хранится вся информация о физическом объекте, прикрепленном к этой сущности. Это позволяет мне просто делать: entity.getPhysics().getCollisionObject()/.setPosition() и т.д...
Затем я создаю свой CollisionObject в этом классе:
List<org.lwjgl.util.vector.Vector3f> mesh = model.getModel().getVertices();
ObjectArrayList<javax.vecmath.Vector3f> vertices = new ObjectArrayList<javax.vecmath.Vector3f>();
for(org.lwjgl.util.vector.Vector3f vertex:mesh){
javax.vecmath.Vector3f v = new javax.vecmath.Vector3f(vertex.x, vertex.y, vertex.z);
vertices.add(v);
}
ConvexHullShape shape = new ConvexHullShape(vertices);
ShapeHull hull = new ShapeHull(shape);
hull.buildHull(shape.getMargin());
ConvexHullShape newShape = new ConvexHullShape(hull.getVertexPointer());
CollisionObject result = newShape;
Я считаю, что это преобразует уже созданную сетку, которую я использую для рендеринга своей сущности, из Vector3f библиотеки LWJGL и Jbullets Vector3f. Затем он создает ConvexHullShape из этих вершин в сетке, и я считаю, что:
hull.buildHull(shape.getMargin());
предполагается как бы упростить сетку (из документации). Затем я просто создаю объект столкновения. Довольно просто, я думаю...
Я создаю свое твердое тело (хотя я не уверен, что мне нужно твердое тело или просто объект столкновения, и если бы кто-нибудь мог сообщить мне, правда ли это, это было бы здорово):
//mass = 0, so that there is not any gravity application?
float mass = 0;
Transform transform = new Transform(new Matrix4f(new Quat4f(rotation.x, rotation.y, rotation.z, 1), position, scale));
this.transform = transform;
MotionState state = new DefaultMotionState(transform);
RigidBodyConstructionInfo info = new RigidBodyConstructionInfo(mass, state, shape);
RigidBody body = new RigidBody(info);
Затем я прохожу свой игровой цикл:
dynamicsWorld.stepSimulation(DisplayManager.getFrameTimeSeconds(), 7);
dynamicsWorld.performDiscreteCollisionDetection();
dynamicsWorld.setInternalTickCallback(new InternalTickCallback(){
@Override
public void internalTick(DynamicsWorld world, float delta) {
Dispatcher dispatcher = world.getDispatcher();
int manifoldCount = dispatcher.getNumManifolds();
for(int i = 0; i < manifoldCount; i ++){
PersistentManifold manifold = dispatcher.getManifoldByIndexInternal(i);
RigidBody object1 = (RigidBody)manifold.getBody0();
RigidBody object2 = (RigidBody)manifold.getBody1();
CollisionObject physicsObject1 = (CollisionObject)object1.getUserPointer();
CollisionObject physicsObject2 = (CollisionObject)object2.getUserPointer();
boolean contact = false;
javax.vecmath.Vector3f normal = null;
for (int j = 0; j < manifold.getNumContacts(); j++) {
ManifoldPoint contactPoint = manifold.getContactPoint(j);
if (contactPoint.getDistance() < 0.0f) {
contact = true;
normal = contactPoint.normalWorldOnB;
break;
}
}
if (contact) {
System.out.println("hit");
}
}
}
}, null);
Я получил это от кого-то... Я забыл, хотя где. Итак, в основном ничего не происходит... Я не уверен, но, возможно, мне нужно добавить объекты в коллектор или что-то в этом роде. Не знаю, как это сделать. Любая помощь?
РЕДАКТИРОВАТЬ: Теперь я создал форму столкновения в виде поля случайного размера:
CollisionShape result = new BoxShape(new Vector3f(10,10,10));
Затем я создаю Тело призрака:
Transform transform = new Transform(new Matrix4f(new Quat4f(rotation.x, rotation.y, rotation.z, 1), position, scale));
this.transform = transform;
transform.origin.set(position);
GhostObject body = new GhostObject();
body.setCollisionShape(shape);
body.setWorldTransform(transform);
тогда я просто делаю, как вы сказали, он все равно не возвращает "попадание";
int overlaps = player.getPhysics().getBody().getNumOverlappingObjects();
for(int i = 0; i < overlaps; i++){
//player.getPhysics().getBody().getOverlappingObject(i).
System.out.println("hit");
}
РЕДАКТИРОВАТЬ 2:
Итак, я создаю объект в своем классе сущностей следующим образом:
if(collision){
physics = new PhysicsEntity(dynamicsWorld, model,new javax.vecmath.Vector3f(position.x, position.y, position.z), new javax.vecmath.Vector3f(rotX, rotY, rotZ), scale);
physics.updatePosition(new javax.vecmath.Vector3f(position.x, position.y, position.z));
physics.updateRotation(new javax.vecmath.Vector3f(rotX, rotY, rotZ));
}
и обновить позицию и прочее:
public void increasePosition(float dx,float dy, float dz){
this.position.x += dx;
this.position.y += dy;
this.position.z += dz;
physics.updatePosition(new javax.vecmath.Vector3f(position.x, position.y, position.z));
}
public void increaseRotation(float dx, float dy, float dz){
this.rotX += dx;
this.rotY += dy;
this.rotZ += dz;
physics.updateRotation(new javax.vecmath.Vector3f(rotX, rotY, rotZ));
}
Итак, это мой класс PhysicsEntity, где я его настроил:
public PhysicsEntity(DynamicsWorld world, TexturedModel model, Vector3f position, Vector3f rotation, float scale){
this.model = model;
this.position = position;
this.rotation = rotation;
this.scale = scale;
shape = createShape();
body = createBody();
object = new CollisionObject();
object.setCollisionShape(shape);
world.addCollisionObject(body);
}
private GhostObject createBody(){
Transform transform = new Transform(new Matrix4f(new Quat4f(rotation.x, rotation.y, rotation.z, 1), position, scale));
this.transform = transform;
transform.origin.set(position);
GhostObject body = new GhostObject();
body.setCollisionShape(shape);
body.setWorldTransform(transform);
return body;
}
private CollisionShape createShape(){
CollisionShape result = new BoxShape(new Vector3f(10,10,10));
return result;
}
public void updatePosition(Vector3f position){
transform.origin.set(position);
body.setWorldTransform(transform);
}
public void updateRotation(Vector3f rotation){
transform.basis.set(new Quat4f(rotation.x, rotation.y, rotation.z, 1));
body.setWorldTransform(transform);
}
Спасибо,