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를 변경하십시오)
기사

답변:


1

내가 쓴 물리 엔진은 세 단계로 작업합니다

각 프레임 :

  1. 모든 물리 객체는 자체 속도 벡터를 계산합니다
  2. 물리 엔진은 객체를 반복하고 다음을 기반으로 새 위치를 업데이트합니다.

    위치 + = 속도 * deltaTime;

  3. 물리 엔진은 모든 충돌을 해결합니다

먼저, FirstPersonCameraController가 카메라의 위치를 ​​설정하게하는 대신 FirstPersonCameraController가 위치가 아닌 카메라의 속도를 제어하도록하여 물리 엔진이 카메라의 위치를 ​​업데이트하도록함으로써 카메라를 물리 객체로 만드는 것이 좋습니다.

물리 엔진을 작성하는 것은 무섭게 들릴 수 있지만 실제로는 장면의 모든 객체를 이동시킨 다음 솔리드 객체가 겹치지 않도록하는 방법 일뿐입니다.

마지막으로, 필요에 따라 충돌을 해결하는 데 사용한 두 가지 방법이 있습니다.

  1. 기본 겹침

물리 엔진이 모든 물체를 움직 인 후. 그런 다음 객체를 반복하여 겹치는 것을 확인하십시오. 중복되는 것이 있으면 충돌 한 것입니다. 이 충돌을 해결하는 방법을 결정해야하지만 일반적으로 이는 더 이상 겹치지 않을 때까지 하나 또는 두 객체를 뒤로 이동한다는 의미입니다.

이 방법의 가장 큰 단점은 용지 문제를 통한 총알이라고합니다. 카메라가 한 프레임에서 전체 큐브를 통과 할만큼 충분히 빠르게 움직이면 충돌을 확인할 때 두 객체가 충돌 한 것으로 등록되지 않습니다. 어떤 물체도 엄청나게 빠르지 않게하고 시간 단계를 고치는 등이를 극복 할 수있는 방법이 있습니다

  1. 스윕 충돌 감지

이 방법으로 다양한 성공을 거두었습니다. 기본적으로 아이디어는 움직임과 충돌 감지 단계를 결합하여 두 물체의 속도 벡터가 주어지면 충돌 할 때 충돌하는 시간을 결정할 수 있다는 것입니다. 이것을 달성하는 방법에 대해 깊이 들어가는 것은 이미 오래 전부터 응답하지 않았지만 여기 에 좋은 기사가 있습니다.

이 방법은 종이 문제를 통해 총알을 해결하지만 이해하기가 어렵고 계산 비용이 많이 듭니다.

충돌 감지를 위해 인터넷을 검색하면 도움이 될 수있는 더 많은 방법이있을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.