J'ai donc passé beaucoup de temps à essayer de travailler sur un système de détection de collision à partir de zéro pour mon propre moteur de jeu et je suis tombé sans résultat faute de temps. Finalement, j'ai décidé d'essayer d'utiliser Jbullet pour essayer de faire les choses plus rapidement. Maintenant, la documentation est fondamentalement inutile, et j'ai un peu de mal à essayer de transférer le code à java (ou ce que je transfère ne fonctionne pas). J'ai arraché mes cheveux en essayant de fouiller dans le code de la bibliothèque, mais le gain de temps que j'espérais a été presque inutile. Donc, je vais vous expliquer ce que je fais, peut-être que vous pouvez m'aider. Je cherche seulement la détection simple de collision, comme si vous frappiez quelque chose alors juste imprimez une ligne pour le moment. Le reste, je peux probablement travailler seul.Détection de collision java 3D avec Jbullet
Je crée mon monde:
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;
J'ai donc ma classe d'entité et là j'ai une autre classe qui stocke toutes les informations de l'objet physique attaché à cette entité. Cela me permet de faire simplement:.. Entity.getPhysics() getCollisionObject()/setPosition() etc ...
Puis-je créer mon CollisionObject dans cette classe:
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;
Je crois que ce convertit déjà rendu maillage, que j'utilise pour rendre mon entité, à partir de Vector3f de la bibliothèque LWJGL, et Jbullets Vector3f. Il crée ensuite un ConvexHullShape de ces sommets dans le maillage, et je crois que:
hull.buildHull(shape.getMargin());
est censé simplifier type de maillage (de la documentation). Ensuite, je viens de créer l'objet de collision. Assez simple, je pense ...
Je crée mon corps rigide (bien que je ne sois pas sûr d'avoir besoin d'un corps rigide ou juste un objet de collision, et si quelqu'un pouvait me faire savoir si cela est vrai, ce serait génial) :
//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);
Puis je passe par ma boucle de jeu:
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);
J'ai eu ce de quelqu'un ... j'ai oublié où bien. Donc, fondamentalement rien ne se passe ... Je ne suis pas sûr mais peut-être que je dois ajouter les objets à la variété, ou quelque chose comme ça. Je ne sais pas comment le faire. De l'aide?
EDIT: Ce que je l'ai fait est maintenant créer la forme de collision comme une boîte de taille aléatoire:
CollisionShape result = new BoxShape(new Vector3f(10,10,10));
Puis je crée le fantôme du corps:
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);
alors je fais comme vous avez dit, il ne revient toujours pas "frapper";
int overlaps = player.getPhysics().getBody().getNumOverlappingObjects();
for(int i = 0; i < overlaps; i++){
//player.getPhysics().getBody().getOverlappingObject(i).
System.out.println("hit");
}
EDIT 2:
Je crée donc l'objet que comme dans ma classe d'entité:
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));
}
et mettre à jour la position et d'autres choses:
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));
}
Okay c'est ma classe PhysicsEntity, où je l'ai mise en place:
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);
}
Merci,
J'ai encore modifié ma réponse. Jetez un coup d'oeil si cela vous aide. – Estiny
Une clarification supplémentaire ajoutée. – Estiny
Sooo ... Encore un edit. Peut-être cette fois. – Estiny