Làm cách nào để tạo ra các sự kiện va chạm trong LibGDX 3D?


9

Trong đoạn mã dưới đây tôi đã đưa ra một ví dụ về điều gì đó tôi muốn làm. Tôi có máy ảnh và tôi muốn nó ngừng di chuyển bất cứ khi nào nó chạm vào một trong các hộp, làm thế nào để tôi làm điều này?

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

Kết quả:

Kết quả


Bạn có thể phát hiện nếu anh ta ở trên một hộp (Nếu y của anh ta là <box.y && y> box.y + box.height và làm xung quanh tương tự cho x và z nếu bạn muốn, sau đó thay đổi Y của anh ta bằng vận tốc của anh ta)
Nghệ thuật

Câu trả lời:


1

Các công cụ vật lý mà tôi đã viết công việc trong ba bước

Mỗi khung:

  1. Tất cả các đối tượng vật lý tính toán véc tơ vận tốc của riêng họ
  2. Động cơ vật lý vòng qua các đối tượng và cập nhật vị trí mới của chúng dựa trên

    vị trí + = vận tốc * deltaTime;

  3. Động cơ vật lý giải quyết tất cả các va chạm

Trước tiên, tôi khuyên bạn thay vì để FirstPersonCameraContoder của bạn đặt vị trí của máy ảnh, hãy biến máy ảnh thành đối tượng vật lý bằng cách để FirstPersonCameraCont kiểm soát vận tốc của máy ảnh, không phải vị trí và sau đó để động cơ vật lý cập nhật vị trí của Máy ảnh.

Viết một công cụ vật lý nghe có vẻ đáng sợ, nhưng nó thực sự chỉ là một phương pháp di chuyển tất cả các vật thể trong một cảnh và sau đó đảm bảo rằng các vật thể rắn không bị chồng chéo.

Cuối cùng, tùy thuộc vào nhu cầu của bạn, có hai cách tiếp cận mà tôi đã sử dụng để giải quyết các va chạm.

  1. Chồng chéo cơ bản

Sau khi động cơ vật lý của bạn đã di chuyển mọi đối tượng. Sau đó lặp qua các đối tượng để xem cái nào đang chồng chéo. Nếu có chồng chéo thì chúng đã va chạm. Bạn phải quyết định cách giải quyết vụ va chạm này, nhưng thông thường, điều này có nghĩa là bạn di chuyển một hoặc cả hai đối tượng cho đến khi chúng không còn chồng chéo.

Hạn chế lớn nhất của phương pháp này được gọi là viên đạn thông qua vấn đề giấy. Nếu máy ảnh của bạn di chuyển đủ nhanh để nó đi qua toàn bộ một khối trong một khung hình, thì khi bạn kiểm tra va chạm, bạn sẽ không đăng ký rằng hai vật thể va chạm. Có nhiều cách để khắc phục điều này như đảm bảo rằng không có đối tượng nào đi quá nhanh và sửa lỗi thời gian của bạn

  1. Phát hiện va chạm quét

Tôi đã thành công khác nhau với phương pháp này. Về cơ bản, ý tưởng là bạn có thể kết hợp pha phát hiện chuyển động và va chạm để xác định rằng vectơ vận tốc của hai vật thể, chúng sẽ va chạm vào thời gian nào nếu chúng va chạm vào nhau. Đi sâu vào cách thực hiện điều này nằm ngoài phạm vi cho phản hồi đã có từ lâu này, nhưng đây là một bài viết hay

Phương pháp này giải quyết viên đạn thông qua một vấn đề trên giấy, nhưng khó hiểu / thực hiện hơn cũng như tốn kém hơn về mặt tính toán.

Có thể có nhiều phương pháp hơn có thể có lợi cho bạn bằng cách tìm kiếm trên internet để phát hiện va chạm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.