Three.js(七)—— 组对象Group、层级对象

文章目录

  • 7、层级结构、树结构
    • 7.1 组对象Group、层级对象
      • Group案例
      • 查看子对象.children
      • 场景对象结构
      • .add() 方法
      • .remove()方法
    • 7.2 对象节点命名、查找、遍历
      • 模型命名(.name属性)
      • 树结构层级模型
      • 递归遍历方法.traverse()
      • 查找某个具体的模型
    • 7.3 本地位置坐标、世界位置坐标
      • .getWorldPosition()方法
      • 建立世界坐标系概念
      • 本地缩放系数.scale
      • 本地矩阵.materix和世界矩阵.matrixWorld

7、层级结构、树结构

Three.js(七)—— 组对象Group、层级对象_第1张图片

7.1 组对象Group、层级对象

Group案例

//创建两个网格模型mesh1、mesh2
var geometry = new THREE.BoxGeometry(20, 20, 20);
var material = new THREE.MeshLambertMaterial({color: 0x0000ff});
var group = new THREE.Group();
var mesh1 = new THREE.Mesh(geometry, material);
var 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

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

场景对象结构

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

Three.js(七)—— 组对象Group、层级对象_第2张图片

.add() 方法

group.add(mesh1);
group.add(mesh2);

group.add(mesh1,mesh2);

.remove()方法

// 删除父对象group的子对象网格模型mesh1
group.remove(mesh1)
// 一次删除场景中多个对象
scene.remove(light,group)

7.2 对象节点命名、查找、遍历

模型命名(.name属性)

group.add(Mesh)
// 网格模型命名
Mesh.name = "眼睛"
// mesh父对象对象命名
group.name = "头"

树结构层级模型

// 头部网格模型和组
var headMesh = sphereMesh(10, 0, 0, 0);
headMesh.name = "脑壳"
var leftEyeMesh = sphereMesh(1, 8, 5, 4);
leftEyeMesh.name = "左眼"
var rightEyeMesh = sphereMesh(1, 8, 5, -4);
rightEyeMesh.name = "右眼"
var headGroup = new THREE.Group();
headGroup.name = "头部"
headGroup.add(headMesh, leftEyeMesh, rightEyeMesh);
// 身体网格模型和组
var neckMesh = cylinderMesh(3, 10, 0, -15, 0);
neckMesh.name = "脖子"
var bodyMesh = cylinderMesh(14, 30, 0, -35, 0);
bodyMesh.name = "腹部"
var leftLegMesh = cylinderMesh(4, 60, 0, -80, -7);
leftLegMesh.name = "左腿"
var rightLegMesh = cylinderMesh(4, 60, 0, -80, 7);
rightLegMesh.name = "右腿"
var legGroup = new THREE.Group();
legGroup.name = "腿"
legGroup.add(leftLegMesh, rightLegMesh);
var bodyGroup = new THREE.Group();
bodyGroup.name = "身体"
bodyGroup.add(neckMesh, bodyMesh, legGroup);
// 人Group
var personGroup = new THREE.Group();
personGroup.name = "人"
personGroup.add(headGroup, bodyGroup)
personGroup.translateY(50)
scene.add(personGroup);

// 球体网格模型创建函数
function sphereMesh(R, x, y, z) {
  var geometry = new THREE.SphereGeometry(R, 25, 25); //球体几何体
  var material = new THREE.MeshPhongMaterial({
    color: 0x0000ff
  }); //材质对象Material
  var mesh = new THREE.Mesh(geometry, material); // 创建网格模型对象
  mesh.position.set(x, y, z);
  return mesh;
}
// 圆柱体网格模型创建函数
function cylinderMesh(R, h, x, y, z) {
  var geometry = new THREE.CylinderGeometry(R, R, h, 25, 25); //球体几何体
  var material = new THREE.MeshPhongMaterial({
    color: 0x0000ff
  }); //材质对象Material
  var mesh = new THREE.Mesh(geometry, material); // 创建网格模型对象
  mesh.position.set(x, y, z);
  return mesh;
}

递归遍历方法.traverse()

scene.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);
})

查找某个具体的模型

// 遍历查找scene中复合条件的子对象,并返回id对应的对象
var idNode = scene.getObjectById ( 4 );
console.log(idNode);
// 遍历查找对象的子对象,返回name对应的对象(name是可以重名的,返回第一个)
var nameNode = scene.getObjectByName ( "左腿" );
nameNode.material.color.set(0xff0000);

7.3 本地位置坐标、世界位置坐标

.getWorldPosition()方法

// 声明一个三维向量用来保存世界坐标
var worldPosition = new THREE.Vector3();
// 执行getWorldPosition方法把模型的世界坐标保存到参数worldPosition中
mesh.getWorldPosition(worldPosition);

建立世界坐标系概念

如果你没有本地坐标系和世界坐标系的概念,可以通过下面的案例源码很快的建立两个坐标系的概念。

你首先在案例中测试下面源码,通过位置属性.position和.getWorldPosition()分别返回模型的本地位置坐标和世界坐标,查看两个坐标x分量有什么不同。你可以看到网格模型mesh通过位置属性.position返回的坐标x分量是50,通过.getWorldPosition()返回的坐标x分量是100,也就是说mesh的世界坐标是mesh位置属性.position和mesh父对象group位置属性.position的累加。

var mesh = new THREE.Mesh(geometry, material);
// mesh的本地坐标设置为(50, 0, 0)
mesh.position.set(50, 0, 0);
var group = new THREE.Group();
// group本地坐标设置和mesh一样设置为(50, 0, 0)
// mesh父对象设置position会影响得到mesh的世界坐标
group.position.set(50, 0, 0);
group.add(mesh);
scene.add(group);

// .position属性获得本地坐标
console.log('本地坐标',mesh.position);

// getWorldPosition()方法获得世界坐标
//该语句默认在threejs渲染的过程中执行,如果渲染之前想获得世界矩阵属性、世界位置属性等属性,需要通过代码更新
scene.updateMatrixWorld(true);
var worldPosition = new THREE.Vector3();
mesh.getWorldPosition(worldPosition);
console.log('世界坐标',worldPosition);

本地缩放系数.scale

本地矩阵.materix和世界矩阵.matrixWorld

你可能感兴趣的:(Three.js,javascript,开发语言,ecmascript)