ฉันจะชักนำให้เกิดเหตุการณ์การชนใน LibGDX 3D ได้อย่างไร


9

ในรหัสด้านล่างฉันได้ยกตัวอย่างของสิ่งที่ฉันต้องการจะทำ ฉันมีกล้องถ่ายรูปและฉันต้องการให้มันหยุดเคลื่อนไหวเมื่อใดก็ตามที่กระทบกับกล่องใดกล่องหนึ่งฉันจะทำสิ่งนี้ได้อย่างไร

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

ผลลัพธ์:

ผลลัพธ์


คุณสามารถตรวจสอบว่าเขาอยู่ในกล่อง (ถ้า y ของเขาคือ <box.y && y> box.y + box.height และทำรอบเหมือนกันสำหรับ x และ z หากคุณต้องการจากนั้นเปลี่ยน Y ของเขาด้วยความเร็วของเขา)
Artsicle

คำตอบ:


1

เอ็นจิ้นฟิสิกส์ที่ฉันได้เขียนทำงานในสามขั้นตอน

แต่ละเฟรม:

  1. วัตถุฟิสิกส์ทั้งหมดคำนวณเวกเตอร์ความเร็วของตนเอง
  2. เอนจินของฟิสิกส์จะวนลูปผ่านวัตถุและอัพเดทตำแหน่งใหม่ตาม

    ตำแหน่ง + = ความเร็ว * deltaTime;

  3. เครื่องยนต์ฟิสิกส์ช่วยแก้ไขการชนทั้งหมด

อันดับแรกฉันขอแนะนำว่าแทนที่จะให้ FirstPersonCameraController ของคุณกำหนดตำแหน่งของกล้องสร้างกล้องเป็นวัตถุฟิสิกส์โดยให้ FirstPersonCameraController ควบคุมความเร็วของกล้องไม่ใช่ตำแหน่งแล้วปล่อยให้กลไกฟิสิกส์อัพเดทตำแหน่งของกล้อง

การเขียนกลไกทางฟิสิกส์อาจฟังดูน่ากลัว แต่จริงๆแล้วมันเป็นเพียงวิธีการหนึ่งที่เคลื่อนย้ายวัตถุทั้งหมดในฉากและจากนั้นตรวจสอบให้แน่ใจว่าวัตถุที่เป็นของแข็งไม่ทับซ้อนกัน

สุดท้ายนี้ขึ้นอยู่กับความต้องการของคุณมีสองวิธีที่ฉันใช้เพื่อแก้ไขการชน

  1. การทับซ้อนขั้นพื้นฐาน

หลังจากเครื่องยนต์ฟิสิกส์ของคุณเคลื่อนย้ายวัตถุทุกอย่าง จากนั้นวนซ้ำวัตถุเพื่อดูว่ามีการทับซ้อนกัน หากมีการทับซ้อนกันพวกเขาจะชนกัน คุณต้องตัดสินใจว่าจะแก้ไขการชนกันอย่างไร แต่โดยปกติหมายความว่าคุณย้ายวัตถุหนึ่งหรือทั้งสองอย่างไปข้างหลังจนกว่าจะไม่ทับซ้อนกันอีกต่อไป

ข้อเสียเปรียบที่ใหญ่ที่สุดในวิธีนี้เรียกว่าสัญลักษณ์แสดงหัวข้อย่อยผ่านปัญหากระดาษ หากกล้องของคุณเคลื่อนที่เร็วพอที่จะผ่านทั้งก้อนในหนึ่งเฟรมจากนั้นเมื่อคุณตรวจสอบการชนคุณจะไม่ลงทะเบียนว่าวัตถุทั้งสองชนกัน มีวิธีที่จะเอาชนะสิ่งนี้ได้เช่นทำให้แน่ใจว่าไม่มีวัตถุใดเข้ามาอย่างรวดเร็วและแก้ไขการประทับเวลาของคุณ

  1. ตรวจจับการชนกันของข้อมูลกวาด

ฉันประสบความสำเร็จหลายอย่างด้วยวิธีนี้ โดยพื้นฐานแล้วแนวคิดก็คือคุณสามารถรวมการเคลื่อนไหวและขั้นตอนการตรวจสอบการชนกันเพื่อกำหนดว่าได้รับเวกเตอร์ความเร็วของวัตถุสองอันเวลาใดที่พวกเขาจะชนกันหากพวกเขาจะชนกันทั้งหมด การเจาะลึกลงไปถึงวิธีการทำสิ่งนี้ให้สำเร็จนั้นอยู่นอกเหนือขอบเขตสำหรับการตอบสนองที่มีมานานแล้ว แต่นี่เป็นบทความที่ดี

วิธีนี้แก้ปัญหา bullet ผ่านกระดาษ แต่มันยากที่จะเข้าใจ / นำไปใช้รวมถึงการคำนวณที่แพงกว่า

อาจมีวิธีเพิ่มเติมที่อาจเป็นประโยชน์กับคุณโดยการค้นหาอินเทอร์เน็ตเพื่อตรวจหาการชนกันของข้อมูล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.