参考资料
知识点
注:基于Three.jsv0.155.0
- Group:add()
- 遍历模型树结构、查询模型节点:name、traverse、
getObjectByName()
- 本地坐标和世界坐标:
getWorldPosition()
- 改变模型相对局部坐标原点位置
- 移除对象:.remove()
- 模型隐藏或显示:visible
代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Three.js</title>
</head>
<body>
</body>
<!-- 具体路径配置,你根据自己文件目录设置,我的是课件中源码形式 -->
<script type="importmap">
{
"imports": {
"three": "./js/three.module.js",
"three/addons/": "../three.js/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const width = 800
const height = 500
// 场景
const scene = new THREE.Scene();
// 几何体
const geometry = new THREE.BoxGeometry(20, 50, 20);
// 材质
const material = new THREE.MeshLambertMaterial({
color:0x0000ff,
});
const mesh0 = new THREE.Mesh(geometry, material);
scene.add(mesh0);
// 网格模型:物体
const mesh = new THREE.Mesh(geometry, material);
mesh.name = '1号楼';
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.material = mesh.material.clone();
mesh2.position.x = 40;
mesh2.name = '2号楼';
// ********** 本章知识点示例代码 Start **********
// 组
const group = new THREE.Group();
// const group = new THREE.Object3D();
group.add(mesh, mesh2);
group.position.y = 20;
scene.add(group);
group.name = '小区';
// 遍历所有的物体
group.traverse(child => {
console.log('🚀 ~ file: 4层级模型.html:52 ~ child:', child.name)
if (child.isMesh) {
child.material.color.set(0xff0000);
}
});
// 根据名称获取物体
const mashByName = group.getObjectByName('1号楼');
mashByName.material.color.set(0x00ff00);
// 本地坐标和世界坐标
mesh.position.x = 10;
group.position.x = 100;
// 获取世界坐标
const vector = new THREE.Vector3();
mesh.getWorldPosition(vector);
console.log('🚀 ~ file: 4层级模型.html:71 ~ vector:', vector) // 110,20,0
const vector2 = new THREE.Vector3();
mesh2.getWorldPosition(vector2);
console.log('🚀 ~ file: 4层级模型.html:75 ~ vector2:', vector2) // 140,20,0
//可视化mesh2的局部坐标系
const meshAxesHelper = new THREE.AxesHelper(50);
mesh2.add(meshAxesHelper);
// 平移几何体的顶点坐标,改变几何体自身相对局部坐标原点的位置
geometry.translate(10, 0, 0);
// 移除
group.remove(mesh);
// 隐藏
// mesh2.visible = false;
mesh2.material.visible = false;
// ********** 本章知识点示例代码 End **********
// 光源
const pointLight = new THREE.PointLight(0xffffff, 1.0, 0, 0);
pointLight.position.set(200, 200, 200 );
scene.add(pointLight);
// 坐标系
const axes = new THREE.AxesHelper(200);
scene.add(axes);
// 相机
const camera = new THREE.PerspectiveCamera(75, width/height, 0.1, 1000);
camera.position.set(200, 200, 200);
camera.lookAt(scene.position);
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
// 控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', () => {
renderer.render(scene, camera);
});
// 渲染循环
function render() {
mesh.rotateY(0.01);// mesh旋转动画
// 同步mesh2和mesh的姿态角度一样,不管mesh姿态角度怎么变化,mesh2始终保持同步
mesh2.rotation.copy(mesh.rotation);
mesh0.rotation.copy(mesh.rotation);
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
</script>
</html>