मैं 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. भौतिकी इंजन वस्तुओं के माध्यम से घूमता है और उनके आधार पर अपने नए पदों को अपडेट करता है

    स्थिति + = वेग * डेल्टा टाइम;

  3. भौतिकी इंजन सभी टकरावों को हल करता है

सबसे पहले, मेरा सुझाव है कि अपने FirstPersonCameraController को कैमरे की स्थिति सेट करने देने के बजाय, FirstPersonCameraController कैमरा के वेग को नियंत्रित करके कैमरा को एक भौतिक वस्तु बनाएं, स्थिति नहीं, और फिर भौतिकी को कैमरा की स्थिति को अपडेट करने दें।

भौतिकी इंजन लिखना डरावना लग सकता है, लेकिन यह वास्तव में सिर्फ एक विधि है जो सभी वस्तुओं को एक दृश्य में ले जाता है और फिर सुनिश्चित करता है कि ठोस ऑब्जेक्ट ओवरलैपिंग नहीं कर रहे हैं।

अंत में, आपकी आवश्यकताओं के आधार पर, दो दृष्टिकोण हैं जिनका उपयोग मैंने टकरावों को हल करने के लिए किया है।

  1. बेसिक ओवरलैपिंग

आपके भौतिकी इंजन के बाद हर वस्तु चली गई है। फिर ऑब्जेक्ट्स के माध्यम से लूप करें जो देखने के लिए कि अतिव्यापी हैं। यदि कोई अतिव्यापी है तो वे टकरा गए हैं। आपको यह तय करना होगा कि इस टकराव को कैसे हल किया जाएगा, लेकिन आमतौर पर इसका मतलब है कि आप एक या दोनों वस्तुओं को पीछे की ओर ले जाते हैं जब तक कि वे अतिव्यापी नहीं होते हैं।

इस दृष्टिकोण की सबसे बड़ी कमी को पेपर समस्या के माध्यम से बुलेट कहा जाता है। यदि आपका कैमरा इतनी तेजी से आगे बढ़ रहा है कि वह एक फ्रेम में पूरे क्यूब से गुजरता है, तो जब आप टकराव की जांच करते हैं, तो आप यह दर्ज नहीं करेंगे कि दोनों ऑब्जेक्ट टकरा गए। इसे दूर करने के तरीके हैं जैसे कि यह सुनिश्चित करना कि कोई भी वस्तु बहुत तेजी से नहीं जाती है और आपके टाइमस्टेप को ठीक करती है

  1. टकराव का पता लगाने

मुझे इस पद्धति के साथ विविध सफलता मिली है। मूल रूप से यह विचार है कि आप दो वस्तुओं के वेग वाले वैक्टर को निर्धारित करने के लिए आंदोलन और टकराव का पता लगाने के चरण को जोड़ सकते हैं, यदि वे बिल्कुल टकराएंगे तो वे किस समय टकराएंगे। इसे पहले से ही लंबे समय तक प्रतिक्रिया देने की गुंजाइश से बाहर होने के बारे में गहराई से जाना, लेकिन यहां एक अच्छा लेख है

यह विधि एक पेपर समस्या के माध्यम से बुलेट को हल करती है, लेकिन इसे समझने / लागू करने के साथ-साथ अधिक कम्प्यूटेशनल रूप से महंगा होना कठिन है।

वहाँ और अधिक तरीके हो सकते हैं जो टकराव का पता लगाने के लिए इंटरनेट पर खोज करके आपको लाभान्वित कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.