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 框选模型的主要内容,如果未能解决你的问题,请参考以下文章
使用片段时 Intellij 无法正确识别 Thymeleaf 模型变量