pmndrs / drei

🥉 useful helpers for react-three-fiber
https://docs.pmnd.rs/drei
MIT License
8.4k stars 703 forks source link

How to use TransformControls to drag objects, and change there positions. #1136

Closed ajitStephen closed 1 week ago

ajitStephen commented 2 years ago

Step 1: I want to activate TransformControls on selection of object, perhaps onClick on mesh. [DONE] Step 2: I want to use TransformControls to drag the #D Object in scene to the wanted place. [DONE]

Step 3: Once drag is finished i want to deactivate TransformControls, and fetch new position of 3D Object moved [I don't know how ?]

I tried to do this with ThreeJS example, it worked:


            import * as THREE from "three";

            import { OrbitControls } from "three/addons/controls/OrbitControls.js";
            import { TransformControls } from "three/addons/controls/TransformControls.js";

            let cameraPersp, cameraOrtho, currentCamera;
            let scene, renderer, control, orbit;

            init();
            render();

            // eslint-disable-next-line padded-blocks
            function init() {
                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio(window.devicePixelRatio);
                renderer.setSize(window.innerWidth, window.innerHeight);
                document.body.appendChild(renderer.domElement);

                const aspect = window.innerWidth / window.innerHeight;

                cameraPersp = new THREE.PerspectiveCamera(50, aspect, 0.01, 30000);
                cameraOrtho = new THREE.OrthographicCamera(
                    // eslint-disable-next-line space-unary-ops
                    -600 * aspect,
                    600 * aspect,
                    600,
                    -600,
                    0.01,
                    30000
                );
                currentCamera = cameraPersp;

                currentCamera.position.set(1000, 500, 1000);
                currentCamera.lookAt(0, 200, 0);

                scene = new THREE.Scene();
                scene.add(new THREE.GridHelper(1000, 10, 0x888888, 0x444444));

                const light = new THREE.DirectionalLight(0xffffff, 2);
                light.position.set(1, 1, 1);
                scene.add(light);

                const texture = new THREE.TextureLoader().load(
                    "textures/crate.gif",
                    render
                );
                texture.anisotropy = renderer.capabilities.getMaxAnisotropy();

                const geometry = new THREE.BoxGeometry(200, 200, 200);

                const material = new THREE.MeshLambertMaterial({
                    map: texture,
                    transparent: true,
                });

                orbit = new OrbitControls(currentCamera, renderer.domElement);
                orbit.update();
                orbit.addEventListener("change", render);

                control = new TransformControls(currentCamera, renderer.domElement);
                control.addEventListener("change", render);

                control.addEventListener("dragging-changed", function (event) {
                    console.log("dragging-changed ", event);
                    if (!event.value) {
                        control.detach();
                        console.log("check mesh", mesh);
                    }

                    orbit.enabled = !event.value;
                });

                const mesh = new THREE.Mesh(geometry, material);
                console.log("check mesh:: ", mesh);

                mesh.position.set(
                    -176.437045359281,
                    -453.50358426586854,
                    403.188837492333
                );

                scene.add(mesh);

                control.attach(mesh);
                scene.add(control);

                window.addEventListener("resize", onWindowResize);

                window.addEventListener("keydown", function (event) {
                    switch (event.keyCode) {
                        case 81: // Q
                            control.setSpace(control.space === "local" ? "world" : "local");
                            break;

                        case 16: // Shift
                            control.setTranslationSnap(100);
                            control.setRotationSnap(THREE.MathUtils.degToRad(15));
                            control.setScaleSnap(0.25);
                            break;

                        case 87: // W
                            control.setMode("translate");
                            break;

                        case 69: // E
                            control.setMode("rotate");
                            break;

                        case 82: // R
                            control.setMode("scale");
                            break;

                        case 67: // C
                            const position = currentCamera.position.clone();

                            currentCamera = currentCamera.isPerspectiveCamera
                                ? cameraOrtho
                                : cameraPersp;
                            currentCamera.position.copy(position);

                            orbit.object = currentCamera;
                            control.camera = currentCamera;

                            currentCamera.lookAt(
                                orbit.target.x,
                                orbit.target.y,
                                orbit.target.z
                            );
                            onWindowResize();
                            break;

                        case 86: // V
                            const randomFoV = Math.random() + 0.1;
                            const randomZoom = Math.random() + 0.1;

                            cameraPersp.fov = randomFoV * 160;
                            cameraOrtho.bottom = -randomFoV * 500;
                            cameraOrtho.top = randomFoV * 500;

                            cameraPersp.zoom = randomZoom * 5;
                            cameraOrtho.zoom = randomZoom * 5;
                            onWindowResize();
                            break;

                        case 187:
                        case 107: // +, =, num+
                            control.setSize(control.size + 0.1);
                            break;

                        case 189:
                        case 109: // -, _, num-
                            control.setSize(Math.max(control.size - 0.1, 0.1));
                            break;

                        case 88: // X
                            control.showX = !control.showX;
                            break;

                        case 89: // Y
                            control.showY = !control.showY;
                            break;

                        case 90: // Z
                            control.showZ = !control.showZ;
                            break;

                        case 32: // Spacebar
                            control.enabled = !control.enabled;
                            break;

                        case 27: // Esc
                            control.reset();
                            break;
                    }
                });

                window.addEventListener("keyup", function (event) {
                    switch (event.keyCode) {
                        case 16: // Shift
                            control.setTranslationSnap(null);
                            control.setRotationSnap(null);
                            control.setScaleSnap(null);
                            break;
                    }
                });
            }

            function onWindowResize() {
                const aspect = window.innerWidth / window.innerHeight;

                cameraPersp.aspect = aspect;
                cameraPersp.updateProjectionMatrix();

                cameraOrtho.left = cameraOrtho.bottom * aspect;
                cameraOrtho.right = cameraOrtho.top * aspect;
                cameraOrtho.updateProjectionMatrix();

                renderer.setSize(window.innerWidth, window.innerHeight);

                render();
            }

            function render() {
                renderer.render(scene, currentCamera);
            }
DennisSmolek commented 2 years ago

If you look at the original Three version you see it has a mouseUp event that you should be able to listen to as well. https://threejs.org/docs/#examples/en/controls/TransformControls

You could also probably use the R3F onPointerUp={(e) => console.log('up')} https://docs.pmnd.rs/react-three-fiber/api/events

Then I'd look into the newer Pivot Controls which have way more options and seems to be the way Paul and others are leaning for more futureproof controls.

https://github.com/pmndrs/drei#pivotcontrols

it actually has onDragEnd

github-actions[bot] commented 2 weeks ago

Thank you for contributing! We’re marking this issue as stale as a gentle reminder to revisit it and give it the attention it needs to move forward.

Any activity, like adding an update or comment, will automatically remove the stale label so it stays on our radar.

Feel free to reach out on Discord if you need support or feedback from the community. This issue will close automatically soon if there’s no further activity. Thank you for understanding and for being part of the project!

github-actions[bot] commented 1 week ago

We’re closing this issue to keep our project manageable and make room for other active work, but we truly appreciate your effort and contribution.

If you’d like to continue working on this, please feel free to re-open it or reach out on Discord — our community is always ready to support you. Thanks again for helping us stay organized and for understanding our approach!