一、层级模型节点命名、查找、遍历
1. 模型命名.name属性
- 在层级模型中可以给一些模型对象通过
.name
属性命名进行标记。javascriptgroup.add(Mesh) // 网格模型命名 Mesh.name = "眼睛" // mesh父对象对象命名 group.name = "头"
2. 树结构层级模型
- 实际开发的时候,可能会加载外部的模型,然后从模型对象通过节点的名称
.name
查找某个子对象,javascript// 头部网格模型和组 const headMesh = sphereMesh(10, 0, 0, 0); headMesh.name = "脑壳" const leftEyeMesh = sphereMesh(1, 8, 5, 4); leftEyeMesh.name = "左眼" const rightEyeMesh = sphereMesh(1, 8, 5, -4); rightEyeMesh.name = "右眼" const headGroup = new THREE.Group(); headGroup.name = "头部" headGroup.add(headMesh, leftEyeMesh, rightEyeMesh); // 身体网格模型和组 const neckMesh = cylinderMesh(3, 10, 0, -15, 0); neckMesh.name = "脖子" const bodyMesh = cylinderMesh(14, 30, 0, -35, 0); bodyMesh.name = "腹部" const leftLegMesh = cylinderMesh(4, 60, 0, -80, -7); leftLegMesh.name = "左腿" const rightLegMesh = cylinderMesh(4, 60, 0, -80, 7); rightLegMesh.name = "右腿" const legGroup = new THREE.Group(); legGroup.name = "腿" legGroup.add(leftLegMesh, rightLegMesh); const bodyGroup = new THREE.Group(); bodyGroup.name = "身体" bodyGroup.add(neckMesh, bodyMesh, legGroup); // 人Group const personGroup = new THREE.Group(); personGroup.name = "人" personGroup.add(headGroup, bodyGroup) personGroup.translateY(50) scene.add(personGroup); // 球体网格模型创建函数 function sphereMesh(R, x, y, z) { const geometry = new THREE.SphereGeometry(R, 25, 25); //球体几何体 const material = new THREE.MeshPhongMaterial({ color: 0x0000ff }); //材质对象Material const mesh = new THREE.Mesh(geometry, material); // 创建网格模型对象 mesh.position.set(x, y, z); return mesh; } // 圆柱体网格模型创建函数 function cylinderMesh(R, h, x, y, z) { const geometry = new THREE.CylinderGeometry(R, R, h, 25, 25); //球体几何体 const material = new THREE.MeshPhongMaterial({ color: 0x0000ff }); //材质对象Material const mesh = new THREE.Mesh(geometry, material); // 创建网格模型对象 mesh.position.set(x, y, z); return mesh; }
3. 递归遍历方法.traverse()
three.ts
层级模型就是一个树结构,可以通过递归遍历的算法去遍历three.ts
一个模型对象的所有后代, 可以通过递归遍历上面创建一个机器人模型或者一个外部加载的三维模型。javascriptscene.traverse(function(obj) { if (obj.type === "Group") { console.log(obj.name); } if (obj.type === "Mesh") { console.log(' ' + obj.name); obj.material.color.set(0xffff00); } if (obj.name === "左眼" | obj.name === "右眼") { obj.material.color.set(0x000000) } // 打印id属性 console.log(obj.id); // 打印该对象的父对象 console.log(obj.parent); // 打印该对象的子对象 console.log(obj.children); })
4. 查找某个具体的模型
- 看到
three.ts
的.getObjectById()
、.getObjectByName()
等方法。 three.ts
和前端DOM
一样,可以通过一个方法查找树结构父元素的某个后代对象, 对于普通前端而言可以通过name
或id
等方式查找一个或多个DOM
元素,three.ts
同样可以通过一些方法查找一个模型树中的某个节点。 更多的查找方法和方法的使用细节可以查看基类Object3D
javascript// 遍历查找scene中复合条件的子对象,并返回id对应的对象 const idNode = scene.getObjectById ( 4 ); console.log(idNode);
javascript// 遍历查找对象的子对象,返回name对应的对象(name是可以重名的,返回第一个) const nameNode = scene.getObjectByName ( "左腿" ); nameNode.material.color.set(0xff0000);