Dalam kode di bawah ini saya telah memberikan contoh tentang sesuatu yang ingin saya lakukan. Saya memiliki kamera dan saya ingin berhenti bergerak setiap kali menyentuh salah satu kotak, bagaimana saya melakukan ini?
public class Main extends ApplicationAdapter {
private final ModelBuilder builder = new ModelBuilder();
private final Environment environment = new Environment();
private ModelBatch modelBatch;
private PerspectiveCamera camera;
private Model model;
private ArrayList<ModelInstance> instance = new ArrayList<ModelInstance>();
private FirstPersonCameraController controller;
private BoundingBox[] boxBounds = new BoundingBox[1000];
private BoundingBox cameraBox = new BoundingBox();
private Vector3 cameraSpeed = new Vector3();
private Vector3 oldCameraPos = new Vector3();
private Vector3 newCameraPos = new Vector3();
@Override
public void create() {
modelBatch = new ModelBatch();
//build the camera
camera = new PerspectiveCamera(67, graphics.getWidth(), graphics.getHeight());
camera.position.set(0f, 10f, 0f);
camera.lookAt(0, 10, 0);
camera.near = 1f;
camera.far = 1000f;
camera.update();
//build all the boxes
for (int i = 0; i < 1000; i++) {
model = builder.createBox(
(float) Math.random() * 50,
(float) Math.random() * 50,
(float) Math.random() * 50,
new Material(ColorAttribute.createDiffuse(
(float) random(),
(float) random(),
(float) random(), 1)
), Position | Normal);
instance.add(new ModelInstance(model));
instance.get(i).transform.setToTranslation(
(float) random() * 1000 - 500,
(float) random() * 1000,
(float) random() * 1000 - 500);
boxBounds[i] = new BoundingBox();
boxBounds[i] = model.calculateBoundingBox(boxBounds[i]);
}
//build the ground
model = builder.createBox(700f, 1f, 700f, new Material(ColorAttribute.createDiffuse(Color.GREEN)), Position | Normal);
ModelInstance ground = new ModelInstance(model);
instance.add(ground);
//build the center
model = builder.createBox(5f, 5f, 5f, new Material(ColorAttribute.createDiffuse(Color.RED)), Position | Normal);
ModelInstance center = new ModelInstance(model);
instance.add(center);
//code the lights here
DirectionalLight light = new DirectionalLight().set(255, 255, 255,
(float) random(),
(float) random(),
(float) random());
//set up the enviroment
environment.set(new ColorAttribute(AmbientLight, 255f, 255f, 255f, 1f));
environment.add(light);
//set up the camera controller
controller = new FirstPersonCameraController(camera);
controller.setDegreesPerPixel(0.25f);
controller.setVelocity(20);
input.setInputProcessor(controller);
}
@Override
public void render() {
//set up OpenGL
gl.glViewport(0, 0, graphics.getWidth(), graphics.getHeight());
gl.glEnable(GL_BLEND);
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl.glClearColor(0, 0, 0, 0);
//render the modelInstances
modelBatch.begin(camera);
modelBatch.render(instance, environment);
modelBatch.end();
controller.update();
if (input.isKeyPressed(Input.Keys.R)) {
camera.lookAt(0, 0, 0);
}
cameraSpeed = newCameraPos.sub(oldCameraPos);
cameraBox = new BoundingBox(new Vector3(camera.position.x,
camera.position.y,
camera.position.z),
new Vector3(camera.position.x + 10,
camera.position.y + 10,
camera.position.z + 10));
for (int i = 0; i < 1000; i++) {
if (cameraBox.contains(boxBounds[i])) {
camera.position.x = camera.position.x - cameraSpeed.x;
camera.position.y = camera.position.y - cameraSpeed.y;
camera.position.z = camera.position.z - cameraSpeed.z;
}
}
System.out.println(cameraSpeed.x + " " + cameraSpeed.y + " " + cameraSpeed.z);
}
@Override
public void dispose() {
modelBatch.dispose();
model.dispose();
}
}
Hasil:
java
collision-detection
3d
libgdx
SirMathhman
sumber
sumber
Jawaban:
Mesin fisika yang saya tulis bekerja dalam tiga langkah
Setiap bingkai:
Mesin fisika berputar melalui objek dan memperbarui posisi baru mereka berdasarkan
posisi + = kecepatan * deltaTime;
Mesin fisika menyelesaikan semua tabrakan
Pertama, saya menyarankan bahwa alih-alih membiarkan FirstPersonCameraController Anda mengatur posisi kamera, menjadikan kamera objek fisika dengan menyuruh FirstPersonCameraController mengontrol kecepatan kamera, bukan posisi, dan kemudian membiarkan mesin fisika memperbarui posisi Kamera.
Menulis mesin fisika mungkin terdengar menakutkan, tetapi itu sebenarnya hanya metode yang memindahkan semua objek dalam sebuah adegan dan kemudian memastikan bahwa benda padat tidak tumpang tindih.
Terakhir, tergantung pada kebutuhan Anda, ada dua pendekatan yang saya gunakan untuk menyelesaikan tabrakan.
Setelah mesin fisika Anda memindahkan setiap objek. Kemudian putar melalui objek untuk melihat yang tumpang tindih. Jika ada yang tumpang tindih maka mereka telah bertabrakan. Anda harus memutuskan bagaimana tabrakan ini akan diselesaikan, tetapi biasanya ini berarti bahwa Anda memindahkan satu atau kedua objek ke belakang sampai mereka tidak lagi tumpang tindih.
Kelemahan terbesar untuk pendekatan ini disebut peluru melalui masalah kertas. Jika kamera Anda bergerak cukup cepat sehingga melewati seluruh kubus dalam satu bingkai, maka ketika Anda memeriksa tabrakan, Anda tidak akan mengetahui bahwa kedua objek bertabrakan. Ada beberapa cara untuk mengatasinya seperti memastikan bahwa tidak ada objek yang berjalan sangat cepat dan memperbaiki catatan waktu Anda
Saya mendapatkan kesuksesan yang beragam dengan metode ini. Pada dasarnya idenya adalah bahwa Anda dapat menggabungkan fase deteksi gerakan dan tabrakan untuk menentukan bahwa dengan diberi vektor kecepatan dua benda, jam berapa mereka akan bertabrakan jika mereka akan bertabrakan sama sekali. Pergi lebih dalam tentang bagaimana mencapai ini di luar jangkauan untuk respon yang sudah lama ini, tapi di sini artikel yang bagus
Metode ini memecahkan peluru melalui masalah kertas, tetapi lebih sulit untuk memahami / mengimplementasikan serta lebih mahal secara komputasi.
Mungkin ada lebih banyak metode di luar sana yang mungkin menguntungkan Anda dengan mencari di internet untuk deteksi tabrakan.
sumber