threejs 加载两个场景_threejs中的三维场景操作

在threejs开发中,不可避免的需要对三维场景进行交互,例如对模型进行旋转,缩放,平移等操作。接下来,我们就聊一聊如何进行三维场景的交互。

控制的对象是谁?

在三维的世界中,如果想达到场景的TRS(translate、rotate、scale)操作,我们其实有两种办法来做到。一种是对模型本身进行TRS操作,通过改变模型的属性,达到视觉上的效果。第二种是对相机进行操作,把相机拉远模型自然缩小了,把相机移动,模型自然就向相反方向移动了。

两种方式各自有各自的特点和使用场景。操作模型,我们可以控制每个模型的TRS,比如在一个家装场景中,我们要对某个家具进行拖动,缩放。操作相机,我们可以对整个场景进行操作,比如拉远相机,查看场景全局外观。两种方式经常也会配合在一起使用。

操作模型

操作模型,首先,选中需要操作的模型。这部分需要,用到我们之前介绍过的拾取操作,首先拾取都某个三维模型,作为选中对象。然后我们才能对选中对象进行操作。第二部分是鼠标及手势的输入及判断。例如我们需要使用鼠标的滚轮触发缩放操作,或者触屏双指进行缩放操作。最后,就是进行模型的属性修改,在threejs中一般使用position,rotate,scale来达到修改模型外观的目的。

我们从最简单的模型缩放来具体讲讲如何实现。

缩放

renderer.domElement.addEventListener("mousewheel", (event) => {

var scaleFactor= 0.001; //鼠标滚轮控制的缩放强度系数

var scale = 1 + event.wheelDelta * scaleFactor; //缩放倍数

cube.scale.multiplyScalar(scale)

})

平移

对于平移来说,我们需要设置一个参考面,让这个模型在这个参考面上进行平移。一般来说我们常见的平移方式有固定参考面,比如地面、墙面。除此以外还有就是相机朝向的参考面。

如图所示,我们以mesh的中心点为面上的一个点,然后以相机的朝向为法向量,可以创建一个平面。整个鼠标的拖动都应该在这个面上。

let dragTarget = null; //拖拽对象

let raycaster = new THREE.Raycaster(); //射线

let mouse = new THREE.Vector2(); //鼠标位置

let hit = new THREE.Vector3(); //射线在参考面上的拾取点

let plane = new THREE.Plane(); //拖拽参考面

plane.setFromNormalAndCoplanarPoint(camera.getWorldDirection(), cube.position);

//let helper = new THREE.PlaneHelper( plane, 50, 0xffff00 ); //拖拽参考面的可视化帮助类

//scene.add( helper );//添加拖拽参考面的可视化帮助类到场景

renderer.domElement.addEventListener("mousedown", (event) => {

mouse.x = (event.clientX / window.innerWidth) * 2 - 1;

mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

raycaster.setFromCamera(mouse, camera);

let intersects = raycaster.intersectObjects([cube], true);

if (intersects.length > 0) {

dragTarget = intersects[0].object;

}

})

renderer.domElement.addEventListener("mousemove", (event) => {

if (dragTarget) {

mouse.x = (event.clientX / window.innerWidth) * 2 - 1;

mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

raycaster.setFromCamera(mouse, camera);

raycaster.ray.intersectPlane(plane, hit);

if (hit) {

cube.position.copy(hit);

console.log(hit)

}

}

})

renderer.domElement.addEventListener("mouseup", (event) => {

dragTarget = null;

})

旋转

一般来说,我们旋转物体都是沿着某个轴的,比如Y轴。我们以鼠标X移动的增量作为参数,沿着模型Y轴方向旋转。

let lastX = null;

renderer.domElement.addEventListener("mousedown", (event) => {

lastX = event.clientX;

})

renderer.domElement.addEventListener("mousemove", (event) => {

if (lastX) {

let delta = event.clientX - lastX

cube.rotateY(delta * 0.01)

lastX = event.clientX;

}

})

renderer.domElement.addEventListener("mouseup", (event) => {

lastX = null;

})

操作相机

threejs为我们提供了一系列的相机操作控件。对于相机控制,最常用的就是OrbitControls控件(一般放在threejs的examples/jsm/controls/OrbitControls.js)。使用起来也比较简单。只需importy引入文件,然后new出一个控件即可。这里注意就是如果copy文件到项目目录,需要手动修改js文件中关于threejs的引用,因为控件中的threejs是引用的是编译出来的文件相对地址,不是通过npm安装的地址。

import {

OrbitControls

} from '../lib/controls/OrbitControls'

const controls = new OrbitControls(camera, renderer.domElement);

控件提供了鼠标左键旋转,右键平移,滚轮缩放的功能,并且支持手势操作。

以上就是对threejs中三维场景操作控制的说明,后续我们将继续讲讲如何在3d场景中加入一些动画。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法题目——最长连续序列

题目链接:leetcode.128 思路: 1.现将数据存放到数组中去 2.再将数据存到一个集合set中去(方便去重,查找某一个元素是否存在于数组中) 3.循环该数组,若该元素的前一个元素不在数组中(通过集合来查找),说明它将会是一个连续序列的开始元素,在对该元素循环查看它的下一个元素…

如何在 ASP.NET Core 中实现全局异常拦截

异常是一种运行时错误,当异常没有得到适当的处理,很可能会导致你的程序意外终止,这篇就来讨论一下如何在 ASP.Net Core MVC 中实现全局异常处理,我会用一些 样例代码 和 截图 来说明这些概念。全局异常处理 其实在 ASP.Net Core M…

算法题目——被围绕的区域(dfs,bfs)

leetcode.130被围绕的区域 dfs解法: 深度优先遍历: 思路: 读取数据后 1.先将数据的四周进行bfs算法(因为只有与外围接触的点,才能不被包围) 算法执行中时,递归看看该点的上下左右有没有是O的,如果是O则标记为A 2.循环完四周之后,将数据中的O全部换成X,将全部的A换成O即得…

qt 从文件中读出数据显示在表格中_QT中有什么控件可以实现向excel的表格显示,qt数据存储到Excel表格...

QT 如何读取大数据量的Excel文件?貌似Excel最多只有1048576行,你这150万行我不知道是怎么放到一个表里面的。数据100多玩行你可以将数据存放在Access或者其他的数据库中或许会比较好一点。QT中有什么控件可以实现向excel的表格显示QTableWidgetQTableVie…

[Windows] 在 Microsoft Docs 网站中挖掘 MVVM 的各种学习资源

最近写了一些 MVVM 框架的文章,翻了一些 Microsoft Docs 的文档,顺便就对 MVVM 本身来了兴致,想看看更多当年相关的文档。在 MVVM 出现后十多年,我在不同的场合见到过多种 MVVM 的实现方式,也看到过各种 MVVM 框架的多…

算法题目——岛屿数量(bfs dfs)

题目链接:leetcode.200岛屿数量 dfs 重点:路过过的点做新标记 ,以防止重复路过 思路: 数据读取完成后 1.对所有数据进行一次循环 2.在循环内部,如果元素为‘1’则进入dfs算法 3.在深度优先遍历中,先将该元素标记为‘0’,在查看它的上下左右元素是否为‘1’,是‘1’则进…

注意| .NET开发者大会防疫须知 !

2020年12月19-20日中国.NET开发者大会将于苏州举办疫情常态化的情况下为确保大会顺利进行大会组委会从会议内容、会务筹备等方面均进行了全面的精细准备以下是组委会发布的参会防疫指南敬请所有现场参会的小伙伴认真阅读并严格按照防疫需求作相应准备▽为保证大会的顺利召开&am…

tensorflow打印模型图_从Tensorflow模型文件中解析并显示网络结构图(pb模型篇)...

最近看到一个巨牛的人工智能教程,分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。平时碎片时间可以当小说看,【点这里可以去膜拜一下大…

算法题目——省份数量(dfs,bfs)

题目链接:leetcode.547省份数量 dfs: 深度优先遍历:递归 思路:读入数据完成后 重点:建立一个数组记录该省份是否访问,新建一个元素记录省份圈的个数 1.对所有省份循环一次,如果该省份未被访问,则进入dfs 2.dfs中,对所有省份循环一遍,如果未被访问且省份index可以到达…

两台思科交换机vlan划分_Cisco交换机Vlan划分及ACL配置详细步骤 | 吴文辉博客

一、开机1、如是新设备,开机需跳过系统默认配置模式,进入手动配置模式。2、进入用户模式,系统提示符为 >,此模式只能查看统计信息,无配置功能。3、用户模式下,输入 enable ,进入特权模式&…

用重构指导Clean Code(二):依恋情结和switch语句

书接上回,我们继续聊如何用重构指导Clean Code。在Clean Code的3.4节中有这样一段代码(代码清单3-4)。(第3章主要讲的是函数,而3.4节讨论的是switch语句。)public Money calculatePay(Employee e) throws I…

算法题目——杨辉三角问题

思路: #include<iostream> #include<cstdio> #include<cstring> #

cascade down_Cascaded CNN 方法寻找人脸关键点

Cascaded CNN 方法寻找人脸关键点论文笔记阅读论文第一阶段阅读论文&#xff0c;大约两天大体阅读完论文 Deep Convolutional Network Cascade for Facial Point Detection。感觉还是比较缺乏论文阅读经验&#xff0c;但是比以前快了很多。主要阅读论文 intro、method 和 model…

了解一下HTTP1.1 Pipelining技术

为什么谈HTTP1.1 Pipelining呢&#xff1f;主要问题根源还是来源于Beetlex参加了techempower的测试。先看一下以下两项测试的结果&#xff1a;以上分别是.net平台的Json和Plaintext的测试结果&#xff0c;其实Plaintext最高能跑700多万RPS已经完全超了对网络IO读写损耗的认知&a…

springboot2 多线程写入数据_解决SpringBoot项目使用多线程处理任务时无法通过@Autowired注入bean问题...

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":7,"count":7}]},"card":[{"des":"EDAS 是一个应用托管和微服务管理的PaaS平台…

算法题目——子序列和问题(poj-3061)(尺取法)

题目链接:POJ-3061 题意:给定一个序列,使得其和大于或等于S,求最短的子序列长度。 问题分析: 1.首先序列都是正整数,当子序列和大于等于S时,已经没有必要再将右端点继续向右移动。因为再向右移动,序列的长度一定会大于此时的长度 2.所以,当子序列和小于S时,右端点向…

读书 | 数字化转型的道与术(下)

【数字化转型】| 作者 / Edison Zhou这是EdisonTalk的第313篇学习总结 最近在阅读钟华老师的新作《数字化转型的道与术》&#xff0c;记录和总结了一些学习笔记和感想&#xff0c;整理成文分享与你&#xff0c;本文为下半部分&#xff0c;希望能对也在参与数字化转型的各位童鞋…

算法题目——读书知识点统计问题(POJ-3320)(尺取法)

题目链接:poj-3320 问题:杰西卡是一个非常可爱的女孩,受到许多男孩的追捧。最近她有个问题。期末考试快到了,但她几乎没花什么时间。如果她想通过考试,她必须掌握一本厚厚的教科书中包含的所有思想。那本教科书的作者和其他作者一样,对这些观点极为挑剔,因此有些观点被…

aop springboot 传入参数_Springboot添加AOP打印请求参数

1. 引入依赖org.springframework.bootspring-boot-starter-aop2. 写切面切面类需要加Aspect和Component注解package com.test.demo.aspect;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.Pro…

GraphQL:面对复杂类型

GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述&#xff0c;使得客户端能够准确地获得它需要的数据&#xff0c;而且没有任何冗余&#xff0c;也让 API 更容易地随着时间推移而演进&#xff0c…