简体   繁体   English

我想知道如何使用鼠标围绕THREE.JS创建的网格的Z轴旋转

[英]I would like to know how to rotate around Z-axis of a mesh created with THREE.JS using the mouse

I'm implementing the function to rotate the mesh using the mouse. 我正在实现使用鼠标旋转网格的功能。

referencing code is linked site. 引用代码是链接站点。 (" http://3dit.bordeaux.inria.fr/testbed.html#navigation_Map_Navigation ") (“ http://3dit.bordeaux.inria.fr/testbed.html#navigation_Map_Navigation ”)

I would like to know how to use the mouse to rotate around the Z axis (red line). 我想知道如何使用鼠标绕Z轴(红线)旋转。

I have found that all of the examples in Three.js have only a way to rotate around the x or y axis. 我发现Three.js中的所有示例都只能绕x或y轴旋转。

Really need help. 真的需要帮助。


My code : https://jsfiddle.net/pfk7j7a3/3/ 我的代码: https : //jsfiddle.net/pfk7j7a3/3/

<script type="text/javascript">
    CustomOrbit = function () {
        var EPS = 0.000001;
        var rotateStart = new THREE.Vector2();
        var rotateEnd = new THREE.Vector2();
        var rotateDelta = new THREE.Vector2();

        var phiDelta = 0;
        var thetaDelta = 0;

        var target = new THREE.Vector3();

        /// How far you can orbit vertically, upper and lower limits.
        var minPolarAngle = Math.PI / 2;
        var maxPolarAngle = Math.PI * 0.91;

        var onMouseDownPosition = new THREE.Vector2();

        this.Initialize = function () {
            renderer.domElement.addEventListener('mousedown', onMouseDown, false);
        }

        var onMouseMove = function (event) {
            event.preventDefault();
            rotateEnd.set(event.clientX, event.clientY);
            rotateDelta.subVectors(rotateEnd, rotateStart);

            thetaDelta -= 2 * Math.PI * rotateDelta.x / renderer.domElement.clientWidth;
            phiDelta -= 2 * Math.PI * rotateDelta.y / renderer.domElement.clientHeight;

            var position = camera.position;
            var offset = position.clone().sub(target);

            // angle from z-axis around y-axis          
            var theta = Math.atan2(offset.x, offset.z);
            theta += thetaDelta;

            // angle from y-axis
            var phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y);
            phi += phiDelta;
            phi = Math.max(minPolarAngle, Math.min(maxPolarAngle, phi));// restrict phi to be between desired limits
            phi = Math.max(EPS, Math.min(Math.PI - EPS, phi));          // restrict phi to be between EPS and PI-EPS

            var radius = offset.length();
            radius = Math.max(0, Math.min(Infinity, radius)); // restrict radius to be between desired limits

            offset.x = radius * Math.sin(phi) * Math.sin(theta);
            offset.y = radius * Math.cos(phi);
            offset.z = radius * Math.sin(phi) * Math.cos(theta);

            position.copy(target).add(offset);

            camera.lookAt(target);

            thetaDelta = 0;
            phiDelta = 0;

            rotateStart.copy(rotateEnd);
        }
        var onMouseUp = function (event) {
            renderer.domElement.removeEventListener('mousemove', onMouseMove, false);
            renderer.domElement.removeEventListener('mouseup', onMouseUp, false);
        }

        var onMouseDown = function (event) {
            event.preventDefault();

            vector = new THREE.Vector3(0, 0, camera.near);
            vector.unproject(camera);
            raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize(), camera.near, camera.far);
            intersects = raycaster.intersectObject(pickingMesh);

            if (intersects.length > 0) {
                target = intersects[0].point;
                rotateStart.set(event.clientX, event.clientY);

                renderer.domElement.addEventListener('mousemove', onMouseMove, false);
                renderer.domElement.addEventListener('mouseup', onMouseUp, false);
            }
        }
    };
</script>
<script type="text/javascript">
    var camera, scene, renderer, pickingMesh, rendWidth = 500, rendHeight = 500;
    init();
    makeMesh();
    makeAxis(200);
    animate();

    function init() {
        scene = new THREE.Scene();
        renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
        renderer.setSize(500, 500);
        document.body.appendChild(renderer.domElement);

        camera = new THREE.PerspectiveCamera(55, 500 / 500, 0.1, 10000);
        camera.position.x = 200000;
        camera.position.y = 400000;
        camera.position.z = 300;
        camera.lookAt(new THREE.Vector3(200000, 400000, 0.0));
    }

    function animate() {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
    }


    //create red square mesh
    function makeMesh() {
        var geometry = new THREE.BufferGeometry();
        var vertices = new Float32Array([
            200000 - 100.0, 400000 - 100.0, 0.0,
            200000 + 100.0, 400000 + 100.0, 0.0,
            200000 - 100.0, 400000 + 100.0, 0.0,

            200000 - 100.0, 400000 - 100.0, 0.0,
            200000 + 100.0, 400000 - 100.0, 0.0,
            200000 + 100.0, 400000 + 100.0, 0.0
        ]);

        geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
        var material = new THREE.MeshBasicMaterial({ color: 0xff0000, transparent: true, opacity: 0.5 });
        material.side = THREE.DoubleSide;
        pickingMesh = new THREE.Mesh(geometry, material);

        scene.add(pickingMesh);
    }

    function makeAxis(axisLength) {
        var x_axis = new THREE.Geometry(); x_axis.vertices.push(new THREE.Vector3(200000 - axisLength, 400000, 0), new THREE.Vector3(200000 + axisLength, 400000, 0));
        var y_axis = new THREE.Geometry(); y_axis.vertices.push(new THREE.Vector3(200000, 400000 - axisLength, 0), new THREE.Vector3(200000, 400000 + axisLength, 0));
        var z_axis = new THREE.Geometry(); z_axis.vertices.push(new THREE.Vector3(200000, 400000, -axisLength), new THREE.Vector3(200000, 400000, axisLength));
        var x_axis_line = new THREE.Line(x_axis, new THREE.LineBasicMaterial({ linewidth: 1, transparent: true, color: 0x0000ff }));
        var y_axis_line = new THREE.Line(y_axis, new THREE.LineBasicMaterial({ linewidth: 1, transparent: true, color: 0x00ff00 }));
        var z_axis_line = new THREE.Line(z_axis, new THREE.LineBasicMaterial({ linewidth: 1, transparent: true, color: 0xff0000 }));
        scene.add(x_axis_line);
        scene.add(y_axis_line);
        scene.add(z_axis_line);
    };

    var myOrbit = new CustomOrbit();
    myOrbit.Initialize();
</script>

If you try to rotate out of 0,0,0 position (camera around something, object on some position around center), mathematics will start to be more complicated. 如果尝试旋转到0,0,0位置(照相机围绕某物,物体围绕中心在某个位置),则数学将变得更加复杂。

My best experience is with orbit controls. 我最好的经验是使用轨道控制。 https://threejs.org/examples/misc_controls_orbit.html https://threejs.org/examples/misc_controls_orbit.html

You can set a angle limitation and pan limitation. 您可以设置角度限制和平移限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM