そのため、自分のゲーム エンジンの衝突検出システムをゼロから作成することに長い時間を費やしましたが、時間がなくて成果がありませんでした。最後に、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;
これは、LWJGL ライブラリの Vector3f と Jbullets Vector3f からエンティティをレンダリングするために使用する、既に作成されたメッシュに変換されると思います。次に、メッシュ内のそれらの頂点から ConvexHullShape を作成します。私は次のように考えています。
hull.buildHull(shape.getMargin());
メッシュを単純化することになっています(ドキュメントから)。次に、衝突オブジェクトを作成します。かなり単純だと思います...
Rigidbody を作成します (ただし、Rigid Body が必要なのか、衝突オブジェクトが必要なのかわかりませんが、これが本当かどうかを誰かが教えてくれれば、それは素晴らしいことです):
//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);
}
ありがとう、