three 層級模型

group.remove(mesh1,mesh2);

Vector3與模型位置、縮放屬性

Group層級模型(樹結構)

創建了兩個網格模型mesh1、mesh2,通過THREE.Group類創建一個組對象group,然后通過add方法把網格模型mesh1、mesh2作為設置為組對象group的子對象,然后在通過執行scene.add(group)把組對象group作為場景對象的scene的子對象。也就是說場景對象是scene是group的父對象,group是mesh1、mesh2的父對象。

//創建兩個網格模型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

hreejs場景對象Scene、組對象Group都有一個子對象屬性.children通過該屬性可以訪問父對象的子對象,子對象屬性.children的值是數組,所有子對象是數組的值,父對象執行.add()方法的本質就是把參數中的子對象添加到自身的子對象屬性.children中。

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

場景對象結構

場景對象Scene的子對象,除了組對象Group之外,還可以看到環境光AmbientLight、平行光DirectionalLight、輔助坐標對象AxesHelper

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

場景對象對象scene構成的層級模型本身是一個樹結構,場景對象層級模型的第一層,也就是樹結構的根節點,一般來說網格模型Mesh、點模型Points、線模型Line是樹結構的最外層葉子結點。構建層級模型的中間層一般都是通過Threejs的Group類來完成,Group類實例化的對象可以稱為組對象。?

.add()方法總結

場景對象Scene、組對象Group.add()方法都是繼承自它們共同的基類(父類)Object3D

group.add(mesh1);
group.add(mesh2);// 或group.add(mesh1,mesh2);

父對象旋轉縮放平移變換,子對象跟著變化

格模型mesh1、mesh2作為設置為父對象group的子對象,如果父對象group進行旋轉、縮放、平移變換,子對象同樣跟著變換。

//沿著Y軸平移mesh1和mesh2的父對象,mesh1和mesh2跟著平移
group.translateY(100);//父對象縮放,子對象跟著縮放
group.scale.set(4,4,4);//父對象旋轉,子對象跟著旋轉
group.rotateY(Math.PI/6)

Object3D表示模型對象節點

受threejs歷史影響,你會在很多別的代碼中看到Object3D作為Group來使用,某種程度上,你可把兩者畫等號,只是Group更加語義化,Object3D本身就是表示模型節點的意思。

const mesh1 = new THREE.Mesh(geometry, material);
const mesh2 = new THREE.Mesh(geometry, material);
const obj = new THREE.Object3D();//作為mesh1和mesh2的父對象
obj.add(mesh1,mesh2);

mesh也能添加mesh子對象

threejs默認mesh也可以添加子對象,其實原因很簡單,mesh和Group父類都是Object3D,本質上也可以認為都是Object3D。

//threejs默認mesh也可以添加子對象,mesh基類也是Object3D
mesh1.add(mesh2);

遍歷模型樹結構、查詢模型節點

模型命名(.name屬性)

在層級模型中可以給一些模型對象通過.name屬性命名進行標記

const group = new THREE.Group();
group.name='小區';
const mesh = new THREE.Mesh(geometry, material);
mesh.name='五號樓';

樹結構層級模型設置.name屬性

下面是通過代碼創建了一個層級模型,一般實際開發的時候,會加載外部的模型,然后從模型對象通過節點的名稱.name查找某個子對象。

// 批量創建多個長方體表示高層樓
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: 0x00ffff});const mesh = new THREE.Mesh(geometry, material);mesh.position.x = i * 30; // 網格模型mesh沿著x軸方向陣列group1.add(mesh); //添加到組對象group1mesh.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: 0x00ffff});const mesh = new THREE.Mesh(geometry, material);mesh.position.x = i * 30;group2.add(mesh); //添加到組對象group2mesh.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()

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

查找某個具體的模型.getObjectByName()

Threejs和前端DOM一樣,可以通過一個方法查找樹結構父元素的某個后代對象,對于普通前端而言可以通過name或id等方式查找一個或多個DOM元素,Threejs同樣可以通過一些方法查找一個模型樹中的某個節點。

// 返回名.name為"4號樓"對應的對象
const nameNode = scene.getObjectByName ("4號樓");
nameNode.material.color.set(0xff0000);

?本地坐標和世界坐標

本地(局部)坐標和世界坐標

mesh的世界坐標就是mesh.position與group.position的累加

const mesh = new THREE.Mesh(geometry, material); 
mesh.position.set(10, 20, 0);
const group = new THREE.Group();
group.add(mesh);
group.position.set(50, 30, 0);
  1. 改變子對象的.position,子對象在3D空間中的坐標會發生改變。

  2. 改變父對象的.position,子對象在3D空間中的位置也會跟著變化,也就是說父對象.position和子對象.position疊加才是才是子對象的.position

任何一個模型的本地坐標(局部坐標)就是模型的.position屬性。

一個模型的世界坐標,說的是,模型自身.position和所有父對象.position累加的坐標。

.getWorldPosition()獲取世界坐標

mesh.getWorldPosition(Vector3)讀取一個模型的世界坐標,并把讀取結果存儲到參數Vector3中。

// 聲明一個三維向量用來表示某個坐標
const worldPosition = new THREE.Vector3();
// 獲取mesh的世界坐標,你會發現mesh的世界坐標受到父對象group的.position影響
mesh.getWorldPosition(worldPosition);
console.log('世界坐標',worldPosition);
console.log('本地坐標',mesh.position);

給子對象添加一個局部坐標系

mesh.add(坐標系)給mesh添加一個局部坐標系。

//可視化mesh的局部坐標系
const meshAxesHelper = new THREE.AxesHelper(50);
mesh.add(meshAxesHelper);

改變模型相對局部坐標原點位置

通過改變幾何體頂點坐標,可以改變模型自身相對坐標原點的位置。

//長方體的幾何中心默認與本地坐標原點重合
const geometry = new THREE.BoxGeometry(50, 50, 50);// 平移幾何體的頂點坐標,改變幾何體自身相對局部坐標原點的位置
geometry.translate(50/2,0,0,);;

旋轉測試

局部坐標相對模型發生改變,旋轉軸自然也會發生變化。

// .rotateY()默認繞幾何體中心旋轉,經過上面幾何體平移變化,你會發現.rotateY()是繞長方體面上一條線旋轉
mesh.rotateY(Math.PI/3);//
function render() {model.rotateY(0.01);//旋轉動畫requestAnimationFrame(render);
}
render();

移除對象.remove()

.remove()方法和.add()方法是相反的,是把子對象從父對象的.children()屬性中刪除。

查看父類Object3D的移除方法.remove()

場景對象Scene、組對象Group、網格模型對象Mesh.remove()方法都是繼承自它們共同的基類(父類)Object3D

.remove()方法使用

.add()方法是給父對象添加一個子對象,.remove()方法是刪除父對象中的一個子對象。

// 刪除父對象group的子對象網格模型mesh1
group.remove(mesh1);scene.remove(ambient);//移除場景中環境光
scene.remove(model);//移除場景中模型對象

一次移除多個子對象

group.remove(mesh1,mesh2);

模型隱藏或顯示

開發web3d項目,有時候需要臨時隱藏一個模型,或者一個模型處于隱藏狀態,需要重新恢復顯示。

模型屬性.visible

模型對象的父類Object3D封裝了一個屬性.visible,通過該屬性可以隱藏或顯示一個模型。

mesh.visible =false;// 隱藏一個網格模型,visible的默認值是true
group.visible =false;// 隱藏一個包含多個模型的組對象groupmesh.visible =true;// 使網格模型mesh處于顯示狀態

?材質屬性.visible

材質對象的父類Material封裝了一個.visible屬性,通過該屬性可以控制是否隱藏該材質對應的模型對象。

// 隱藏網格模型mesh,visible的默認值是true
mesh.material.visible =false;
// 注意如果mesh2和mesh的.material屬性指向同一個材質,mesh2也會跟著mesh隱藏

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712049.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712049.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712049.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

jenkins部署maven項目

流程&#xff1a; jenkins從代碼倉庫讀取代碼&#xff0c;將代碼文件放入jenkins的工作空間&#xff0c;將jenkins工作空間的代碼進行打包&#xff0c;將jar包遠程發送給服務器。 一&#xff1a;所需插件二&#xff1a;Tools 三&#xff1a;System&#xff1a; 配置ssh連接的…

github要求2fa身份驗證

前言 github登陸的時候發現要求2fa驗證, 2fa是啥?咋驗證? 解決 2FA&#xff08;Two-Factor Authentication&#xff0c;雙因素身份驗證&#xff09; 就是在賬戶和密碼的基礎上增加一次驗證碼驗證,這樣即使密碼被竊取,由于黑客沒有你的驗證碼也無法登陸 就像是銀行的u盾一樣…

python63-Python的循環之循環使用else

Python的循環都可以定義else代碼塊&#xff0c;當循環條件為False 時&#xff0c;程序會執行else代碼塊。如下代碼示范了為while循環定義else代碼塊。 # !/usr/bin/env python# -*- coding: utf-8 -*-# Time : 2024/01# Author : Laopicount_i 0while count_i < 5:print(c…

Java集合相關面試題(2024大廠高頻面試題系列)

1、說一說Java提供的常見集合&#xff1f;&#xff08;畫一下集合結構圖&#xff09; 在java中提供了量大類的集合框架&#xff0c;主要分為兩類&#xff1a; 第一個是Collection 屬于單列集合&#xff0c;第二個是Map 屬于雙列集合 在Collection中有兩個子接口List和Set。…

【力扣hot100】刷題筆記Day14

前言 又是新的一周&#xff0c;快樂的周一&#xff0c;快樂地刷題&#xff0c;今天把鏈表搞完再干活&#xff01; 114. 二叉樹展開為鏈表 - 力扣&#xff08;LeetCode&#xff09; 前序遍歷 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

回溯 Leetcode 51 N皇后

N皇后 Leetcode 51 學習記錄自代碼隨想錄 按照國際象棋的規則&#xff0c;皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。 n 皇后問題 研究的是如何將 n 個皇后放置在 nn 的棋盤上&#xff0c;并且使皇后彼此之間不能相互攻擊。 給你一個整數 n &#xff0c;返回所…

Linux —— 鏈接文件

硬鏈接 一般情況下&#xff0c;文件名和inode號碼是"一一對應"關系&#xff0c;每個inode號碼對應一個文件名。但是&#xff0c;Unix/Linux系統允許&#xff0c;多個文件名指向同一個inode號碼。 這意味著&#xff0c;可以用不同的文件名訪問同樣的內容&#xff1b;對…

軟件開發常見模型解析

軟件開發常見模型解析 摘要&#xff1a;本文將為您詳細介紹軟件開發過程中常見的幾種模型&#xff0c;包括瀑布模型、敏捷開發模型、螺旋模型、迭代模型和原型模型。通過了解這些模型的原理、優缺點&#xff0c;幫助您在不同的軟件項目中選擇最適合的開發模型。 一、引言 在…

【IC前端虛擬項目】inst_buffer子模塊DS與RTL編碼

【IC前端虛擬項目】數據搬運指令處理模塊前端實現虛擬項目說明-CSDN博客 需要說明一下的是,在我所提供的文檔體系里,并沒有模塊的DS文檔哈,因為實際項目里我也不怎么寫DS畢竟不是每個公司都和HISI一樣對文檔要求這么嚴格的。不過作為一個培訓的虛擬項目,還是建議在時間充裕…

Docker技術概論(3):Docker 中的基本概念

Docker技術概論&#xff08;3&#xff09; Docker 中的基本概念 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://…

基于java+springboot女士電商平臺系統源碼+文檔設計

基于javaspringboot女士電商平臺系統源碼文檔設計 博主介紹&#xff1a;多年java開發經驗&#xff0c;專注Java開發、定制、遠程、文檔編寫指導等,csdn特邀作者、專注于Java技術領域 作者主頁 央順技術團隊 Java畢設項目精品實戰案例《1000套》 歡迎點贊 收藏 ?留言 文末獲取源…

C語言----動態內存管理(2)

1.這里總結動態內存管理里面的錯誤 &#xff08;1&#xff09;使用malloc開辟空間以后直接賦值 這個就是malloc開辟失敗返回空指針&#xff0c;直接給空指針賦值就是錯誤的&#xff0c; tip1:使用malloc開辟空間以后一定要判斷是否為空 &#xff08;2&#xff09; 越界訪問…

Python批量提取文件夾中圖片的名稱及路徑到指定的.txt文件中

目錄 一、代碼二、提取效果 一、代碼 import os# 定義要保存的文件名 file_name "TestImage/Image_Visible_Gray.txt"# 讀取文件夾路徑 folder_path "TestImage/Image_Visible_Gray"# 遍歷文件夾中的所有文件 with open(file_name, "w") as f…

IO進程線程day1

編寫鏈表&#xff0c;鏈表里面隨便搞點數據&#xff0c;使用fprintf將鏈表中所有的數據保存到文件中&#xff0c;用fscanf讀取文件中的數據寫入鏈表中 #include <stdio.h> #include <stdlib.h>typedef struct Node {int data;struct Node* next; } Node;// 創建新…

可移植性(兼容性)測試指南

可移植性是指應用程序能夠安裝到不同的環境中&#xff0c;在不同的環境中使用&#xff0c;甚至可以移動到不同的環境中。當然&#xff0c;前兩者對所有系統都很重要。就PC軟件而言&#xff0c;鑒于操作系統、共存和互操作應用程序、硬件、帶寬可用性等方面的快速變化&#xff0…

抖店如何運營?新手應該怎么做?從入門到精通詳細講解!

我是電商珠珠 做抖店必須先搞懂它的基礎流程&#xff0c;流程搞懂了&#xff0c;才能有進一步的可能。不要急功近利&#xff0c;想要一口吃個胖子&#xff0c;這樣做就會直接造成店鋪被清店&#xff0c;扣除保證金&#xff0c;甚至還會埋怨自己沒用。 我做電商已經三年多的時…

vue3 日期延后一天

問題&#xff1a;提交信息時要求將所選日期延后一天進行提交解決過程&#xff1a;1.定義延后一天的計算方法&#xff0c;在提交前&#xff0c;將提交日期傳入調用該方法 2.對延后的日期進行格式化&#xff0c;最后格式為yy-mm-dd解決結果&#xff1a; const…

c++ - pointer convert - class member function‘s pointer <==> void*

文章目錄 c - pointer convert - class member functions pointer <> void*概述筆記END c - pointer convert - class member function’s pointer <> void* 概述 想將結構體中的void指針賦值為類成員函數的指針, 用于回調. 這個結構體相關的函數寫完, 就不用再因…

Stable Diffusion中的Clip模型

基礎介紹 Stable Diffusion 是一個文本到圖像的生成模型&#xff0c;它能夠根據用戶輸入的文本提示&#xff08;prompt&#xff09;生成相應的圖像。在這個模型中&#xff0c;CLIP&#xff08;Contrastive Language-Image Pre-training&#xff09;模型扮演了一個關鍵的角色&a…

Biotin aniline,生物素苯胺,用于研究蛋白質結構和功能

您好&#xff0c;歡迎來到新研之家 文章關鍵詞&#xff1a;769933-15-5&#xff0c;Biotin aniline&#xff0c;生物素苯胺&#xff0c;Biotin-aniline&#xff0c;生物素-苯胺 一、基本信息 【產品簡介】&#xff1a;Biotin aniline is composed of three parts: biotin, w…