学習threejs線を使用してください

内容:あなたは、グリッド、Shiftキーを押しながら上の任意の場所をクリックし、ボックスの現在の位置を削除するときに使用するthreejsは箱に入れ20×20のグリッド、マウスが移動すると、それに箱を移動し、作成します。

次のようにプロセスは以下のとおりです。

  • グリッドを作成します。
  • 同じサイズのグリッドで平面を作成します。
  • グリッドの同じサイズのボックスを作成しmesh_1
  • 同じブロックgeometry_2とグリッドは、シーンに追加されていません
  • 3つのイベント:
    • マウスモーションイベントは、マウスが移動するように、mesh_1位置を変更し、再レンダリング
    • オブジェクトが現在のオブジェクトを削除し、その後、面と交差していない場合、新しいメッシュを作成し、位置の交差点で、イベントをマウスをクリックしてください
    • ステータスの変更を削除するかどうかのkeydown、keyUpイベント、

次のように詳細なコードは次のとおりです。


import * as THREE from './build/three.module'
import { stat } from 'fs';

var camera, scene, renderer;
var moveMesh, staticGeo,staticMat, plane;
var objects = [];
var raycaster, mouse;
var isShiftDown = false;

function init() {
    camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
    camera.position.set(500, 800, 1300);
    camera.lookAt(0, 0, 0);

    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xf0f0f0);

    // lights
    var light = new THREE.AmbientLight(0x606060);
    scene.add(light);

    // grids
    var grid = new THREE.GridHelper(1000, 20); 
    scene.add(grid);

    // plane, 辅助碰撞检测
    var planeGeo = new THREE.PlaneBufferGeometry(1000, 1000);
    var planMat = new THREE.MeshBasicMaterial({color: 0xffff00, visible : true});
    plane = new THREE.Mesh(planeGeo, planMat);
    plane.rotateX(-Math.PI /2);
    scene.add(plane);
    objects.add(plane);

    // 射线 raycaster = new THREE.Raycaster();
    mouse = new THREE.Vector2();

    // moveCube;
    var moveGeo = new THREE.BoxBufferGeometry(50, 50, 50);
    var moveMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, opacity: 0.5, transparent: true });
    moveMesh = new THREE.Mesh(moveGeo, moveMaterial);
    scene.add(moveMesh);

    // static cube
    staticGeo = new THREE.BoxBufferGeometry(50, 50, 50);
    staticMat = new THREE.MeshLambertMaterial({ color: 0xfeb74c, map: new THREE.TextureLoader().load('textures/square-outline-textured.png') });

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);

    document.body.appendChild(renderer.domElement);
    document.body.addEventListener('mousemove', onDocuementMouseMove, false);
    document.body.addEventListener('mousedown', onDocumentMouseDown, false);
    document.body.addEventListener('keydown', onDocuementKeyDown, false);
    document.body.addEventListener('keyup', onDocuementKeyUp, false);

    window.addEventListener('resize', onWindowResize, false);
}


function onDocumentMouseDown(event) {
    event.preventDefault();

    // 鼠标位置归一化
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // 通过摄像机与鼠标更新射线
    raycaster.setFromCamera(mouse, camera);
    var intersects = raycaster.intersectObjects(objects);
    if(intersects.length > 0) {
        var intersect = intersects[0];
        if (isShiftDown) {
            if(intersect.object !== plane) {
                scene.remove(intersect.object);
                objects.splice(objects.indexOf(intersect.object), 1);
            }
        }
        else
        {
            var staticMesh = new THREE.Mesh(staticGeo, staticMat);
            staticMesh.position.copy(intersect.point).add(intersect.face.normal);
            staticMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
            scene.add(staticMesh);
            objects.push(staticMesh);
        }
    }
    
}

function onDocuementMouseMove(event) {
    event.preventDefault();
    // 鼠标位置归一化
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // 通过摄像机与鼠标更新射线
    raycaster.setFromCamera(mouse, camera);
    var intersects = raycaster.intersectObjects(objects);

    if(intersects.length > 0) {
        intersect = intersects[0];
        // 移动位置到目标点
        moveMesh.position.copy(intersect.point).add(intersect.face.normal);
        // 计算具体方格
        moveMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25);
    }
    render();
}

function onDocuementKeyDown(event) {
    switch (event.keyCode) {
        case 16: isShiftDown = true; break;
    }
}

function onDocuementKeyUp(event) {
    switch (event.keyCode) {
        case 16: isShiftDown = false; break;
    }
}

function onWindowResize() {
    camera.aspect = window.innerWidth/ window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);

}

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

おすすめ

転載: www.cnblogs.com/yaolin1228/p/11374596.html