四、threejs 学习笔记-层级模型

友情链接:threejs 中文文档

目录

1. 层级结构 

查看子对象.children

父对象旋转缩放平移变换,子对象跟着变化

2. 遍历模型树结构和查询模型节点

(1) 模型命名(.name属性)

(2) 递归遍历traverse()方法

(3) 查找某个具体的模型.getObjectByName()

3. 本地坐标和世界坐标

(2) getWorldPosition()获取世界坐标

4. 移除对象.remove()

5. 模型隐藏或显示

1. 层级结构 

 下面代码创建了两个网格模型mesh1、mesh2,通过THREE.Group类创建一个组对象group,然后通过add方法把网格模型mesh1、mesh2作为设置为组对象group的子对象,然后在通过执行scene.add(group)把组对象group作为场景对象的scene的子对象。也就是说场景对象是scene是group的父对象,group是mesh1、mesh2的父对象。这样就构成了一个三层的层级结构,当然了你也可以通过Group自己创建新模型节点作为层级结构中的一层。

//创建两个网格模型mesh1、mesh2
const geometry = new THREE.BoxGeometry(20, 20, 20);
const material = new THREE.MeshLambertMaterial({color: 0x00ffff});
const group = new THREE.Group();
const mesh1 = new THREE.Mesh(geometry, material);
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.translateX(25);
//把mesh1型插入到组group中,mesh1作为group的子对象
group.add(mesh1);
//把mesh2型插入到组group中,mesh2作为group的子对象
group.add(mesh2);
//把group插入到场景中作为场景子对象
scene.add(group);

查看子对象.children

Threejs场景对象Scene、组对象Group都有一个子对象属性.children,通过该属性可以访问父对象的子对象,子对象属性.children的值是数组,所有子对象是数组的值,你可以在浏览器控制台打印测试上面案例代码。

console.log('查看group的子对象',group.children);

父对象旋转缩放平移变换,子对象跟着变化

网格模型mesh1、mesh2作为设置为父对象group的子对象,如果父对象group进行旋转、缩放、平移变换,子对象同样跟着变换,就像你的头旋转了,眼睛会跟着头旋转。 

//沿着Y轴平移mesh1和mesh2的父对象,mesh1和mesh2跟着平移
group.translateY(100);

//父对象缩放,子对象跟着缩放
group.scale.set(4,4,4);

//父对象旋转,子对象跟着旋转
group.rotateY(Math.PI/6)

2. 遍历模型树结构和查询模型节点

(1) 模型命名(.name属性)

在层级模型中可以给一些模型对象通过.name属性命名进行标记。

const group = new THREE.Group();
group.name='小区房子';
const mesh = new THREE.Mesh(geometry, material);
mesh.name='一号楼';

(2) 递归遍历traverse()方法

Threejs层级模型就是一个树结构,可以通过递归遍历的算法去遍历Threejs一个模型对象包含的所有后代。

// 递归遍历model包含所有的模型节点
model.traverse(function(obj) {
    console.log('所有模型节点的名称',obj.name);
    // obj.isMesh:if判断模型对象obj是不是网格模型'Mesh'
    if (obj.isMesh) {//判断条件也可以是obj.type === 'Mesh'
        obj.material.color.set(0xffff00);
    }
});

(3) 查找某个具体的模型.getObjectByName()

Threejs和前端DOM一样,可以通过一个方法查找树结构父元素的某个后代对象,对于普通前端而言可以通过name或id等方式查找一个或多个DOM元素,Threejs同样可以通过一些方法查找一个模型树中的某个节点。更多的查找方法和方法的使用细节可以查看基类Object3D。

// 返回名.name为"4号楼"对应的对象
const nameNode = scene.getObjectByName ("4号楼");
nameNode.material.color.set(0xff0000);

3. 本地坐标和世界坐标

(1) 本地(局部)坐标和世界坐标

// mesh的世界坐标就是mesh.position与group.position的累加
const mesh = new THREE.Mesh(geometry, material); 
mesh.position.set(50, 0, 0);
const group = new THREE.Group();
group.add(mesh);
group.position.set(50, 0, 0);

有时候模型可能有多个层级,那么模型的坐标就分为本地坐标和世界坐标了。

本地坐标就是模型自身的position属性,而世界坐标就是模型自身的position属性再加上所有父模型的position属性

(2) getWorldPosition()获取世界坐标

mesh.getWorldPosition(Vector3)读取一个模型的世界坐标,并把读取结果存储到参数Vector3中。

// 声明一个三维向量用来表示某个坐标
const worldPosition = new THREE.Vector3();
// 获取mesh的世界坐标,你会发现mesh的世界坐标受到父对象group的.position影响
mesh.getWorldPosition(worldPosition);
console.log('世界坐标',worldPosition);
console.log('本地坐标',mesh.position);

4. 移除对象.remove()

既然有.add() 方法添加对象,那就一定有删除对象的方法,使用.remove()可以删除一个或多个对象。

// 删除一个对象
group.remove(mesh1);

// 删除多个对象
group.remove(mesh1,mesh2);

5. 模型隐藏或显示

开发web3d项目,有时候需要临时隐藏一个模型,或者一个模型处于隐藏状态,需要重新恢复显示

mesh.visible = false;// 隐藏一个网格模型,visible的默认值是true

group.visible =false; // 隐藏一个包含多个模型的组对象group

 文章中部分素材选取自Threejs中文网:Three.js中文网

猜你喜欢

转载自blog.csdn.net/weixin_60645637/article/details/131487487