Bagaimana cara menginduksi peristiwa tabrakan di LibGDX 3D?


9

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:

Hasil


Anda dapat mendeteksi apakah dia ada di kotak (Jika y-nya <box.y && y> box.y + box. Tinggi dan lakukan sekitar sama untuk x dan z jika Anda mau, Kemudian ubah Y-nya dengan kecepatannya)
Artsicle

Jawaban:


1

Mesin fisika yang saya tulis bekerja dalam tiga langkah

Setiap bingkai:

  1. Semua benda fisika menghitung vektor kecepatannya sendiri
  2. Mesin fisika berputar melalui objek dan memperbarui posisi baru mereka berdasarkan

    posisi + = kecepatan * deltaTime;

  3. 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.

  1. Tumpang tindih Dasar

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

  1. Deteksi tabrakan tersapu

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.