Three.js 使用鼠标绘制 3D 矩形

Three.js draw 3D rectangle using mouse

所以,我正在尝试使用鼠标绘制一个 3D 矩形。经过几个小时的尝试,我发布了这个问题。

我设法绘制了一个可调整大小的矩形。我通过编辑和更新顶点来做到这一点。

我做了一个 jsfiddle:https://jsfiddle.net/bgzrcx46/7/

我遇到了一些问题:

谁能帮我解决这个问题?

如果你想要普通的HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RSCEDIT - Test</title>

    <style>
        body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
        }
        #main {
            width: 100%;
            height: 100%;
            display: block;
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body>
    <div class="container">
        <canvas id="main"></canvas>
    </div>

    <script src="https://rscedit.io/assets/client/js/core/libraries/jquery.min.js"></script>

    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/three.min.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/Detector.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/controls/OrbitControls.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/Projector.js"></script>
    <script type="text/javascript" src="https://rscedit.io/assets/client/js/threejs/dat.gui.min.js"></script>

    <script>

        var canvas = document.getElementById('main');

        var renderer = new THREE.WebGLRenderer({
            canvas: canvas
        });

        var scene = new THREE.Scene();

        var camera = new THREE.PerspectiveCamera(45, canvas.clientWidth / canvas.clientHeight, 1, 100000);

        var geometry = new THREE.Geometry();

        var rayCaster = new THREE.Raycaster();

        var controls;

        var dragging = false;

        var startPosition = {
            x: 0,
            y: 0
        };

        var vertexSize = 2;

        onLoad();

        function onLoad() {

            canvas.onmousedown = onMouseDown;
            canvas.onmousemove = onDrag;
            canvas.onmouseup = onMouseUp;

            renderer.setSize(canvas.clientWidth, canvas.clientHeight);

            camera.position.set(0, 0, 25.0);
            scene.add(camera);

            /*
             * Create a Rectangle
             */
            geometry.vertices.push(new THREE.Vector3(-vertexSize, vertexSize, 0.0));
            geometry.vertices.push(new THREE.Vector3(vertexSize, vertexSize, 0.0));
            geometry.vertices.push(new THREE.Vector3(vertexSize, -vertexSize, 0.0));
            geometry.vertices.push(new THREE.Vector3(-vertexSize, -vertexSize, 0.0));
            geometry.faces.push(new THREE.Face3(0, 1, 2));
            geometry.faces.push(new THREE.Face3(0, 2, 3));

            var material = new THREE.MeshBasicMaterial({
                color: 0xDB1E1E,
                wireframe: true
            });

            var mesh = new THREE.Mesh(geometry, material);
            mesh.rotation.x = Math.PI / 2;
            scene.add(mesh);

            var gridSize = 20;
            var divisions = 20;
            var gridHelper = new THREE.GridHelper(gridSize, divisions);
            scene.add(gridHelper);

            controls = new THREE.OrbitControls(camera, renderer.domElement);

            render();
        }

        function update(index, x, y) {
            geometry.vertices[index].set(x, y, 0);
            geometry.verticesNeedUpdate = true;
        }

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

        function onMouseDown(e) {
            var relative = get3DPosition(e);
            if (!relative) {
                return;
            }
            dragging = true;
            startPosition.x = e.pageX;
            startPosition.y = e.pageY;
            scene.children[1].position.set(relative.x + vertexSize, relative.y, relative.z);
            controls.enabled = false;
        }

        function onDrag(e) {
            if (dragging) {
                var clientX = (e.pageX - startPosition.x) / 50;
                var clientY = (e.pageY - startPosition.y) / 50;
                var vertices = geometry.vertices;
                vertices[1].x = clientX;
                vertices[2].x = clientX;
                vertices[2].y = -clientY;
                vertices[3].y = -clientY;
                geometry.verticesNeedUpdate = true;
            }
        }

        function onMouseUp(e) {
            dragging = false;
            controls.enabled = true;
        }

        function get3DPosition(event) {
            var offset = $(canvas).offset();
            var position = {
                x: ((event.clientX - offset.left) / canvas.clientWidth) * 2 - 1,
                y: -((event.clientY - offset.top) / canvas.clientHeight) * 2 + 1
            };
            rayCaster.setFromCamera(position, camera);
            var intersects = rayCaster.intersectObjects(scene.children, true);
            if (intersects.length > 0) {
                return intersects[0].point;
            }
        }

    </script>
</body>
</html>

谢谢!

感谢分享您的 JFiddle!这将对我目前正在做的事情有很大的帮助!!

目前对所有这些编码仍然很陌生,但我弄乱了你的 JFiddle 并发现:

  • 鼠标拖动方框的准确性受到相机距网格的位置的影响,所以我将其锁定并将其设置为正交以及..
  • 为每个顶点 'onDrag' 命令添加了“* -1”(因为 框在相反的方向调整自己的大小。
  • 将初始框大小设置为 0 以从鼠标位置拖出

这是要检查的 JFiddle,希望对您有所帮助!您可以随时更改相机并再次将 controls.enabled = false 设置为 true。

https://jsfiddle.net/JoshyB/o2ze8qer/