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



我正在实现使用鼠标旋转网格的功能。

引用代码是链接站点。("http://3dit.bordeaux.inria.fr/testbed.html#navigation_Map_Navigation"(

我想知道如何使用鼠标绕 Z 轴(红线(旋转。

我发现 Three.js 中的所有示例都只有一种绕 x 或 y 轴旋转的方法。

真的需要帮助。


我的代码 : 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>

如果你尝试从0,0,0位置旋转(相机围绕某物,物体围绕中心的某些位置(,数学将开始变得更加复杂。

我最好的经验是轨道控制。https://threejs.org/examples/misc_controls_orbit.html

您可以设置角度限制和声移限制。

相关内容

  • 没有找到相关文章

最新更新