LibGDX 3D'de çarpışma olaylarını nasıl indükleyebilirim?


9

Aşağıdaki kodda ben yapmak istiyorum bir şey bir örnek koydum. Kameram var ve kutulardan birine çarptığında hareket etmeyi bırakmasını istiyorum, bunu nasıl yapabilirim?

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();
    }
}

Sonuç:

Sonuç


Bir kutuda olup olmadığını tespit edebilirsiniz (eğer y'sı <box.y && y> box.y + box.height ve isterseniz x ve z için aynı şeyi yapın, sonra Y'sini hızına göre değiştirin)
Artsicle

Yanıtlar:


1

Yazdığım fizik motorları üç adımda çalışıyor

Her çerçeve:

  1. Tüm fizik nesneleri kendi hız vektörlerini hesaplar
  2. Fizik motoru nesneler arasında dolaşır ve yeni konumlarını

    konum + = hız * deltaTime;

  3. Fizik motoru tüm çarpışmaları çözer

İlk olarak, FirstPersonCameraController kameranızın konumunu ayarlamasına izin vermek yerine, FirstPersonCameraController'ın kameranın hızını kontrol etmesini sağlayarak kamerayı bir fizik nesnesi yapmasını ve ardından fizik motorunun Kameranın konumunu güncellemesini sağlamanızı öneririm.

Bir fizik motoru yazmak korkutucu gelebilir, ancak gerçekten sadece bir sahnedeki tüm nesneleri hareket ettiren ve daha sonra katı nesnelerin üst üste binmediğinden emin olan bir yöntemdir.

Son olarak, ihtiyaçlarınıza bağlı olarak, çarpışmaları çözmek için kullandığım iki yaklaşım var.

  1. Temel Çakışma

Fizik motorunuz her nesneyi hareket ettirdikten sonra. Ardından, üst üste binenleri görmek için nesneler arasında dolaşın. Herhangi biri çakışıyorsa çarpıştılar. Bu çarpışmanın nasıl çözüleceğine karar vermelisiniz, ancak bu genellikle bir veya iki nesneyi artık çakışmayacak şekilde geriye doğru hareket ettirdiğiniz anlamına gelir.

Bu yaklaşımın en büyük dezavantajı kağıt sorunuyla kurşun olarak adlandırılmaktadır. Kameranız bir küp içinde tüm bir küpün içinden geçecek kadar hızlı hareket ediyorsa, çarpışmaları kontrol ettiğinizde, iki nesnenin çarpıştığını kaydetmezsiniz. Bunun üstesinden gelmenin, hiçbir nesnenin korkunç bir şekilde hızlı gitmemesini sağlamak ve zamanınızı düzeltmek gibi yollar vardır.

  1. Süpürme çarpışma tespiti

Bu yöntemle çeşitli başarılar elde ettim. Temel olarak fikir, iki nesnenin hız vektörleri verildiğinde, çarpışacaklarsa ne zaman çarpışacaklarını belirlemek için hareket ve çarpışma algılama aşamasını birleştirebilmenizdir. Bunu nasıl başaracağınız konusunda derinlemesine konuşmak, zaten uzun olan bu yanıtın kapsamı dışındadır, ancak burada iyi bir makale

Bu yöntem, mermiyi bir kağıt problemi ile çözer, ancak anlaşılması / uygulanması daha zor ve hesaplama açısından daha pahalıdır.

Çarpışma tespiti için internette arama yaparak size fayda sağlayabilecek daha fazla yöntem olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.