SceneKit中的物理效果模拟 | 基础API详解

物理场景

物理模拟(Physics Simulation)主要用来实现:

  • 将动态行为添加到场景中的对象
  • 检测碰撞并响应物体之间的接触
  • 模拟真实的物理效应,如重力,弹力和 汽车模拟

1. 物理体(Physics Bodies)

1.1 SCNPhysicsBody 类

添加到节点上的物理模拟属性。

当SceneKit准备渲染新的一帧时,它会对连接到场景中节点的物理实体执行物理计算。 这些计算包括重力,摩擦以及与其他物体的碰撞。 你也可以将自己的力量和冲动应用于身体。 SceneKit完成这些计算后,它会在渲染帧之前更新节点对象的位置和方向。

要将物理模拟添加到节点,请创建并配置一个 SCNPhysicsBody 对象,然后将其赋给 SCNNode对象 的 physicsBody 属性。 在对其施加力或冲击之前,物理体必须与节点对象相关联。

planeNode.physicsBody = SCNPhysicsBody(type:.kinematic, shape: nil)

1.1.1 一个对象的物理特征

SCNPhysicsBody 类在场景模拟时定义身体的物理特征。 有三个重要的属性:

  • type 属性,用于确定对象在模拟中如何与力和其他物体进行交互:① 静态物体(static)不受力量和碰撞的影响,不能移动;② 动态物体(dynamic)受到力量和与其他身体类型碰撞的影响;③ 运动物体(kinematic)不受力或碰撞的影响,但通过直接移动它们,可能会导致影响动态物体的碰撞。

  • physicsShape 属性,它定义用于碰撞检测目的的三维形体。 使用简单形状代替节点的可见几何体的精细细节时,物理模拟运行速度更快。 通常,您将一个物体的物理形状设置为与其节点的可见内容大致相匹配的边界框,球体或原始形状。 有关创建物理形状的详细信息,请参阅 SCNPhysicsShape。

  • kinematic() 属性, 对动力体(dynamic body)施加力或力矩会导致与其质量成比例的加速度(或角加速度)。

1.1.2 定义一个物体的类别和碰撞(Category and Collisions)

当你设计使用物理效果的游戏时,你可以按需在场景中定义不同类别的物理体。一个物理体可以分配到多个类别中。 除了声明对象自己的类别之外,它还会声明它可以与哪些类别的物理体进行交互。

使用 categoryBitMaskcollisionBitMask 属性来定义对象的碰撞行为。 SCNPhysicsCollisionCategory中列出的常量为这些属性提供默认值。 另外,通过 contactTestBitMask 属性,实现 SCNPhysicsContactDelegate 的协议方法,可以获取到发生碰撞的对象 。

关于碰撞和类别,另外有一篇博客专门讲解。

1.1.3 与之相关的类

”物理场”会产生影响某个区域所有物体的力量,例如涡旋和引力吸引力。 有关可用字段类型的详细信息和列表,后面 SCNPhysicsField类 会详细讲解。

你可以添加更高级别的行为来控制多个物体之间的交互,例如关节和轮式车辆。 有关可用行为的详细信息和列表,后面 SCNPhysicsBehavior会详细讲解。

场景的physicsWorld属性包含一个 SCNPhysicsWorld 对象,用于管理影响整个场景的物理特性。

1.1.4 物理模拟和渲染循环

SceneKit 将物理模拟作为渲染循环的一部分,遵守 SCNSceneRendererDelegate 协议,在每次渲染循环的时候,SceneKit 确定每个添加在每个节点上的物理模拟,并且同步计算出物理模拟对物体的影响。

例如,基于速度更新物体的位置,SceneKit将物理模拟的结果应用到场景中进行显示。

不仅可以通过物理模拟为 SceneKit 内容创建动画,还可以通过动作(action)来隐式或显式定义的动画。

注意, SceneKit并不是将物理模拟的结果应用于场景中的 SCNNode 对象,而是应用于表示其当前显示状态的每个节点的表示对象。因此,改变受物理影响的节点的属性需要特别考虑。

如果更改变 transform 属性或者transform 属性中的某个值(如物理位置或旋转),则 SceneKit 将重置该节点的物理模拟。

如果只想更改变换 transform 中的某个值,请在进行更改之前复制该演示节点的transform ,如下所示:

// Copy the presentation node's transform to the model node.
node.transform = node.presentationNode.transform
// Change one component of the new transform
node.eulerAngles.z = newRollValue

SCNPhysicsShape 类

对物理体的外观的抽象,用于调整碰撞检测。

当SceneKit为场景中的 SCNPhysicsBody对象 执行接触检测和其他模拟时,它将使用 SCNPhysicsShape 描述的物理形状,而不是可见对象的渲染几何体。 这种方法既提高了仿真性能,又可让你更轻松地设计玩家可与之互动的场景元素周围的游戏玩法。

2. 碰撞和接触检测

SCNPhysicsContactDelegate 协议

当场景中两个物理实体之间发生接触或碰撞(Contact)时,可以使用这些方法进行响应。

要接收 Contact 消息,请设置 SCNPhysicsWorld 对象的 contactDelegate 属性。 当 Contact 开始,Contact 信息发生变化以及 Contact结束时,SceneKit 会调用委托方法。

SCNPhysicsContact 类

两个物理体之间接触的详细信息。

开发者不直接创建 SCNPhysicsContact 实例; 无论何时发生contact ,SceneKit都会自动创建这些对象。

要接收 contact 消息,设置 SCNPhysicsWorld 对象的 contactDelegate 属性后,实现 SCNPhysicsContactDelegate 协议方法。 接下来,对于场景中的每个物理实体,设置 categoryBitMaskcollisionBitMask属性以定义哪些交互应生成contact 消息。

这一块刚开始不好理解,三言两语难讲清楚,详细请参考 SceneKit中的物理模拟 | Bit-masks

3. 物理场景( Physics in a Scene )

SCNPhysicsWorld

全局模拟场景中的碰撞,重力,关节和其他物理效应。
不要直接创建SCNPhysicsWorld对象; 相反,参考请 SCNScene对象的physicsWorld 属性。 使用物理世界对象来执行以下任务:

  • 管理物理模拟的全局属性,例如其速度和恒定的引力(为了更精确地控制重力和类似的效果,请参阅 SCNPhysicsField 类)
  • 注册修改场景中物理实体(如关节和车辆)之间交互的行为。 有关更多详细信息,请参阅 SCNPhysicsBehavior
  • 当两个物理体彼此接触时,指定一个委托对象来接收消息

SCNPhysicsField 类

SCNPhysicsField 对象可以将引力、电磁和气流等外力应用于物理体的特定区域上。

您可以创建许多类型的场效应,例如引力,电磁和气流。 要将场效应添加到场景中,请创建要使用的类型的物理场,然后将其附加到场景中节点的physicsField 属性。

物理场可以影响 SCNPhysicsBody对象 和 SCNParticleSystem对象产生的粒子。


电磁场.gif

SCNPyhsicsBehavior 类

包含多个物理体的的关节、车辆模拟和其他高级行为的抽象父类。

SCNPhysicsBehavior对象定义一个或多个物理体的高级行为,修改物理模拟的结果。 这些高级行为包括连接多个物体的关节,以便它们一起移动;车辆定义,使物体像汽车一样滚动。 你从不直接使用这个类; 相反,你实例化了一个定义你想添加到物理世界中的行为类型的子类。

4. 关节(Joints)

SCNPhysicsHingeJoint 类

连接两个物体并允许它们在一个轴上相互转动的物理行为。

铰链(Hinge)具有单一的自由度(旋转)。 你还可以使用铰链连接来固定物体,以便它只能通过围绕包含它的节点的坐标空间中的特定轴旋转来移动。

Hinge.gif

SCNPhysicsSliderJoint 类

连接两个物体并允许它们相互滑动并围绕其连接点旋转的物理行为。

根据滑块(Slider)关节是否允许滑动或旋转,滑块关节可以具有零个,一个或两个自由度。 您还可以使用滑块接头固定一个物体,以便只能通过在包含该物体的节点的坐标空间中滑动特定的轴来移动物体。 您也可以使用滑块接头作为电机,对连接的物体施加力或扭矩。

Slider Joint 运动.gif

SCNPhysicsBallSocketJoint 类

连接两个物理体并允许它们在任何方向上相互转动的物理行为。

Ball Socket Joint

动图来自 Physics Joints in Unity 2D 一文中。

5. 汽车模拟(Vehicle Simulation)

Physics Vehicle.png

SCNPhysicsVehicle类

一种物理行为,修改一个物理体的行为,像汽车,摩托车或其他轮式车辆。

要搭建一辆车,请将 SCNPhysicsBody对象 指定为底盘,并将SCNPhysicsVehicleWheel对象作为其车轮。 对于每个车轮,您可以定义悬架和牵引力等物理特征,并将场景中的节点关联起来以提供车轮的大小和视觉表示。 在构建车辆后,可以通过加速,制动和转向来控制它。

尽管也可以使用一组物理体和关节来共同模拟轮式车辆,但 SCNPhysicsVehicle类实现了更高级别的仿真,可以提供逼真的车辆行为和更高效的仿真性能。

SCNPhysicsVehicleWheel 类

上面已经提到了,SCNPhysicsVehicleWheel是与物理车辆行为相关的单个车轮的外观和物理特征。

Physics Vehicle.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容