物理系统
此类拼图用来模拟对象的物理系统行为。
![](files/puzzles/puzzles-physics.jpg)
内容
- 物理拼图参考
- create physics world(创建物理世界)
- create rigid body(创建刚体)
- create soft body(创建柔体)
- Remove physics body(删除物理实体)
- apply body param(应用实体参数)
- get body param(获取实体参数)
- set body state(设置实体的状态)
- on simulation tick(在模拟启动时)
- snap body(对齐实体)
- add constraint to(添加约束到)
- remove constraint from(从...移除约束)
- anchor soft body(锚定柔体)
- detect collisions and collision info(检测碰撞与碰撞信息)
- Extending with JavaScript(用JavaScript进行扩展)
物理拼图参考
create physics world(创建物理世界)
使用指定的gravity(重力)和frames-per-second(帧/秒)参数初始化物理引擎。默认的gravity(重力)值为9.8,对应于地球表面重力。零代表没有重力,类似在太空。fps值越高,模拟质量越好,但要牺牲性能。
soft body(柔体)复选框激活了柔体模拟功能。
![](files/puzzles/puzzles-physics-create-physics-world.jpg)
基于引擎,这个拼图还可以实现碰撞检测和自动图形同步。
create rigid body(创建刚体)
从一个指定的对象创建一个实体,类型为dynamic(动态)、kinematic(运动)、static(静态)或ghost(幽灵)。指定碰撞形状,并为该体设置质量(仅对dynamic(动态)体有效)。也适用于对象列表,组(或者组的列表)以及 all objects(所有对象) 拼图。
![](files/puzzles/puzzles-physics-create-physics-body.jpg)
实体的类型:
- dynamic - 动态--由物理引擎移动,受碰撞影响,与其他物体相撞。
- kinematic - 通过动画或用户动作移动。动态对象会被推开,但没有来自动态对象的影响。
- static - 不能移动,但会与其他对象发生碰撞。
- ghost - 类似于kinematic,但不产生任何碰撞反应。用它来 detect collision(检测碰撞) (例如,实现接近传感器)。
支持的刚体形状:
- box - 盒子形状的边界。
- sphere - 球体形状的边界。
- mesh - 网格形状。
- capsule - 沿上下轴拉伸的胶囊形状。
- cone - 沿上下轴拉伸的圆锥体形状。
- cylinder - 沿上下轴拉伸的圆柱体形状。
- empty - 空的形状。用于创建约束性附件和柔体锚点。
出于性能因素,优先考虑原始物理形状(盒子、球体、胶囊、圆锥体和圆柱体)而不是网格形状。另外,static网格的性能比dynamic, kinematic 和 ghost 的性能好得多。
create soft body(创建柔体)
从一个指定的对象中创建一个柔体,具有给定的总mass(质量)和可选的pressure(压力)参数。也适用于对象列表,组(或者组的列表)以及 all objects(所有对象) 拼图。
![](files/puzzles/puzzles-physics-create-soft-body.jpg)
支持的柔体形状:
- volume - 封闭受压的三维体积。
- rope - 类似绳子的线状对象。
- patch - 多边形表面,如布或纺织品补丁。
在创建柔体之前,不要忘记激活 physics world(物理世界) 上的柔体模拟。
Remove physics body(删除物理实体)
通过破坏与之相关的实体,从指定的对象中移除物理特性。也适用于对象列表,组(或者组的列表)以及 all objects(所有对象) 拼图。
![](files/puzzles/puzzles-physics-remove-physics-body.jpg)
apply body param(应用实体参数)
为与指定对象相关的实体设置参数。也适用于对象列表,组(或者组的列表)以及 all objects(所有对象) 拼图。
![](files/puzzles/puzzles-physics-apply-body-param.jpg)
参数:
- angular damping - 角度阻尼,用于减缓对象旋转的阻尼系数:0-没有阻尼,1-最大阻尼。输入值被钳制在[0, 1]范围内。
- angular factor - 角度系数,设置指定对象的旋转自由度。例如,通过设置Z分量为零,您可以禁止实体围绕上下(Blender,Max)或前后(Maya)轴旋转。
- angular velocity - 角速度,设置旋转速度矢量。
- ccd motion threshold - CCD运动阈值 ,用于模拟连续碰撞检测(CCD)物理学的运动阈值。指定低值,例如 0.001
- ccd swept sphere radius - CCD扫掠球半径 ,用于模拟连续碰撞检测(CCD)物理的扫掠球半径。这个值应该与碰撞对象的大小相对应。例如,为了模拟尺寸为0.01米的小子弹,这个值设置为0.5会比较安全。
![](files/puzzles/puzzles-physics-ccd-example.jpg)
- force - 作用力,在指定的方向上推动实体。
- friction - 摩擦力,实体相互滑动的相对运动的阻力系数。
- gravity - 重力,为一个指定的实体单独分配重力。
- impulse - 冲量,作用类似于线性速度,但也考虑到了实体的质量(较重的对象将获得较少的速度)。
![](files/puzzles/puzzles-physics-apply-body-param-impulse.jpg)
- linear damping - 线性阻尼,将使运动对象减速的阻力系数。0-没有阻尼(例如自由落体),1-最大阻尼(例如对象下落时没有加速度)。输入值被钳制在[0, 1]范围内。
- linear factor - 线性因子,为指定的对象设置位置自由度。例如,通过设置Z分量为零,您可以禁止实体的上下(Blender,Max)或前后(Maya)运动。
- linear velocity - 线性速度,设置运动速度矢量。
- position - 位置,设置实体的位置(作用类似于 snap body(对齐实体) 的拼图)。
- rotation - 旋转, 设置实体的旋转(欧拉旋转以XYZ为顺序,像 snap body(对齐实体) 拼图一样工作)。
- restitution - 恢复,弹性系数。0 - 实体像粘土一样没有弹性,1 - 实体的行为像由橡胶制成。
- stiffness - 刚度,柔体的刚度,如体积和绳索。
- torque - 扭矩,在一个指定的方向上旋转实体。
- torque impulse - 扭矩冲量,作用类似于角速度,但也考虑到了实体的质量(较重的对象将获得较少的旋转速度)。
当两个对象发生碰撞时,它们的摩擦力和恢复力参数会被考虑在内。
get body param(获取实体参数)
从与指定对象相关的实体中获取一个参数。
![](files/puzzles/puzzles-physics-get-body-param.jpg)
参数:
- angular damping - 角度阻尼,用于减缓对象旋转的阻尼系数:0-没有阻尼,1-最大阻尼。
- angular factor - 角度系数,选定对象的旋转自由度(XYZ)。
- angular velocity - 角速度,旋转速度矢量。
- ccd motion threshold - CCD运动阈值 ,用于模拟连续碰撞检测(CCD)物理学的运动阈值。
- ccd swept sphere radius - CCD扫掠球半径 ,用于模拟连续碰撞检测(CCD)物理的扫掠球半径。
- force - 作用力,施加到实体上的力矢量。
- friction - 摩擦力,实体相互滑动的相对运动的阻力系数。
- gravity - 重力,施加在对象上的重力矢量。
- linear damping - 线性阻尼,将使运动对象减速的阻力系数。0-没有阻尼(例如自由落体),1-最大阻尼(例如对象下落时没有加速度)。
- linear factor - 线性系数,指定体的位置自由度(XYZ)。
- linear velocity - 线性速度,运动速度矢量。
- position - 位置,实体的XYZ位置。
- rotation - **, 实体的XYZ欧拉旋转。
- restitution - 恢复,弹性系数。0 - 实体像粘土一样没有弹性,1 - 实体的行为像由橡胶制成。
- stiffness - 刚度,柔体的刚度,如体积和绳索。
- torque - 扭矩,应用于实体的扭矩矢量。
set body state(设置实体的状态)
改变与指定对象相关的实体的状态。也适用于对象列表,组(或者组的列表)以及 all objects(所有对象) 拼图。
![](files/puzzles/puzzles-physics-set-body-state.jpg)
参数:
- activate - 激活睡眠的实体。
- sleep - 强制实体进入睡眠状态。
- enable simulation - 启用实体模拟(默认启用)。
- disable simulation - 禁用实体模拟。
- reset - 清除所有应用于实体的力和速度。
- enable contact response - 允许实体之间发生碰撞(默认情况下启用)。
- disable contact response - 禁用接触响应,禁用实体的碰撞。
- make dynamic - 使实体动态化。
- make kinematic - 使实体运动。
- make static - 使实体静止。
- enable deactivation - 允许实体在不活动一段时间后转入睡眠状态(默认启用)。
- disable deactivation- 禁止实体睡眠。
on simulation tick(在模拟启动时)
在物理模拟启动的瞬间 之前 或 之后 ,触发在 "do" 槽中指定的拼图。
![](files/puzzles/puzzles-physics-on-simulation-tick.jpg)
物理模拟计时与创建 物理世界 时指定的FPS值相对应,与渲染帧不一致。因此,我们建议你在模拟启动之前应用力、速度和脉冲,在模拟启动之后检测实体之间的碰撞。这样您就可以实现更稳定和更真实的模拟。
snap body(对齐实体)
通过复制实体的变换数据,将与指定对象相关的实体以及对象本身移动到另一个对象的位置。同时复制旋转。对列表、组或 "all objects(所有对象)" 拼图不起作用。
![](files/puzzles/puzzles-physics-snap-body.jpg)
作用类似于apply body param / position(应用体参数/位置)拼图。
add constraint to(添加约束到)
通过一个给定类型的约束来连接两个实体。
![](files/puzzles/puzzles-physics-add-physics-constraint.jpg)
约束类型:
- hinge - *铰链 *,通过共用的轴连接两个实体,被连接的实体仅可以绕一个轴旋转。
- ball - *球* ,通过球状的插座来连接两个实体。
- slider - 滑块 约束限制实体移动方向在X轴向上。
- spring - 弹簧 ,通过类似弹簧的关节连接两个实体。
- fixed - 固定 ,紧密地连接两个实体。
![](files/puzzles/puzzles-physics-add-physics-constraint-example.jpg)
remove constraint from(从...移除约束)
移除物理约束。
![](files/puzzles/puzzles-physics-remove-physics-constraint.jpg)
anchor soft body(锚定柔体)
将柔体锚定在给定矢量所代表的空间点的给定刚体上。
![](files/puzzles/puzzles-physics-anchor-soft-body.jpg)
detect collisions and collision info(检测碰撞与碰撞信息)
检测指定的实体与另一个实体(或列表中的任一实体与组)在此刻是否有碰撞。如果有碰撞,那么在 "if touching do" 槽中的拼图会被触发,否则将触发在 "if not touching do" 插槽中的拼图。
"detect collisions" 拼图在每一个渲染帧中都会触发它的回调插槽。
![](files/puzzles/puzzles-physics-detect-collisions.jpg)
collision info 拼图会输出一个 字典 ,其字段如下:
- objectA - 第一个碰撞实体的名字。
- objectB - 第二个碰撞实体的名字。
- distance - 碰撞点之间的距离。
- positionOnA - 第一个对象上的碰撞点的XYZ坐标。
- positionOnB - 第二个对象上的碰撞点的XYZ坐标。
- normalOnB - 第二个对象上的碰撞点的法向量的XYZ分量。
![](files/puzzles/puzzles-physics-detect-collisions-info.jpg)
Extending with JavaScript(用JavaScript进行扩展)
在您开始阅读以下内容之前,请先熟悉本用户手册的 使用JavaScript 部分。
为了构建物理拼图,我们使用了名为Ammo.js的JavaScript库。这是流行的开源物理引擎Bullet的JavaScript版本,经过编译可以在浏览器中使用。
要熟悉Bullet,请查阅GitHub上的 Bullet Physics SDK Manual 以及官方的 Bullet API Reference。
在Verge3D中,您可以通过使用Ammo命名空间直接执行Bullet/Ammo.js APIs。
var myVector = new Ammo.btVector3(1.0, 0.0, 0.0);
console.log('My physics vector is:', myVector.x(), myVector.y(), myVector.z());
此外,您还可以通过 your_app_name.js 模块 的 runCode() 函数的 puzzles 参数或 exec script(执行脚本) 拼图中的内置 puzzles 变量, 来访问我们在拼图中使用的以下数据结构:
World
根据所初始化的物理世界,它可以是 btDiscreteDynamicsWorld 或 btSoftRigidDynamicsWorld 类的实例。
var gravity = puzzles.physics.world.getGravity();
console.log('World gravity:', gravity.y());
Physics Bodies
实体作为键值数据存储在 Puzzles.physics.bodies 对象中。
var body = puzzles.physics.bodies['Whirligig'];
console.log('Body mass:', 1.0 / body.getInvMass());
刚体是 btRigidBody 类的实例,而柔体是 btSoftBody 类的实例。
Physics Constraints
Bullet/Ammo 约束以键值数据的形式存储在二维的 Puzzles.physics.constraints 对象中。
var hingeConstraint = puzzles.physics.constraints['Suzanne']['Axis'];
hingeConstraint.enableAngularMotor(true, 10, 10);
这些名称分别代表约束的第一和第二实体。
Physics Sync List
Verge3D拼图使用所谓的同步列表在空间中移动由实体代表的对象。同步列表不能被直接访问,所以您需要使用下面的API方法来添加实体到该列表,或移除出列表。
// add obj / body to the sync list
// the type can be 'DYNAMIC', 'KINEMATIC', 'STATIC', 'GHOST', or 'SOFT_BODY'
puzzles.physics.addToSyncList(obj, body, 'DYNAMIC');
// remove obj / body from the sync list
puzzles.physics.removeFromSyncList(obj, body);
在使用拼图时遇到困难?
欢迎您随时在 论坛上提问!您还可以加入中文用户社区QQ群(171678760),在线寻求帮助。