BabylonJS 6.0文档 Deep Dive 摄像机(二):摄像机碰撞

news2024/11/13 10:33:57

摄像机、网格碰撞和重力

你玩过第一人称射击游戏(FPS)吗?在本教程中,我们将模拟FPS的摄影机移动:摄影机位于地板上,与地面碰撞,并可能与场景中的任何对象碰撞。

如何实现?

为了实现这一功能,我们必须执行3个简单步骤:

1.定义并应用重力

首先要做的是定义重力矢量,定义重力。

Babylon.js的Scene类具有重力属性,可以应用于您之前在代码中定义的任何相机。这将沿指定的方向和速度移动摄影机(Vector3对象),除非摄影机的椭球体(参见下面的第2步)在checkCollisions设置为true的情况下与该方向上的另一个网格(如地面网格)发生碰撞。

Scene设置重力属性

scene.gravity = new BABYLON.Vector3(0, -0.15, 0);

摄像机开启重力属性

camera.applyGravity = true;

在现实世界中,重力是一种向下施加的力,即沿Y轴的负方向施加的力。在地球上,这一力大约为9.81m/s²。下落物体在下落时会加速,因此需要1秒才能完全达到这一速度,然后在2秒后速度达到19.62m/s,在3秒后达到29.43m/s... 在大气层中,风阻力将最终与这一力相匹配,自由落体速度也会停止增加(达到“终极速度”)。

然而,Babylon.js遵循了一个简单得多的引力模型 - scene.gravity表示恒定的速度,而不是加速度,它是以单位/帧而不是米/秒来测量的。渲染每个帧时,应用该重力的摄影机将沿每个轴移动矢量值(通常x和z设置为0,但您可以在任何方向上使用“重力”!),直到检测到碰撞。

虽然Babylon.js单元距离(unit)没有直接对应物理世界的东西,但在默认的相机视场下,1个单元距离=1米的近似值是一个相当标准的假设。因此,如果想要模拟地球重力,你需要对每秒渲染的帧数做出一些假设,并计算一个合适的矢量:

const assumedFramesPerSecond = 60;
const earthGravity = -9.81;
scene.gravity = new BABYLON.Vector3(0, earthGravity / assumedFramesPerSecond, 0);

由于这是每帧计算一次,所以相机实际上并没有“移动”,而是沿着重力矢量的方向进行微小的“跳跃”。如果您依靠碰撞检测来确定相机(或者更确切地说,是为此目的附着在相机上的网格)是否“进入”或“退出”了其他网格(例如,“地面”层下的一个平面,用于感测下落的角色并重置游戏),这一点可能很重要。根据您选择的重力、起始高程以及“触发”网格的位置和高度,相机可能会直接跳过触发网格,而不会与之“相交”。因此请务必检查Math类,以确保添加到起始高程的场景重力的至少一个倍数会与触发网格相交。

如果你需要更准确地表示引力(或其他力),你可以使用Babylon集成的物理引擎,或者添加自定义的物理引擎。

警告:

如在一对象上添加physicsimpostor(自定义的外部物理引擎)并同时启用碰撞(collision),可能会导致意外行为。

2. 定义椭圆球体

下一个重要步骤是定义相机周围的椭圆球体。这个椭圆球体代表了我们玩家的尺寸:当对象网格与这个椭圆球体接触时,会引发碰撞事件,防止我们的相机离这个对象网格太近:

Babylon.js相机上的椭圆球属性默认为尺寸大小为(0.5、1、0.5)。更改这些值会使您变高、变大、变小、变瘦。在下面的示例中,我们将使相机的椭圆球体比默认的更胖:

//Set the ellipsoid around the camera (e.g. your player's size)
camera.ellipsoid = new BABYLON.Vector3(1, 1, 1);

请注意,摄像机的椭圆球体应该是偏移的,以便是视点(眼睛)始终位于椭球体的顶部。

可以通过更新椭球体偏移特性来控制此行为。

计算方法如下:

finalPosition = position - vec3(0, ellipsoid.y, 0) + ellipsoidOffset

3. 应用碰撞

我们的最后一步是声明我们对感知场景中的碰撞感兴趣:

scene.collisionsEnabled = true;
camera.checkCollisions = true;

以及要声明哪些网格可能与我们的相机发生碰撞(box和ground):

ground.checkCollisions = true;
box.checkCollisions = true;

非常简单,以下是案例代码:

4.物体与物体碰撞

你可以通过对物体网格(Mesh)的ellipsoid属性和moveWithCollisions(速度)函数的使用来达到相同的效果。此函数将尝试根据给定的速度移动Mesh,并检查当前模型与激活了checkCollisions的所有模型之间是否产生了碰撞。

也可以使用mesh.ellipsoidOffse来移动网格上的椭球体(默认情况下,椭球体以网格为中心)。

代码如下:

const speedCharacter = 8;
const gravity = 0.15;
const character = Your mesh;

character.ellipsoid = new BABYLON.Vector3(0.5, 1.0, 0.5);
character.ellipsoidOffset = new BABYLON.Vector3(0, 1.0, 0);

const forwards = new BABYLON.Vector3(parseFloat(Math.sin(character.rotation.y)) / speedCharacter, gravity, parseFloat(Math.cos(character.rotation.y)) / speedCharacter);
forwards.negate();
character.moveWithCollisions(forwards);
// or
const backwards = new BABYLON.Vector3(parseFloat(Math.sin(character.rotation.y)) / speedCharacter, -gravity, parseFloat(Math.cos(character.rotation.y)) / speedCharacter);
character.moveWithCollisions(backwards);

案例如下:

弧形旋转摄像机(Arc Rotate Camera)的碰撞

ArcRotateCamera也可以检查碰撞,但碰撞发生时,该相机不会移动。

如要激活碰撞,只需将camera.checkCollisions设置为true。还可以定义碰撞半径:

camera.collisionRadius = new BABYLON.Vector3(0.5, 0.5, 0.5);

其他类型的碰撞

太好了,现在你可以开发一款真正的FPS游戏了!但也许你想知道一个网格何时与另一个网格碰撞?如果你对此感兴趣,你可以在这里学习:网格碰撞。

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

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

相关文章

Linux———head命令详解

目录 head 命令是一个用于在命令行中显示文件开头部分内容的常用工具。 head 命令基本语法: 常用选项 示例 显示文件的前 10 行: 显示文件的前 5 行: 显示文件的前 100 个字节: 不显示文件名的标题信息: 显示…

Elasticsearch基本操作之文档操作

本文来说下Elasticsearch基本操作之文档操作 文章目录 文档概述创建文档示例创建文档(生成随机id)创建文档(自定义唯一性标识) 查看文档示例根据主键查看文档查看所有文档 本文小结 文档概述 文档概述 在创建好索引的基础上来创建文档,并添加数据。这里的文档可以类…

Unity 利用UGUI之Slider制作进度条

在Unity中使用Slider和Text组件可以制作简单的进度条。 首先在场景中右键->UI->Slider,新建一个Slider组件: 同样方法新建一个Text组件,最终如图: 创建一个进度模拟脚本,Slider_Progressbar.cs using System.C…

QT qss文件设置样式

方式一 (单个) 方式二 (全局) 所有按钮都会采用这个样式。 方式三 (qss文件) 创建资源文件 创建qss文件(Button.qss) 引用qss文件 QApplication a(argc, argv);QString qss;QFile…

tiktok云手机有用吗?用哪个好?

很多做独立站的跨境卖家都会搭配一些社媒平台给自己引流带货,比如说目前很火的TikTok,这也是目前比较有效的一种引流方式。本文将介绍tiktok运营方法以及如何用tiktok云手机规避运营风险。 TikTok是个不错的风口,不过我们在国内想要运营好Tik…

7 种常见的前端安全攻击

文章目录 七种常见的前端攻击1.跨站脚本(XSS)2.依赖性风险3.跨站请求伪造(CSRF)4.点击劫持5.CDN篡改6. HTTPS 降级7.中间人攻击 随着 Web 应用程序对业务运营变得越来越重要,它们也成为更有吸引力的网络攻击目标。但不…

Vue3-44-Pinia- 安装步骤

介绍 本文介绍 在 vue3 中 安装 Pinia 的步骤 安装步骤 1、npm 安装 npm install pinia》 安装完成后可以看到 package.json 中添加了 pinia 的依赖信息 2、main.ts 中配置 // 引入 vue实例创建方法 import { createApp } from vue// 引入pinia import { createPinia } fro…

10086 shop

中国移动网上商城--个人中心 查看套餐收费流程

安防视频云平台/可视化监控云平台ARM版EasyCVR无法下载录像文件,如何解决?

视频集中存储/云存储/视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。GB28181视频监控/AI智能大数据视频分析EasyCVR平台已经广泛应用在工地…

Java LeetCode篇-二叉搜索树经典解法(实现:二叉搜索树的最近公共祖先、根据前序遍历建树等)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 判断合法 1.1 使用遍历方式实现验证二叉搜索树 1.2 使用递归方式实现验证二叉搜索树 2.0 求范围和 2.1 使用非递归实现二叉搜索树的范围和 2.2 使用递归方式实现…

【模拟IC学习笔记】 采样保持电路的设计

目录 采样保持工作原理 概念 时域响应-采保信号 采样网络的KT/C噪声 采样电容大小的选取 采样抖动(jitter) jitter对SNR的影响 法一 法二 采样开关的种类 单MOS管 实践:Nmos导通电阻 传输门 栅压自举开关 采样技术 上极板采样 下极板采样 采样保持…

ArcGIS中style文件的导入及lyr的文件的使用

地图是地理信息的重要载体,科学的配色方案可以有效地传递地理信息,而美观协调的配色方案也是我们进行地图符号化设计的重要内容。在日常工作中,我们常常苦恼于自带颜色不能满足需要或是希望使用现成的颜色模板,自定义配色方案导入…

Android14之刷机模式总结(一百七十八)

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android系统攻城狮 1.前言 本篇目的:Android14之刷机模式总结: 1.bootloader模式 2.recovery模式 3.fastbootd模式 4.OTA模式2…

嵌入式Linux:环境搭建之TFTP、NFS、SSH和FTP的安装和使用

在我们做嵌入式Linux开发的时候,需要安装一些环境以方便我们的开发,本篇文章就来介绍一下TFTP、NFS、SSH和FTP的作用和环境搭建(以Ubuntu为例)。 文章目录 1 TFTP1.1 服务端1.2 客户端 2 NFS2.1 介绍2.2 安装过程2.2.1 安装nfs2.2.2 在服务端创建共享目录…

C++CLI——4数组、泛型、集合与属性

CCLI——4数组、泛型、集合与属性 C数组 在c中,数组的大小必须在编译时确定,并且将数组传递给函数时,传递的只是数组起始地址,所以要想办法连同数组大小一同传递给函数。 int arr[4] { 1,2,3,4 }; int arr1[] { 1,2,3,4 }; i…

Vue-4、单向数据绑定与双向数据绑定

1、单向数据绑定 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>数据绑定</title><!--引入vue--><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/…

进阶分布式链路追踪

另外我的新书RocketMQ消息中间件实战派上下册&#xff0c;在京东已经上架啦&#xff0c;目前都是5折&#xff0c;非常的实惠。 https://item.jd.com/14337086.html​编辑https://item.jd.com/14337086.html “RocketMQ消息中间件实战派上下册”是我既“Spring Cloud Alibaba微…

C++面试宝典第16题:盛最多水的容器

题目 给定n个非负整数a1、a2、…、an,每个数代表坐标中的一个点(i, ai)。画n条垂直线,使得第i条垂直线的两个端点分别为(i, ai)和(i, 0)。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。说明:不能倾斜容器,且n的取值至少为2。 在下图中,垂直线代表的输…

时序预测 | Matlab实现GJO-VMD-LSTM金豺-变分模态分解-长短期记忆网络时间序列预测

时序预测 | Matlab实现GJO-VMD-LSTM金豺-变分模态分解-长短期记忆网络时间序列预测 目录 时序预测 | Matlab实现GJO-VMD-LSTM金豺-变分模态分解-长短期记忆网络时间序列预测预测效果基本介绍模型设计程序设计参考资料 预测效果 基本介绍 Matlab实现GJO-VMD-LSTM金豺-变分模态分…

【uniapp】调用阿里云OCR图片识别文字:

文章目录 一、效果&#xff1a;二、实现&#xff1a; 一、效果&#xff1a; 二、实现&#xff1a; 【阿里官方】高精版OCR文字识别【最新版】-云市场-阿里云 <template><view class"container"><!-- 选择图片 --><button click"imageO…