threejs 8随机生成千个cube和点击选中模型
Posted Jessica巨人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了threejs 8随机生成千个cube和点击选中模型相关的知识,希望对你有一定的参考价值。
有滑动条和白边:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,body{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
</body>
</html>
效果:模型选中之后变红,点击选择其他的模型之后恢复原来的颜色
第一个实现:
/**
* 一个基本的threejs例子
*/
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{FBXLoader}from "three/examples/jsm/loaders/FBXLoader"
import{MTLLoader} from "three/examples/jsm/loaders/MTLLoader"
import{OBJLoader}from "three/examples/jsm/loaders/OBJLoader"
import{GLTFLoader}from "three/examples/jsm/loaders/GLTFLoader"
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());
}
//---------------------------点击选中---------------------------------------
/*表示一条射线
Raycaster(origin?:THREE.vector3,direction?:THREE.Vector3,near?:number,far?:number)
*/
var raycaster=new THREE.Raycaster();
var coords=new THREE.Vector2(0,0);
var selectedMaterial=new MeshPhongMaterial({color:0xff0000});
var lastSelectModel=null;
window.addEventListener("pointerdown",(ev)=>{
coords.x=(ev.clientX/window.innerWidth)*2-1;
coords.y=-(ev.clientY/window.innerHeight)*2+1;
// raycaster.setFromCamera({x:0,y:0},camera);
raycaster.setFromCamera(coords,camera);
var intersectObjects= raycaster.intersectObject(scene,true);
if (intersectObjects.length>0) {
//说明模型被选中
var interObj=intersectObjects[0];
var selectedmodel= interObj.object;
selectedmodel.orgMaterial=selectedmodel.material;
selectedmodel.material=selectedMaterial;
// selectedmodel.material.emissive.set(0xff0000);
if (lastSelectModel!==null&& lastSelectModel!==selectedMaterial) {
lastSelectModel.material=lastSelectModel.orgMaterial;
}
lastSelectModel=selectedmodel;
}
})
//-----------------------------------------------------------------------------------------------------
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);
});
/**
*练习一下点选
*/
import * as THREE from "three"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import { AmbientLight, AxesHelper, BoxBufferGeometry, Color, DirectionalLight, HemisphereLight,
Mesh, MeshPhongMaterial, Raycaster, SphereGeometry, TextureLoader } from "three";
var renderer = new THREE.WebGLRenderer({ antialias: true });
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;
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; index < 100; i++)
{
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());
}
//---------------------------点击选中START---------------------------------------
var raycaster = new THREE.Raycaster()
var mouse = new THREE.Vector2()
function onMouseClick(event){
//将鼠标点击位置的屏幕坐标转换成threejs中的标准坐标
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
mouse.y = (event.clientY/window.innerHeight) *2 + 1
// 通过鼠标点的位置和当前相机的矩阵计算出raycaster
raycaster.setFromCamera( mouse, camera );
// 获取raycaster直线和所有模型相交的数组集合
var intersects = raycaster.intersectObjects( scene.children );
console.log(intersects);
//将所有的相交的模型的颜色设置为红色
for ( var i = 0; i < intersects.length; i++ ) {
intersects[ i ].object.material.color.set( 0xff0000 );
}
}
window.addEventListener( 'click', onMouseClick, false );
//---------------------------选中部分END-----------------------------------------
update()
function update() {
console.log('刷新')
renderer.render(scene, camera);
requestAnimationFrame(update);//不会卡塞,专门针对图形渲染刷新的方法
}
//-------------------------------------------------------------------------------
效果图:
以上是关于threejs 8随机生成千个cube和点击选中模型的主要内容,如果未能解决你的问题,请参考以下文章