3D看房實現房屋的切換

作為3D看房的補充,在這里,我們講一下如何實現房屋的切換,我這里提供兩種思路,

  • 切換貼圖,
  • 切換場景,

接下我們按照較復雜的場景切換來講,切換貼圖也就水到渠成:

  1. 初始化場景:創建多個場景,并根據需求切換。
  2. 處理點擊事件:通過射線投射(Raycasting)檢測點擊位置與對象的交點。
  3. 動態更新場景:根據點擊事件的結果切換場景或執行其他邏輯。

以下是詳細的實現步驟和代碼示例:


1. 初始化多個場景

首先,我們需要創建多個場景。每個場景可以包含不同的對象、燈光和相機設置。

import * as THREE from 'three'// 創建場景1
const scene1 = new THREE.Scene()
scene1.background = new THREE.Color(0x0000ff) // 藍色背景
const cube1 = new THREE.Mesh(new THREE.BoxGeometry(),new THREE.MeshBasicMaterial({ color: 0xff0000 })
)
cube1.position.set(0, 0, 0)
scene1.add(cube1)// 創建場景2
const scene2 = new THREE.Scene()
scene2.background = new THREE.Color(0x00ff00) // 綠色背景
const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({ color: 0xffff00 })
)
sphere.position.set(0, 0, 0)
scene2.add(sphere)// 當前場景
let currentScene = scene1

2. 處理點擊事件

使用射線投射(Raycasting)檢測用戶點擊的對象。如果點擊了特定對象,則可以觸發場景切換或其他邏輯。

// 相機和渲染器
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 5
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)// 射線投射器
const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()// 點擊事件處理函數
function onCanvasClick(event: MouseEvent) {// 計算標準化設備坐標mouse.x = (event.clientX / window.innerWidth) * 2 - 1mouse.y = -(event.clientY / window.innerHeight) * 2 + 1// 設置射線投射器raycaster.setFromCamera(mouse, camera)// 檢測當前場景中的交點const intersects = raycaster.intersectObjects(currentScene.children)if (intersects.length > 0) {const clickedObject = intersects[0].objectconsole.log('點擊的對象:', clickedObject)// 如果點擊的是立方體,則切換到場景2if (clickedObject === cube1) {console.log('切換到場景2')currentScene = scene2}}
}// 監聽畫布點擊事件
window.addEventListener('click', onCanvasClick)

3. 渲染循環

在渲染循環中,確保渲染當前場景的內容。

function animate() {requestAnimationFrame(animate)// 渲染當前場景renderer.render(currentScene, camera)
}
animate()

4. 完整代碼示例

以下是完整的代碼示例,展示了如何初始化多個場景、處理點擊事件并動態切換場景:

import * as THREE from 'three'// 創建場景1
const scene1 = new THREE.Scene()
scene1.background = new THREE.Color(0x0000ff) // 藍色背景
const cube1 = new THREE.Mesh(new THREE.BoxGeometry(),new THREE.MeshBasicMaterial({ color: 0xff0000 })
)
cube1.position.set(0, 0, 0)
scene1.add(cube1)// 創建場景2
const scene2 = new THREE.Scene()
scene2.background = new THREE.Color(0x00ff00) // 綠色背景
const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32),new THREE.MeshBasicMaterial({ color: 0xffff00 })
)
sphere.position.set(0, 0, 0)
scene2.add(sphere)// 當前場景
let currentScene = scene1// 相機和渲染器
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.z = 5
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)// 射線投射器
const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()// 點擊事件處理函數
function onCanvasClick(event: MouseEvent) {// 計算標準化設備坐標mouse.x = (event.clientX / window.innerWidth) * 2 - 1mouse.y = -(event.clientY / window.innerHeight) * 2 + 1// 設置射線投射器raycaster.setFromCamera(mouse, camera)// 檢測當前場景中的交點const intersects = raycaster.intersectObjects(currentScene.children)if (intersects.length > 0) {const clickedObject = intersects[0].objectconsole.log('點擊的對象:', clickedObject)// 如果點擊的是立方體,則切換到場景2if (clickedObject === cube1) {console.log('切換到場景2')currentScene = scene2}}
}// 監聽畫布點擊事件
window.addEventListener('click', onCanvasClick)// 渲染循環
function animate() {requestAnimationFrame(animate)// 渲染當前場景renderer.render(currentScene, camera)
}
animate()

關鍵點說明

  1. 場景切換

    • 使用一個變量(如 currentScene)來跟蹤當前活動的場景。
    • 在點擊事件中,根據條件切換 currentScene 的值。
  2. 射線投射(Raycasting)

    • 使用 THREE.Raycaster 和鼠標位置計算點擊的對象。
    • 根據點擊結果執行邏輯(如切換場景或高亮對象)。
  3. 渲染循環

    • 在渲染循環中,始終渲染 currentScene,以確保顯示正確的場景。

注意事項

  • 只讀屬性問題

    • 如果你遇到類似 hotspot.name = 'hotspot-1' 的錯誤,請檢查 hotspot 是否被凍結或標記為只讀。
    • 解決方法包括避免直接修改只讀屬性,或者創建新的對象來更新值。
  • 性能優化

    • 如果場景中有大量對象,可以通過優化射線投射的檢測范圍(如僅檢測特定對象組)來提高性能。

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

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

相關文章

[Android]ANR的線程

ANR的原理是進行了超時告警,在執行一個需要被監控的任務時,注冊一個超時提醒,如果很快執行好了,刪除這個提醒,如果超時,這個提醒就被觸發,這個超時處理是通過handler方式來調用的,這…

RLVR來做Agent任務能力增強訓練

和上一篇其實有點承接 上一篇的爭論其實是因為要優化agent的任務規劃和實現能力的 所以有了self-learning之爭 當我們說Self-learning,其實是在說什么? 其實上一篇最后時候提了一點拿RLVR來做agent的任務提升 正好今天看到了一篇應景的論文&#xf…

如何運營一個開源項目并取得較大影響力?

開源不僅是主要的軟件開發方法論,還是助力快速創新、分散協作、 生態系統建設和職業發展的卓越戰略。如今,無論在哪里,都離不開與 開源的互動。開源存在于你的手機、汽車和冰箱中,它使你最喜歡的節 目或電影的制作和發行成為可能&…

華為高斯數據庫的數據類型

華為高斯數據庫的數據類型 國產數據庫華為高斯的GaussDB的數據類型 華為高斯數據庫的數據類型? 一、數值類型(Numeric Types)? 二、字符類型(Character Types)? 三、布爾類型(Boolean Type)? 四、日期和…

生物實驗室安全、化學品安全

zhihu.com/column/c_1922752541369800632 Docs 目錄 第七章 7.1 實驗室生物安全等級 7.1.1 生物安全基本概念 7.1.2 生物的危害等級 7.1.2.1 國內生物危害等級 7.1.3 實驗室生物安全防護水平分級 7.2 實驗室生物安全控制 7.2.1 實驗室生物儀器設備安全控制 7.2.1.1 生…

【QT】第一個QT程序 || 對象樹 || 編碼時的注意事項

一、編寫第一個 Qt 程序 1. 開發環境搭建 安裝 Qt Creator(推薦使用官方在線安裝器)安裝 Qt 庫(如 Qt 5.15.2 或 Qt 6.x)配置編譯器(MinGW / MSVC / GCC) 2. 創建一個簡單的 Qt GUI 應用程序 打開 Qt C…

多服務器IP白名單配置(使用redis stream實現)

應用背景 現在我有一個管理平臺,可以通過代理連接到內網網站,但是這個代理服務器沒有設置密碼,所以需要IP白名單讓指定用戶才可以使用代理。 添加白名單流程圖 流程描述: 登錄管理平臺成功后,管理平臺的后臺將這個登錄的IP地址添加到redis,并設置過期時間為24小時redis…

Vue 3 Teleport 特性

目錄 基本用法? 搭配組件使用? 禁用 Teleport? 多個 Teleport 共享目標? 延遲解析的 Teleport ? 總結 <Teleport> 是一個內置組件&#xff0c;它可以將一個組件內部的一部分模板“傳送”到該組件的 DOM 結構外層的位置去。 基本用法? 有時我們可能會遇到這…

常用指令合集(DOS/Linux/git/Maven等)

文章目錄 常用指令收集vmware 虛擬機聯網設置ubuntu 常見問題設置apt 相關指令&#xff1a;gcc 編譯相關指令 sqlite3VSCode 快捷鍵&#xff1a;收索引擎技巧&#xff08;google&#xff09;Intelideashell--LinxvimgitDOS:mavendockerkubectl 指令nginx配置redis-clientMySQLl…

ABP VNext + MassTransit:構建分布式事務與異步消息協作

ABP VNext MassTransit&#xff1a;構建分布式事務與異步消息協作 &#x1f680; &#x1f4da; 目錄 ABP VNext MassTransit&#xff1a;構建分布式事務與異步消息協作 &#x1f680;&#x1f4da; 1. 背景與動機&#x1f6e0;? 2. 環境與依賴&#x1f527; 3. 在 ABP 模塊…

語義網技術

用通俗語言說語義網技術&#xff0c;以及它和現在互聯網的關系 一、語義網技術&#xff1a;讓網絡“聽懂人話”的智能升級 現有互聯網就像一本巨大的“圖文報紙”&#xff1a;我們人類看文章、圖片能輕松理解意思&#xff0c;但計算機只能識別文字符號&#xff0c;不知道“蘋…

pytorch學習—4.反向傳播(用pytorch算梯度)

2. 線性模型 3.梯度下降算法 4.反向傳播_嗶哩嗶哩_bilibili 4.1 代碼復現 import torch import matplotlib.pyplot as pltx_data=[1.0,2.0,3.0] y_data=[2.0,4.0,6.0]#這里創建了一個PyTorch張量w,初始值為1.0,并且設置requires_grad=True, #這意味著在計算過程中,PyTo…

7類茶葉嫩芽圖像分類數據集

在茶葉育種、溯源管理與自動采摘等智能農業場景中&#xff0c;茶樹品種的識別與分類是一項關鍵任務。不同茶葉品種在嫩芽期表現出顯著的形態差異&#xff0c;例如顏色、葉緣結構、芽頭密度等。因此&#xff0c;基于圖像的茶葉品種分類不僅具備實際應用價值&#xff0c;也為農業…

【Elasticsearch】Linux環境下安裝Elasticsearch

一&#xff0c;前言 Elasticsearch&#xff08;簡稱 ES&#xff09;是一個基于 ??Apache Lucene?? 構建的開源分布式搜索與分析引擎。它支持??實時數據處理??&#xff0c;提供近實時的全文搜索能力&#xff0c;并通過 ??JSON 格式的 RESTful API?? 實現數據索引與檢…

【數據結構--樹于哨兵查找-1】

查找 從前到后- 線性查找 -就是順序查找. 哨兵法查找–節省每次都要判斷是否越界的這一步驟利于節省開銷&#xff0c;從而提升效率。 參考我的程序 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <stdbool.h>#define SIZE …

MyBatis修改(update)操作

1. 三步法口訣 “接口收對象&#xff0c;SQL全賦值&#xff0c;主鍵定目標” 2. 詳細記憶點 | 步驟 | 口訣 | 說明與示例 | |--------------|----------------|----------------------------------------------------------------------------| | 1. 寫接口 | “接口收對象…

Spring Boot 入門學習

一、 Web應用開發概述 什么是Web應用 1. Web應用 &#xff08;Web Application&#xff09;是一種運行在Web服務器上的軟件程序&#xff0c;由用戶通過Web瀏覽器進行訪問和交互。 2.Web應用與傳統的桌面應用不同&#xff0c;它不需要在個人計算機上安裝特定的軟件&#xff0…

深度解讀概率與證據權重 -Probability and the Weighing of Evidence

以下是I.J.古德&#xff08;I.J. Good&#xff09;的經典著作 《概率與證據權衡》&#xff08;Probability and the Weighing of Evidence, 1950&#xff09; 的中文詳細總結&#xff1a; 本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒…

跟著AI學習C#之項目實戰-電商平臺 Day6

&#x1f4c5; Day 6&#xff1a;后臺管理系統開發&#xff08;Admin Panel&#xff09; ? 今日目標&#xff1a; 創建管理員頁面布局實現商品管理&#xff08;CRUD&#xff09;實現訂單管理&#xff08;查看、狀態變更&#xff09;添加權限控制&#xff08;僅管理員可訪問&…

使用OpcUaHelper在C# WinForms中連接OPC UA服務器并讀取數據

使用OpcUaHelper在C# WinForms中連接OPC UA服務器并讀取數據 下面是一個完整的示例&#xff0c;展示如何使用OpcUaHelper庫在C# WinForms應用程序中連接OPC UA服務器并讀取數據。 1. 準備工作 首先&#xff0c;確保你已經安裝了OpcUaHelper NuGet包。可以通過NuGet包管理器控…