【iOS ARKit】RealityKit 中的物理组件

       在 RealityKit 中,对虚拟物体进行物理模拟时需要在该物体实体对象上挂载物理组件,物理引擎会忽略所有未挂载物理组件的物体,RealityKit 包含两个跟物理相关的组件:PhysicsBodyComponent 和PhysicsMotionComponent,ModelEntity 实体类默认带有这两个组件,即使用 ModelEntity 类创建的实体都会参与物理模拟。

PhysicsBodyComponent 组件

      PhysicsBodyComponent 组件以纯物理的方式处理力、质量、材质属性,根据牛顿力学模拟物体的运动。它是 RealityKit 物理模拟最主要的组件,利用该组件可以设置物体质量、物理质、物理类型、受力等所有与物理相关的属性。需要注意的是,物理模拟要起作用,物体还必须要有CollisionComponent 组件。

     PhysicsBodyComponent 组件属性从功能上可以分为3大类:物理属性类、力学属性类和辅助类。物理属性类主要包括表9-1所示物理属性。

表9-1 物理属性类

属性名称

描述

mode

PhysicsBodyMode 属性,定义物体受力影响的类型

massProperties

PhysicsMassProperties 属性,定义物体质量相关属性

material

PhysicsMaterialResource 属性,定义物体的物理材质

is TranslationLocked

移动限制,定义物体是否在某个或几个轴方向上锁定移动,默认不限制。限制移动可以限制物体在指定范围内,如限制桌子在Y轴上的移动,不允许桌子悬空

isRotationLocked

旋转限制,定义物体是否在某个或几个轴方向上锁定旋转,默认不限制。限制旋转可以限制物体的旋转范围,如限制车轮在Z轴上的旋转,不允许车轮翻转

isContinuousCollisionDetectionEnabled

连续碰撞检测,常称为 CCD,用于快速运动物体的碰撞检测,性能开销比较大,默认 false。如子弹射击时,由于子弹速度快,可能会在两次物理模拟循环之间穿过某个物体,导致漏检,利用CCD可以检测子弹等快速移动物体与其他物体的碰撞

      从表9-1可以看出,物理属性类定义了物理模拟所需要的各类参数,这些参数设置会直接影响物理模拟后物体的运动表现。力学属性类主要处理与力相关的动态工作,如表9-2所示。

表9-2 力学属性类

方法名称

描述

addForce (SIMD3 < Float >, relative To:Entity?)

在物体的质心处施加一个力,这个力相对于 relativeTo实体的坐标空间,nil为世界空间。施加的力在下一个模拟周期中执行,且在一个完整的模拟周期执行完后被移除

addForce (SIMD3 < Float >, at: SIMD3< Float>, relativeTo: Entity?)

在物体的指定位置施加一个力,这个力相对于 relativeTo实体的坐标空间,nil为世界空间。施加的力在下一个模拟周期中执行,且在一个完整的模拟周期执行完后被移除

add Torque (SIMD3 < Float>, relative To:Entity?)

在物体的质心处施加一个力矩,这个力矩相对于 relativeTo实体的坐标空间,nil为世界空间。施加的力矩在下一个模拟周期中执行,且在一个完整的模拟周期执行完后被移除

clearForcesAndTorques ()

清除施加到物体的所有力与力矩

applyLinearImpulse (SIMD3 < Float >,

relative To: Entity?)

在物体的质心处施加一个线性冲量,这个冲量相对于 relativeTo实体的坐标空间,nil为世界空间

applyAngularlmpulse(SIMD3 < Float >,

relative To: Entity?)

在物体的质心出施加一个线性冲量,这个冲量相对于 relativeTo实体的坐标空间,nil 为世界空间

applyImpulse (SIMD3 < Float >,at:SIMD3 < Float >,relativeTo: Entity?)

在物体的指定位置施加一个线性冲量,这个冲量相对于 relativeTo实体的坐标空间,nil 为世界空间

reset Physics Transform (recursive: Bool)

重置模拟物理体的位置、方向和速度

     使用表9-2中的方法,可以按照牛顿力学的方式对物体施加力、力矩、冲量,如果对不活跃的物体(Entity.isActive=false)施加力、力矩、冲量,物理引擎不会进行模拟计算,也不会有任何效果。addForce和addlmpulse 是两种施加力的方式,Impulse称为冲量,是一个与时间有关的物理量,单位是kg•m/s, 而力是与时间无关的物理量,单位是牛顿。

提示:冲量描述了动量(momentum)的改变量,Impulse=m(W」一w2),而F=ma,因此F=m(V1一V2)/t,所以Impulse=Ft,即冲量是力与该力作用时间的乘积。物理引擎中的材质称为物理材质,物理材质定义了物体的物理特性,如静摩擦力、动摩擦力、弹性系数、恢复系数等

      辅助类用于辅助进行初始化或者物理模拟,主要包括表9-3所示功能。

表9-3 辅助类

名称

类型

描述

init

方法

初始化方法,共有4个重载,用于以指定质量、物理材质、物理类型初始化

PhysicsBodyComponent 组件

physics Body

属性

指向该实体的 PhysicsBodyComponent 组件

registerComponent)

方法

类方法,用于注册各类组件

     在实际的开发过程中,我们一般会通过实体的 physicsBody 属性获取该实体上挂载的PhysicsBodyComponent 组件,然后利用该组件设置物体的物理属性、施加作用力进行物理模拟。利用PhysicsBodyComponent 组件进行物理模拟是完全按照物理力学规律进行仿真计算,因此模拟结果与真实物体行力表现相一致。

     PhysicsBodyComponent 组件的mode 属性描述物体的物理类型,该值为 PhysicsBodyMode 枚举值,PhysicsBodyMode 枚举定义了物体受力影响的类型,该枚举有3个枚举值:static、kinematic、dynamic。

     1. static(静态体) 静态体参与碰撞,但不参与物理模拟,也不会移动位置。静态体存在的重要意义在于其能与动态体产生相互作用,当动态体与静态体发生碰撞时,静态体本身不会受到任何力与碰撞的影响,但动态体会遵循物理规律,受力并发生变化。如场景中的墙壁与巨大的石头,因为它们不会移动位置,在使用中,通常会用作环境物体,应当设置为静态体,不应当使用任何方式移动静态体。当一个动态体小球与墙壁或者石头发生碰撞时,墙壁和石头不会受到力的影响,也不会产生位置移动,但小球会发生受力变化,产生反弹或者改变运动方向。

    2. kinematic(动力学体)动力学体与静态体一样,也不参与物理模拟,但动力学体可以运动,其运动由开发人员自行处理,不必遵循物理学规律。动力学体也会与动态体发生碰撞并影响动态体的运动。例如电梯或者大门,这类物体可以运动,但通常不需要使用物理引擎模拟,一般采用手动的方式控制其运动,如当一个机器人接近大门时,大门可以自动开启,而无须机器人对大门施加作用力。该类物体运动时也会影响与其相关的动态体,如电梯会使电梯内的动态体升高或者降低,门开关时会推动门后的动态体。

   3. dynamic(动态体)动态体的运动受到物理引擎的控制,如给子弹施加一个力,子弹的运动就会受到物理引擎的驱动,呈现与真实世界一致的运动轨迹。动态体可以与静态体、动力学体、动态体发生碰撞反应,并遵循物理规律。

     PhysicsBodyComponent 组件的 massProperties 属性力 PhysicsMassProperties 类型,该属性定义了物体的质量属性。PhysicsMassProperties 结构体的主要属性如表9-4所示。

表 9-4 PhysicsMassProperties 结构体

属性名称

类型

描述

init( )

方法

初始化方法,共有4个重载,用于以指定质量、惯性、质心、包围盒进行初始化

mass

属性

物体质量,单位为千克(kg)

inertia

属性

转动贯量,单位为千克平方米(kg•m”)

centerOfMass

属性

质心的位置和主轴的方向

       该结构体用于描述物体的质量属性,其中 inertia 称转动惯量,转动惯量用于描述改变物体转动状态的难易程度,转动惯量与物体质量的分布情况和转动轴位置有非常大的关系,同一物体如果质量分布情况不一样或者转动轴位置与方向不一样时转动惯量差异可能会非常大。就像质量对物体非旋转运动状态改变的阻碍一样,转动惯量对物体旋转运动状态改变也产生同样的阻碍,即转动惯量在旋转动力学中的角色相当于线性动力学中的质量,因此转动惯量可以形象地理解为一个物体对旋转运动的惯性,用于建立角动量、角速度、力矩和角加速度等数个物理量之间的关系。centerOfMass 用于描述质心的位置与主轴方向,这个参数影响物体的转动。

       PhysicsBodyComponent 组件的 material 属性 PhysicsMaterialResource 类型,该属性定义了物体的物理材质属性。PhysicsMaterialResource 类包含两个方法和一个 default 属性,如表9-5所示。

表9-5 PhysicsMaterialResource 类

名称

类型

描述

default

属性

使用默认的物理材质

generate(friction: Float, restitution: Float) -> PhysicsMaterialResource

方法

以指定的摩擦系数与恢复系数生成物理材质

generate staticFriction: Float, dynamicFriction: Float, restitution: Float) ->

PhysicsMaterialResource

方法

以指定的静摩擦系数、动摩擦系数、恢复系数生成物理材质

      PhysicsMaterialResource 类用于描述物体的物理材质属性,其中 friction 为摩擦系数(staticFriction 为静摩擦系数,dynamicFriction 为动摩擦数),取值范围为[0,∞),默认为 0.8;restitution 为恢复系数,取值范围为[0,1],默认为0.8,该属性描述的是物体反弹的程度,如一个球从1m 高的位置自由下落,恢复系数描述的是这个球能反弹的高度,默认将反弹到0.8m 的高度。

PhysicsMotionComponent 组件

     PhysicsBodyComponent 组件完全按照物理学规律处理物体的运动,通过设置真实的物理参数、施加作用力进行物理模拟,由于是完全依照真实物理世界规律处理物体运动,因此不能直接设置物体的位置与速度参数。

     PhysicsMotionComponent 组件则不完全拘泥于真实物理规律,可以通过设置物体的速度、角速度驱动物体运动,虽然可以直接设置非真实物理参数,但在设置完参数后,物体的行为仍然受物理引擎模拟,受物体 PhysicsBodyMode 属性影响。

     当物体为静态体时,对该物体设置速度、角速度无效,物理引擎会忽略所有属性设置值,静态体也不参与物理模拟。当物体为动力学体时,物理引擎会读取开发人员设置的速度值,并相应地处理物体的运动。当物体为动态体时,物理引擎会实时地更新物体的运动状态,但直接设置速度值不会产生运动效果,直到 resetPhysicsTransform(_:recursive:)方法被调用。换言之,动态体不能通过直接设置速度的方法产生运动效果。                    

      PhysicsMotionComponent 组件由于可以直接设置更容易理解和产生效果的速度、角速度等非基本物理参数,在某些情况下更容易达到预定效果,更方便使用。PhysicsMotionComponent 组件主要包括两个属性:linearVelocity 和 angularVelocity。 linearVelocity即促使物体直线运动的速度,而angularVelocity 是促使物体转动的角速度。

     需要注意的是,在使用 PhysicsMotionComponent组件进行物理模拟时,所有模拟相对于 physiesOrigin进行(速度其实是个相对量,描述两个物体之间距离的变化程度,因此需要一个参考体),獸认 physicsOrigin为场景的原点,即世界坐标系原点,在实际使用时可以将 physicsOrigin 设置到特定的实体上。

CollisionComponent 组件

     CollisionComponent 组件不属于 RealityKit 中的物理组件,但物理引擎会忽略没有挂载该组件的物体,CollisionComponent 组件直译为碰撞组件,顾名思义,碰撞组件负责处理碰撞相关事项,不带碰撞组件的实体不能参与碰撞,也不能参与物理模拟。碰撞组件实现两个关键功能,一个是定义碰撞体形状(Shape),主要目的是提高碰撞检测性能,另一个是检测并处理碰撞。CollisionComponent 组件包含3 个属性和1个初始化方法,如表9-6所示。

表9-6 CollisionComponent 组件

名称

类型

描述

init(shapes: [ShapeResource], mode: CollisionComponent.

方法

初始化方法,设置实体碰撞属性

Mode, filter: CollisionFilter)

mode

属性

CollisionComponent. Mode 类型,用于设置碰撞器的类型,分为普通碰撞器(default)和触发器(trigger)两种

filter

属性

CollisionFilter类型,用于设置碰撞检测过滤类型

shapes

属性

shapeResource数组类型,用于设置碰撞器外形

    CollisionComponent. Mode 是一个枚举,该枚举有两个枚举值(default、trigger),用于设定碰撞器为普通碰撞类型还是触发器类型。CollisionFilter 是一个用于设置碰撞检测过滤属性的结构体,该结构体主要包括4个属性,如表9-7所示。

表 9-7 CollisionFilter 结构体

名称

类型

描述

default

类属性

默认常规碰撞器

sensor

类属性

传感器,设置该值实体会与所有对象发生碰撞,通常用于射线检测(Raycast)和触发器

group

实例属性

CollisionGroup 类型,用于设置碰撞器所属的分组

mask

实例属性

CollisionGroup 类型,用于设置碰撞器所使用的掩码

      通过设置 CollisionFilter 值,将碰撞器设置成不同分组和使用不同掩码,可以对碰撞物体进行分层处理,实现复杂大场景、多物体间的不同碰撞效果,并能提升性能。如在AR 游戏中,在主角通过发射火球攻击柽物场景,可以通过设置火球与圣物的分组或者掩码将其分割在相同的层中,在进行碰撞检测时火球就只会与怪物发生碰撞反应,而不会与队友发生碰撞。这样做,一方面在进行碰撞检测时可以只检测特定的分组,提高碰撞检测效率;另一方面,通过分组分层可以简化处理逻辑。

       通过 CollisionFilter 的group 值和 mask 值设置,可以实现非常灵活、复杂的碰撞检测功能,并能有效地提升碰撞检测效率。ShapeResource 是一个用于定义碰撞器形状的类,碰撞器形状定义了物体发生碰撞时的外观。为提高检测效率,碰撞并不是以模型的几何网格为边界进行检查,而是依据碰撞器形状进行检测,模型几何网格可能会非常复杂,通过定义简单的能满足需要的碰撞器形状,可以大幅提高碰撞检测效率。在 RealityKit 中,ShapeResource 类可以生成如表9-8所示形状。

表9-8 ShapeResource 类可生成的形状

方法

描述

offsetBy()

3个重载,平移或者旋转物体的碰撞器形状,使其更符合物体的几何外观

generateBox)

2个重载,根据指定的尺寸生成立方体或长方体形状

generateSphere ()

根据指定的半径生成球体形状

generateCapsule()

根据指定的高与半径生成胶囊体形状

generateConvex()

根据指定的点或者网格生成形状

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

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

相关文章

学习JAVA的第二十一天(基础)

多线程 线程&#xff1a; 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 进程&#xff1a; 程序的基本执行实体 并发&#xff1a; 在同一时刻&#xff0c;有多个指令在单个CPU上交替执行 并行&#xff1a; 在同一时刻&…

HTML本地离线缓存?

在 HTML5 中&#xff0c;提供了一种本地离线存储的机制&#xff0c;即应用程序缓存&#xff08;Application Cache&#xff09;。通过应用程序缓存&#xff0c;可以使 Web 应用程序在离线状态下继续访问&#xff0c;并提高应用程序的加载速度和性能。以下是应用程序缓存的基本工…

【C语言】Windows下的C语言线程编程详解

文章目录 1. 头文件1.1 windows.h1.2 process.h 2. 创建线程3. 线程同步3.1 线程同步方式3.1 互斥量&#xff08;Mutex&#xff09;3.2 事件&#xff08;Event&#xff09; 4. 线程的结束与资源管理5.线程池&#xff08;简要&#xff09; 在Windows平台下&#xff0c;C语言提供…

活动会议线上直播,如何扩大曝光?媒体直播分流解析

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 线上直播扩大曝光与媒体直播分流解析 一、扩大曝光策略&#xff1a; 平台选择&#xff1a;选择用户基数大、活跃度高的直播平台进行直播。 预告宣传&#xff1a;提前发布直播预告&…

k8s-Istio服务网络 27

官网&#xff1a;https://istio.io/latest/zh/about/service-mesh/ Istio与k8s的区别 SpringCloud传统微服务结合k8s与Istio与k8s结合&#xff1a; Istio数据面&#xff1a;通过envoy以sidecar方式拦截svc的流量来进行治理。 Istio控制面&#xff1a;pilot list/watch APIserv…

Flask学习(二):flask模板渲染

Flask没有自己模板引擎&#xff0c;使用的是 jinja2 模板引擎&#xff0c;可以帮助我们将数据渲染到各种格式的文档中&#xff0c;如 HTML、XML、Markdown 等。 中文文档地址&#xff1a;Jinja2中文文档_w3cschool 程序示例&#xff1a; from flask import Flask, render_te…

HarmonyOS NEXT应用开发之异常处理案例

介绍 本示例介绍了通过应用事件打点hiAppEvent获取上一次应用异常信息的方法&#xff0c;主要分为应用崩溃、应用卡死以及系统查杀三种。 效果图预览 使用说明&#xff1a; 点击构建应用崩溃事件&#xff0c;3s之后应用退出&#xff0c;然后打开应用进入应用异常页面&#x…

nginx启动闪退

在nginx目录下cmd&#xff0c;nginx -t&#xff0c;找到原因是&#xff1a;“在端口80上运行NGINX时&#xff0c;因为端口80是HTTP默认端口&#xff0c;需要管理员权限才能访问” 所以修改端口号&#xff1a; 在nginx.conf文件中&#xff0c;修改listen&#xff1a;80为8080 …

【C++】类的默认成员函数(下)

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、运算符重载1.1 引例1.2 概念及运用&#xff1a;1.3 牛刀小试:1.4 重载1.5 运…

QT TCP通信介绍

QT是一个跨平台的C应用程序开发框架&#xff0c;它提供了一套完整的工具和库&#xff0c;用于开发各种类型的应用程序&#xff0c;包括图形用户界面(GUI)应用程序、命令行工具、网络应用程序等。QT提供了丰富的功能和类来简化网络通信的开发&#xff0c;其中包括TCP通信。 TCP…

C++面试100问!(二)

怎么定义常量的&#xff1f;常量存放在内存的哪个位置&#xff1f; 常量在C里的定义就是一个const加上对象类型&#xff0c;常量定义必须初始化。对于局部对象&#xff0c;常量存放在栈区&#xff0c;对于全局对象&#xff0c;常量存放在全局/静态存储区。对于字面值常量&#…

Linux-轻量级数据库sqlite函数接口-016

1 1.1【sqlite3_open】 1.1.1函数原型 【int sqlite3_open(const char *filename, /* Database filename (UTF-8) */sqlite3 **ppDb /* OUT: SQLite db handle */);】1.1.2函数功能 打开数据库文件(创建一个数据库连接)1.1.3函数参数 【filename】&#xff1a;…

Element Plus与Ant Design Vue:选型对比

在Vue.js的开发过程中&#xff0c;选择合适的UI框架对于项目的成功至关重要。Element Plus和Ant Design Vue作为两个热门的Vue UI框架&#xff0c;各自拥有独特的特点和优势。本文将从多个维度对这两个框架进行对比&#xff0c;帮助开发者在选择时做出明智的决策。 一、框架版…

Python网络基础爬虫-python基本语法

文章目录 逻辑语句if,else,elifforwhile异常处理 函数与类defpassclass 逻辑语句 熟悉C/C语言的人们可能很希望Python提供switch语句&#xff0c;但Python中并没有这个关键词&#xff0c;也没有这个语句结构。但是可以通过if-elif-elif-…这样的结构代替&#xff0c;或者使用字…

目标检测——YOLOv2算法解读

论文&#xff1a;YOLO9000: Better, Faster, Stronger 作者&#xff1a;Joseph Redmon, Ali Farhadi 链接&#xff1a;https://arxiv.org/pdf/1612.08242v1.pdf 代码&#xff1a;http://pjreddie.com/yolo9000/ YOLO系列其他文章&#xff1a; YOLOv1通俗易懂版解读SSD算法解读…

STM32/GD32——CAN协议

说明&#xff1a;本文不断更新中&#xff0c;内容均为作者手打... 芯片选型 Ciga Device — GD32F470系列 CAN协议规则 CAN帧种类介绍 CAN总线以“帧”的方式进行通讯。CAN协议定义了5种类型的帧&#xff1a;数据帧、遥控帧、错误帧、过载帧、间隔帧。其中“数据帧”最为常…

记一次生产慢sql索引优化及思考

记一次生产慢sql索引优化及思考 问题重现 夜黑风高的某一晚&#xff0c;突然收到一条运营后台数据库慢sql的报警&#xff0c;耗时竟然达到了60s。看了一下&#xff0c;还好不是很频繁&#xff0c;内心会更加从容排查问题&#xff0c;应该是特定条件下没有走到索引导致&#x…

如何在数据库中存储小数:FLOAT、DECIMAL还是BIGINT?

前言 这里还是用前面的例子: 在线机票订票系统的数据表设计。此时已经完成了大部分字段的设计&#xff0c;可能如下: CREATE TABLE flights ( flight_id INT AUTO_INCREMENT PRIMARY KEY, flight_number VARCHAR(10), departure_airport_code VARCHAR(3), arrival_ai…

[论文精读]Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection

论文网址&#xff1a;[2304.08876] 用于定向微小目标检测的动态粗到细学习 (arxiv.org) 论文代码&#xff1a;https://github.com/ChaselTsui/mmrotate-dcfl 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&…

支付模块-基于消息队列发送支付通知消息

消息队列发送支付通知消息 需求分析 订单服务作为通用服务&#xff0c;在订单支付成功后需要将支付结果异步通知给其他对接的微服务&#xff0c;微服务收到支付结果根据订单的类型去更新自己的业务数据 技术方案 使用消息队列进行异步通知需要保证消息的可靠性即生产端将消息…