学习: Threejs (3)& Threejs (4)

一、三维向量Vector3与模型位置、缩放属性

位置属性.position

执行.translateX().translateY()等方法本质上改变的都是模型的位置属性.position

javascript 复制代码
// 位置属性.position使用threejs三维向量对象Vector3表示的
console.log("模型位置属性.position的值", mesh.position);

//new THREE.Vector3()实例化一个三维向量对象
const v3 = new THREE.Vector3(0, 0, 0);
console.log("v3", v3);
v3.set(10, 0, 0); //set方法设置向量的值
v3.x = 100; //访问x、y或z属性改变某个分量的值

// .position的值是Vector3,意味着你想改变.position,可以查询文档Vector3类
// 直接设置网格模型的位置
mesh.position.set(100, 100, 100);
mesh.position.x = 100; //设置模型的x坐标

// 网格模型沿着x轴方向平移100,
mesh.translateX(100);

属性.scale表示模型对象的xyz三个方向上的缩放比例,.scale的属性值是一个三维向量对象Vector3,默认值是THREE.Vector3(1.0,1.0,1.0)

javascript 复制代码
mesh.scale.y = 3; //y方向放大3倍
// 网格模型xyz方向分别缩放0.5,1.5,2倍
mesh.scale.set(0.5, 1.5, 2);

二、欧拉Euler与角度属性.rotation

javascript 复制代码
// 角度属性.rotation使用threejs欧拉对象Euler表示的
console.log('模型角度属性.rotation的值', mesh.rotation);

// 创建一个欧拉对象,表示绕着x、y、z轴分别旋转45度,0度,90度
// const Euler = new THREE.Euler( Math.PI/4,0, Math.PI/2);
const Euler = new THREE.Euler();
// 通过xyz分量属性定义和参数一样
Euler.x = Math.PI/4;
Euler.y = 0;
Euler.z = Math.PI/2;

角度属性.rotation的值是欧拉对象Euler,意味着你想改变属性.rotation

javascript 复制代码
//绕y轴的角度设置为60度
mesh.rotation.y = Math.PI/3;
//绕y轴的角度增加60度
mesh.rotation.y += Math.PI/3;
//绕y轴的角度减去60度
mesh.rotation.y -= Math.PI/3;

模型执行.rotateX().rotateY()等旋转方法,改变了模型的角度属性.rotation

javascript 复制代码
// 通过模型的旋转方法,也可以改变角度属性.rotation
mesh.rotateY(Math.PI / 3);// 绕着Y轴旋转60度

三、模型材质颜色(Color对象)

javascript 复制代码
const material = new THREE.MeshLambertMaterial({
    color: 0xffff00,
});
const mesh = new THREE.Mesh(geometry, material);
// 浏览器控制台查看材质颜色属性的属性值
console.log('material.color',material.color);

颜色对象

javascript 复制代码
// 创建一个颜色对象
const color = new THREE.Color();//默认是纯白色0xffffff。
console.log('查看颜色对象结构',color);//可以查看rgb的值

通过.r.g.b属性改变颜色值

javascript 复制代码
color.r = 0.0;
color.b = 0.0;

Color提供了.setHex().setRGB().setStyle().set()等修改颜色值的方法

javascript 复制代码
color.setRGB(0,1,0);//RGB方式设置颜色
color.setHex(0x00ff00);//十六进制方式设置颜色
color.setStyle('#00ff00');//前端CSS颜色值设置颜色

重置模型材质的颜色

javascript 复制代码
// 十六进制颜色
material.color.set(0x00ff00);
// 前端CSS风格颜色值:'#00ff00'、'rgb(0,255,0)'等形式
// material.color.set('#00ff00');
// material.color.set('rgb(0,255,0)');

四、模型材质父类Material

javascript 复制代码
material.transparent = true;//开启透明
material.opacity = 0.5;//设置透明度
// material.side = THREE.BackSide;//背面可以看到
material.side = THREE.DoubleSide;//双面可见

五、模型材质和几何体属性

javascript 复制代码
console.log('mesh',mesh);
console.log('mesh.geometry',mesh.geometry);
console.log('mesh.material',mesh.material);
javascript 复制代码
// 访问模型材质,并设置材质的颜色属性
mesh.material.color.set(0xffff00);
// 访问模型几何体,并平移几何体顶点数据
mesh.geometry.translate(0,100,0);

mesh共享材质或几何体

javascript 复制代码
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.position.x = 100;

// 两个mesh共享一个材质,改变一个mesh的颜色,另一个mesh2的颜色也会跟着改变
// mesh.material和mesh2.material都指向同一个material
// 三者等价:mesh.material、mesh2.material、material
mesh.material.color.set(0xffff00);


// 三者等价:mesh.geometry、mesh2.geometry、geometry
mesh.geometry.translate(0,100,0);
export {mesh,mesh2};

六、克隆.clone()和复制.copy()

克隆.clone()简单说就是复制一个和原对象一样的新对象

javascript 复制代码
const v1 = new THREE.Vector3(1, 2, 3);
console.log('v1',v1);
//v2是一个新的Vector3对象,和v1的.x、.y、.z属性值一样
const v2 = v1.clone();
console.log('v2',v2);

复制.copy()简单说就是把一个对象属性的属性值赋值给另一个对象

javascript 复制代码
const v3 = new THREE.Vector3(4, 5, 6);
//读取v1.x、v1.y、v1.z的赋值给v3.x、v3.y、v3.z
v3.copy(v1); 

Mesh克隆

javascript 复制代码
const material = new THREE.MeshLambertMaterial({
  color: 0xffffff,
});
const mesh = new THREE.Mesh(geometry, material);
// 通过mesh克隆.clone()一个和mesh一样的新模型对象mesh2
const mesh2 = mesh.clone();
mesh2.position.x = 100;

// 通过克隆.clone()获得的新模型和原来的模型共享材质和几何体
//改变材质颜色,或者说改变mesh2颜色,mesh和mesh2颜色都会改变
// material.color.set(0xffff00);
mesh2.material.color.set(0xffff00);

// 改变mesh的位置,使之位于mesh2的正上方(y),距离100。
mesh.position.copy(mesh2.position); //1. 第1步位置重合
mesh.position.y += 100; //1. 第2步mesh在原来y的基础上增加100
javascript 复制代码
// 克隆几何体和材质,重新设置mesh2的材质和几何体属性
mesh2.geometry = mesh.geometry.clone();
mesh2.material = mesh.material.clone();
// 改变mesh2颜色,不会改变mesh的颜色
mesh2.material.color.set(0xff0000);

Threejs (4)

一、组对象Group、层级模型

javascript 复制代码
//创建两个网格模型mesh1、mesh2
const geometry = new THREE.BoxGeometry(20, 20, 20);
const material = new THREE.MeshLambertMaterial({ color: 0xffffff });
// 创建一个组对象
const group = new THREE.Group();
const mesh1 = new THREE.Mesh(geometry, material);
const mesh2 = new THREE.Mesh(geometry, material);
mesh2.translateX(25);

插入到组中

javascript 复制代码
//把mesh1型插入到组group中,mesh1作为group的子对象
group.add(mesh1);
//把mesh2型插入到组group中,mesh2作为group的子对象
group.add(mesh2);

// group.add(mesh1, mesh2);

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

javascript 复制代码
//沿着Y轴平移mesh1和mesh2的父对象,mesh1和mesh2跟着平移
group.translateY(100);
//父对象缩放,子对象跟着缩放
group.scale.set(4, 4, 4);
//父对象旋转,子对象跟着旋转
group.rotateY(Math.PI / 6);
javascript 复制代码
// group也会作为场景scene的子对象插入到场景中
export default group;

查看子对象.children

javascript 复制代码
console.log('查看group的子对象',group.children);

查看Scene的子对象

javascript 复制代码
console.log('查看Scene的子对象',scene.children);

Object3D作为Group来使用,Group更加语义化,Object3D本身就是表示模型节点的意思

mesh也能添加mesh子对象

javascript 复制代码
//threejs默认mesh也可以添加子对象,mesh基类也是Object3D
mesh1.add(mesh2);

高层楼、洋房

javascript 复制代码
// 引入three.js
import * as THREE from 'three';

// 创建一个层级模型对象

// 批量创建多个长方体表示高层楼
const group1 = new THREE.Group(); //所有高层楼的父对象
for (let i = 0; i < 5; i++) {
    const geometry = new THREE.BoxGeometry(20, 60, 10);
    const material = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = i * 30; // 网格模型mesh沿着x轴方向阵列
    group1.add(mesh); //添加到组对象group1
}
// 平移父对象group1,所有子对象跟着平移
group1.position.y = 30;
// 旋转父对象group1,所有子对象跟着旋转
// group1.rotateY(Math.PI/2);


const group2 = new THREE.Group();
// 批量创建多个长方体表示洋房
for (let i = 0; i < 5; i++) {
    const geometry = new THREE.BoxGeometry(20, 30, 10);
    const material = new THREE.MeshLambertMaterial({
        color: 0xffffff
    });
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.x = i * 30;
    group2.add(mesh); //添加到组对象group2
}
group2.position.z = 50;
group2.position.y = 15;

const model = new THREE.Group();
model.add(group1, group2);
// 整体平移model里面的所有模型对象
model.position.set(-50,0,-25);


export default model;

二、递归遍历模型树结构、查询模型节点

模型命名(.name属性)

javascript 复制代码
// 批量创建多个长方体表示高层楼
const group1 = new THREE.Group(); //所有高层楼的父对象
group1.name = "高层";
javascript 复制代码
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 30;
  group2.add(mesh); //添加到组对象group2
  mesh.name = i + 6 + "号楼";
javascript 复制代码
// 批量创建多个长方体表示高层楼
const group1 = new THREE.Group(); //所有高层楼的父对象
group1.name = "高层";
for (let i = 0; i < 5; i++) {
  const geometry = new THREE.BoxGeometry(20, 60, 10);
  const material = new THREE.MeshLambertMaterial({
    color: 0xffffff,
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 30; // 网格模型mesh沿着x轴方向阵列
  group1.add(mesh); //添加到组对象group1
  mesh.name = i + 1 + "号楼";
  console.log('mesh.name',mesh.name);
}
group1.position.y = 30;

const group2 = new THREE.Group();
group2.name = "洋房";
// 批量创建多个长方体表示洋房
for (let i = 0; i < 5; i++) {
  const geometry = new THREE.BoxGeometry(20, 30, 10);
  const material = new THREE.MeshLambertMaterial({
    color: 0xffffff,
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 30;
  group2.add(mesh); //添加到组对象group2
  mesh.name = i + 6 + "号楼";
}
group2.position.z = 50;
group2.position.y = 15;

const model = new THREE.Group();
model.name = "小区房子";
model.add(group1, group2);
model.position.set(-50, 0, -25);

递归遍历方法.traverse()

javascript 复制代码
// 递归遍历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);
  }
});

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

javascript 复制代码
// .getObjectByName()根据名字选择模型节点
const mesh = model.getObjectByName("2号楼");
mesh.material.color.set(0xff0000);

三、本地坐标和世界坐标

javascript 复制代码
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属性。

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

.getWorldPosition()获取世界坐标

给模型添加一个可视化的局部坐标系

javascript 复制代码
//可视化mesh的局部坐标系
const meshAxesHelper = new THREE.AxesHelper(50);
mesh.add(meshAxesHelper);

四、改变模型相对局部坐标原点位置

javascript 复制代码
 model.rotateY(0.01);//旋转动画
javascript 复制代码
// 平移几何体的顶点坐标,改变几何体自身相对局部坐标原点的位置
geometry.translate(50/2,0,0,);
javascript 复制代码
// .rotateY()默认绕几何体中心旋转,经过上面几何体平移变化,你会发现.rotateY()是绕长方体面上一条线旋转
mesh.rotateY(Math.PI/3);

五、移除对象.remove()

javascript 复制代码
//把mesh1型插入到组group中,mesh1作为group的子对象
group.add(mesh1);
//把mesh2型插入到组group中,mesh2作为group的子对象
group.add(mesh2);

remove

javascript 复制代码
// 删除父对象group的子对象网格模型mesh1
group.remove(mesh1);
// 通过`.remove()`方法删除父对象的子对象之后,可以通过浏览器控制台查看`.children()`属性的变化。
console.log('查看group的子对象',group.children);
javascript 复制代码
group.remove(mesh1,mesh2);//一次移除多个子对象

六、模型隐藏或显示

模型属性.visible

javascript 复制代码
mesh.visible =false;// 隐藏一个网格模型,visible的默认值是true
javascript 复制代码
group.visible =false;// 隐藏一个包含多个模型的组对象group

材质属性.visible

material.visible可以控制是否隐藏该材质对应的模型对象。

如果多个模型引用了同一个材质,如果该材质`.visible`设置为false,意味着隐藏绑定该材质的所有模型。

javascript 复制代码
mesh1.material.visible =false;
相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习