threejs9 框选模型

Posted Jessica巨人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了threejs9 框选模型相关的知识,希望对你有一定的参考价值。

按住空格键control.enabled=false,框选模型变成红色。

/**
 * 框选
 */

import * as THREE from "three"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import { AmbientLight, AxesHelper, BoxBufferGeometry, DirectionalLight, HemisphereLight, Mesh, MeshPhongMaterial, SphereGeometry, TextureLoader } from "three";
import{GLTFLoader}from "three/examples/jsm/loaders/GLTFLoader"
import{SelectionBox}from "three/examples/jsm/interactive/SelectionBox"
import{SelectionHelper}from "three/examples/jsm/interactive/SelectionHelper"

var renderer = new THREE.WebGLRenderer({ antialias: true });
// renderer.domElement;//是一个canvas 可以从参数传入
document.body.appendChild(renderer.domElement);

renderer.setSize(window.innerWidth, window.innerHeight);//设置画布高宽
renderer.setClearColor(0xffffff);//设置背景清空颜色

window.addEventListener("resize", () => {//窗口大小变化事件
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    //设置了aspect  必须更新相机的投影矩阵
    camera.updateProjectionMatrix();
})

var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 2, 100)
var control = new OrbitControls(camera, renderer.domElement);
var scene = new THREE.Scene();

scene.background = new THREE.CubeTextureLoader()
    .setPath( "../assets/textures/cubeMaps/")
    .load( [
        'posx.jpg',
        'negx.jpg',
        'posy.jpg',
        'negy.jpg',
        'posz.jpg',   
        'negz.jpg'
    ] );


var dirLight=new DirectionalLight(0xffffff);
dirLight.intensity=5;

var light = new HemisphereLight(0xffffff, 0x444444);
scene.add(light);
scene.add(dirLight);

//---------------------生成1000个随机立方体-------------------------------------
var cubeGrometry=new BoxBufferGeometry(2,2,2);
for (let i = 0; i < 1000; i++) {
    //Math.random()生成一个0-1之间的随机数
    var mesh=new Mesh(cubeGrometry,new MeshPhongMaterial({color:0xffffff*Math.random()}))
    scene.add(mesh);
    mesh.position.set(300*Math.random()-50,300*Math.random()-50,300*Math.random()-50);
    mesh.scale.set(2*Math.random()+1,2*Math.random()+1,2*Math.random()+1);
    mesh.rotation.set(7*Math.random(),7*Math.random(),7*Math.random());
}
//---------------------------框选---------------------------------------
var raycaster =new THREE.Raycaster();
var coords=new THREE.Vector2(0,0);

var selectedMaterial=new MeshPhongMaterial({color:0xff0000});

var lastSelectModel=null;

/**
 * 选中包围盒
 * SelectionBox(camera: THREE.Camera, scene: THREE.Scene, deep?: number)
 * SelectionBox.collection 表示选中的几何
 */
 var selectedBox = new SelectionBox(camera, scene);
 var selectedHelper = new SelectionHelper(selectedBox, renderer, "selectBox");
 var allowBoxSelectd = true;
 
 window.addEventListener("keydown", (ev) => {
     control.enabled=false;
     if (ev.key == " ") {
         allowBoxSelectd = !allowBoxSelectd;
         if (allowBoxSelectd)
             selectedHelper.element.style.display = ""
         else {
             selectedHelper.element.style.display = "none"
         }
     }
 })
 
 window.addEventListener("pointerdown", (ev) => {
     if (allowBoxSelectd) {
         var x = (ev.clientX / window.innerWidth) * 2 - 1;
         var y = -(ev.clientY / window.innerHeight) * 2 + 1;
 
         //清空状态 
         for (let i = 0; i < selectedBox.collection.length; i++) {
             var oneSelectedModel = selectedBox.collection[i];
             oneSelectedModel.material = oneSelectedModel.orgMaterial
         }
 
         selectedBox.startPoint.set(x, y, 0.5);
 
     }
 })
 
 window.addEventListener("pointermove", (ev) => {
 
     if (allowBoxSelectd && selectedHelper.isDown) {
         control.enabled = false
         var x = (ev.clientX / window.innerWidth) * 2 - 1;
         var y = -(ev.clientY / window.innerHeight) * 2 + 1;
 
         selectedBox.endPoint.set(x, y, 0.5);
 
         selectedBox.select();
 
         // console.log(selectedBox.collection)
 
         for (let i = 0; i < selectedBox.collection.length; i++) {
             var oneSelectedModel = selectedBox.collection[i];
             if (!oneSelectedModel.orgMaterial)
                 oneSelectedModel.orgMaterial = oneSelectedModel.material;
 
             oneSelectedModel.material = selectedMaterial
         }
 
     } else {
         control.enabled = true;
     }
 
 })
 
 window.addEventListener("pointerup", (ev) => {
 
     if (allowBoxSelectd) {
         control.enabled = false
         var x = (ev.clientX / window.innerWidth) * 2 - 1;
         var y = -(ev.clientY / window.innerHeight) * 2 + 1;
 
         selectedBox.endPoint.set(x, y, 0.5);
 
         selectedBox.select();
 
 
         for (let i = 0; i < selectedBox.collection.length; i++) {
             var oneSelectedModel = selectedBox.collection[i];
             //必须先判断是否备份原始材质
             if (!oneSelectedModel.orgMaterial)
                 oneSelectedModel.orgMaterial = oneSelectedModel.material;
             oneSelectedModel.material = selectedMaterial
         }
 
         if (selectEvent.onSelectd)
             selectEvent.onSelectd(selectedBox.collection);
 
     }
 })
//--------------------------------END----------------------------------------
update()

function update() {
    console.log('刷新')
    renderer.render(scene, camera);
    requestAnimationFrame(update);//不会卡塞,专门针对图形渲染刷新的方法
}

//-------------------------模型加载--------------------------------
var gltfLoader=new GLTFLoader();
gltfLoader.load("../assets/models/glTF/wuren.glb",(glb)=>{
glb.scene.x=-10;
// glb.scale.set(10,10,10);
    scene.add(glb.scene);
});

效果图:

以上是关于threejs9 框选模型的主要内容,如果未能解决你的问题,请参考以下文章

AJAX相关JS代码片段和部分浏览器模型

鼠标框选 下篇

红警框选功能

使用片段时 Intellij 无法正确识别 Thymeleaf 模型变量

php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用

如何防止在背面片段导航上再次设置视图模型