我们已经准备好了,你呢?

2023我们与您携手共赢,为您的企业形象保驾护航!


喜讯:国内、香港、海外云服务器租用特惠活动,2核/4G/10M仅需31元每月,点击抢购>>>

点击这里点击这里申请百度智能云特邀VIP帐号,立即体验AR开放平台>>>

百度智能云AR开放平台AR场景开发指南-物理引擎

物理引擎

一、简介

百度AR引擎已经支持了物理引擎,开发者可以通过简单的配置,向三维模型添加物理属性,让三维模型在场景实现中碰撞与被碰撞、受重力下落以及约束等效果。本篇教程主要内容是物理相关接口教程。如果你对百度AR如何搭建一个场景还不熟悉,请先查看其他教程。

基础:如果你已经搭建好了一个场景,比如有两个三维模型能够显示出来。这时你会发现,这两个三维模型一动不动,(除非你使用了刚体动画的接口或者手势移动三维物体)。如果你希望这两个物体能够像真实物体一样,在场景中受重力影响下落或者在平面上随意滚动,你可以看看下面的内容。

1.1 物理世界坐标系

首先先介绍物理引擎使用的坐标系。物理世界坐标系使用右手坐标系,如图所示。

二.场景的物理世界的创建

2.1 简介

scene是一个场景,它会包含众多的物体在其中。scene中的物理世界创建,会创建一个影响整个场景的物理环境。

注意:

1、创建的场景会影响场景里的所有带有物理效果的实体。

2、如果没有创建物理世界,场景中的物体是不会有物理效果的。

2.2 创建一个物理世界

如果你想要创建一个拥有物理效果的场景,首先一定要调用ARScene类的这个接口:

create_physics_world(ARVec3& gravity)

void create_physics_world(ARVec3& gravity)

为该场景创建一个物理世界

Parameters

  • gravity | ARVec3: 重力,用一个三维向量表示

Returns

  • void

sample:

scene = app:get_current_scene()

local gravity = ae.ARVec3:new_local(0,-3000,0)
scene:create_physics_world(gravity)

创建物理世界必须要传入重力gravity,重力是使用一个ARVec3来表示的。分别代表x,y,z方向。结合右手坐标系可以看出,如果设置重力为(0, -3000, 0),那么表示重力向下,也就是说,如果你把一个物体放在了空中,那它将会垂直下落!

注意:现实中的重力系数为9.8,如果你设置了9.8或者更小,发现物体并没有像期望一样快速下落,请把重力值调大。

2.3 获取物理世界的实例

当你创建完一个物理世界以后,你可以通过获取物理世界的实例来修改这个世界的部分属性。

获取物理世界实例的接口如下:

get_physics_world()

ARPhysicsWorld& get_physics_world()

获取该场景的物理世界实例

Parameters

Returns

  • ARPhysicsWorld& | 返回一个物理世界的实例

sample:

scene = app:get_current_scene() 

local gravity = ae.ARVec3:new_local(0,-3000,0) 
scene:create_physics_world(gravity) 
physics_world = scene:get_physics_world()

这样就可以获取到场景的物理实例了。

注意:如果你在没有使用创建物理世界的接口就调用了这个接口,那么程序会出错,请小心!

2.4 总结

现在,通过调用创建物理世界函数的接口,你已经成功在场景中生成一个物理世界了,但是你会发现你的三维物体还是没有下落或碰撞。接下来,请继续看下面的内容。再一次强调,一定要调用创建物理世界的接口。

物理世界还有一些能力,诸如创建约束与DebugDraw功能。在后面会提到。你也可以去到DebugDraw功能,先看看如何开启物体碰撞体的显示。

三.为单个物体创建物理碰撞体

3.1 简介

当你创建完物理世界后,接下来你需要做的就是为每一个三维物体创建物理碰撞体,这样这个三维物体才能具有物理属性!

先陈述两个不同的概念:三维物体与碰撞体。

三维模型是我们在渲染引擎中显示的物体,它可能会很复杂,有色彩有动画,这是我们实际可以看见的物体。

碰撞体是通过三维物体来创建的一个虚拟的物体,它可能只是包围在三维物理周围的一个长方体或者一个球体等等。这取决于你如何创建一个碰撞体。有些时候我们不需要如此精确的碰撞,那么我们只需要一个长方体来进行碰撞就可以了。

所以,物体模拟实际模拟的是碰撞体的运动,然后我们会把碰撞体的旋转与移动赋予三维物体,这样可见的三维物体就像是在进行物理模拟一样。

注意:

1、如果你不为三维模型创建物理碰撞体,那么它不具有物理属性。

2、物理世界的重力属性,会对你所有的物理碰撞体都生效。

注意:我们推荐只对三维物体创建物理碰撞体,也就是说,这个节点是一个pod节点或者gltf节点。

3.2 创建一个物理碰撞体

如果你想要让一个三维模型拥有物理效果,首先一定要调用下面这个接口:

create_physics_body(float mass, float restitution, float friction, string body_type, string shape_type, float shape_scale = 1.0)

void create_physics_body(float mass, float restitution, float friction, std::string body_type, std::string shape_type, float shape_scale = 1.0)

为该节点创建一个物理碰撞体

Parameters

  • mass | float: 物体的质量

  • restitution | float: 弹性系数

  • friction | float :摩擦系数

  • body_type | string :碰撞体类型,包括:dynamic、kinematic、static

  • shape_type | string:碰撞体形状,包括:box、sphere、capsule、cylinder、cone、mesh

  • shape_scale | float: 形状放缩系数

Returns

  • void

sample:
node:create_physics_body(0.0, 0.5, 0.3,"kinematic", "box");

这些参数包括:质量(mass)、 弹性系数(restitution)、摩擦系数(friction)、 碰撞体类型(body_type)、碰撞体形状(shape_type)、碰撞体形状缩放系数(shape_scale)

接下来的每一个小节中会重点讲述每一个属性的意义以及需要注意的地方。

3.2.1 质量

物体的质量很好理解,对于物理效果来说,如果两个轻重不同的物体相撞,那么轻的那个更容易被撞飞。

小tips:

1、如果你想让一个物体不那么容易被其他物体撞飞,那你可以给它一个大的质量;反之亦然。

2、不要给一个物体质量赋予一个负值,比如-1。如果是负值,那它的质量会是一个默认值。

3.2.2 弹性系数

弹性系数也很好理解,如果一个物体的弹性系数越大,那它碰撞后反弹获取的能量越大。比如,其他属性一定时,弹性系数大的小球与弹性系数小的小球,碰到地上,弹性系数大的小球会弹得高。

小tips:

弹性系数的反弹效果由两个碰撞物体的弹性系数决定。如果两个弹性系数的乘积大于1,则反弹效果越强;如果等于1则反弹效果不变,如果小于1则反弹效果越来越弱。

3.2.3 摩擦系数

摩擦系数越大,物体受到的阻力也越大,意味着它越容易停下来。推荐设置在0-1之间。

3.2.4 碰撞体类型

碰撞体类型有三种,分别是static、kinematic与dynamic。下面的表格具体说明了三种碰撞体的不同。

类型意义备注
static一个静态的物体,当被创建之后,它在任何情况下都不能被移动质量一定为0
kinematic一个可运动的物体,当被创建之后,它的位置不会被重力影响,
也不会被碰撞影响,但是可以位置与旋转可以根据三维物体的位置改变
质量一定为0
dynamic一个完全可以运动的物体,当被创建之后,它的位置会被重力影响,
也会被碰撞影响,它的位置与旋转只能通过施加力与力矩、冲量、线速度和角速度来影响

DEMO:

node:create_physics_body(0.0, 0.5, 0.5,"static", "box")   -- static碰撞体创建
node:create_physics_body(0.0, 0.5, 0.5,"kinematic", "box") -- kinematic碰撞体创建
node:create_physics_body(20, 0.5, 0.5,"dynamic", "box")    -- dynamic碰撞体创建

Tips:

如果对这三种类型的具体含义还不是特别清楚,请看下面的例子:

1.如果你需要一个可以碰撞的地面,而且你能够确保在任何时候都不会去变更它的位置或者旋转,那你可以采用static来创建。注意:如果你通过set_world_position改变了三维物体的位置,但是static碰撞体还是会在原处!

2.如果你需要创建一个可以移动的墙,那么你可以使用kinematic来创建。当创建完毕后,它也是不动的,不会下落也不会被其他物理撞飞(但是它可以撞飞一个dynamic的物体)。如果你需要移动它的位置,你可以调用node节点的set_world_position方法。换句话中,物理世界的重力与碰撞对它不会产生任何影响,但是它的位置永远和三维物体保持一致。

3.如果你想要一个可以碰撞的小球,那么你可以使用dynamic来创建,当创建完毕后,这个物体就会受物理规律的影响,如下落或者被碰撞离开。需要注意的是,这个三维物体的位置与旋转完全被碰撞体控制,如果你通过set_world_position接口是无法改变它的位置的。如果你想改变它的位置,你需要对它的碰撞体施加力或者速度!

3.2.5 碰撞体形状

如之前所说,三维物体会被抽象为一个碰撞体进行碰撞。所以碰撞体的形状有简单有复杂,这取决你需要多么精确地碰撞。

我们提供了6种碰撞体形状,分别是box、sphere、capsule(包括x,y,z三个不同的轴)、cylinder(包括x,y,z三个不同的轴)、cone(包括x,y,z三个不同的轴)、mesh。

注意:在生成碰撞体形状的时候,如果你对形状的旋转有些不解,那你可以先把场景json配置文件中节点的rotation改为"0,0,0",这样你就会得到一个处在标准右手坐标系下的碰撞体。如果你确定你需要的碰撞体就是这样,你再去修改rotation字段。碰撞体也同样会旋转。

接下来会通过图片的形式展示每一个碰撞体的样子。

3.2.5.1 box(长方体)

推荐:TOP云智能建站优惠活动,仅880元即可搭建一个后台管理五端合一的智能网站(PC网站、手机网站、百度智能小程序、微信小程序、支付宝小程序),独享百度搜索SEO优势资源,让你的网站不仅有颜值有排面,更有排名,可以实实在在为您带来效益,请点击进入TOP云智能建站>>>,或咨询在线客服了解详情。



我们已经准备好了,你呢?

2023我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

131-3501-0006

上班时间

周一到周五

公司电话

130-0743-9476

二维码
线