@@ -32,18 +32,30 @@ import { Physics } from "@orillusion/physics"
3232 </script >
3333```
3434
35- ## 物理环境的运行
36-
35+ ## 基本用法
3736目前 [ Physics] ( /physics/classes/Physics ) 支持的参数及方法如下表所示:
3837
3938| API | 描述 |
4039| --- | --- |
4140| init(): void | 初始化物理引擎 |
41+ | initDebugDrawer(): void | 初始化物理调试器 |
4242| update(): void | 更新物理系统,需要在 loop 主体中调用 |
4343| gravity: Vector3 | 重力参数 |
4444| isStop: boolean | 控制物理世界是否暂停运行 |
45- | world: Ammo.btDiscreteDynamicsWorld | ammo.js 原生物理世界 |
45+ | debugDrawer: PhysicsDebugDrawer | 可视化调试工具 |
46+ | physicsDragger: PhysicsDragger | 拖拽交互工具 |
47+ | world: Ammo.btDiscreteDynamicsWorld | Ammo.js 原生物理世界 |
48+
49+ ` init() ` 初始化配置参数:
50+
51+ | 参数 | 类型 | 描述 |
52+ | --- | --- | --- |
53+ | useSoftBody | ` boolean ` | 是否启用软体模拟 |
54+ | useDrag | ` boolean ` | 是否启用拖拽交互功能 |
55+ | physicBound | ` Vector3 ` | 物理世界边界 |
56+ | destroyObjectBeyondBounds | ` boolean ` | 超出边界时销毁3D对象 |
4657
58+ ### 启动物理系统
4759我们可以初始化 ` init() ` 来开启物理系统,并通过在渲染主循环中调用 ` update() ` 实现物理世界的运行:
4860``` ts
4961import { Engine3D } from ' @orillusion/core'
@@ -54,21 +66,61 @@ await Engine3D.init({
5466 renderLoop : () => Physics .update ()
5567});
5668```
69+ ::: tip
5770通过以上方法开启并运行物理系统后,引擎会在每一帧渲染时,根据设定的参数计算并更新物体模型对物理世界的实际响应。
71+ :::
5872
59- 在一些项目中通常会有暂停物理世界模拟的需求,因此我们提供了一个参数可以暂停&恢复物理世界的运行:
73+ ### 暂停与恢复
6074``` ts
6175Physics .isStop = ! Physics .isStop ;
6276```
6377
64- ## 重力环境模拟
65- 引擎默认的重力参数为 ` Vector3(0, -9.8, 0) ` ,模拟的是地球的重力。如果需要自定义重力参数的话,只需更改 ` Physics.gravity ` 属性即可。
6678
67- 例如,如果需要模拟太空中的无重力环境,可以更改 ` gravity ` 参数为:
79+ ### 重力环境模拟
80+ 默认重力为 ` Vector3(0, -9.8, 0) ` (地球重力)。自定义重力只需修改 ` Physics.gravity ` :
81+ ``` ts
82+ Physics .gravity = new Vector3 (0 , 0 , 0 ); // 无重力环境
83+ ```
84+
85+ ## 辅助功能
86+ - ** 物理可视化** :为了可视化物理对象,我们可以在引擎启动后初始化物理可视化调试器,需要为其传入 ` Graphic3D ` 对象:
6887``` ts
69- Physics .gravity = new Vector3 (0 ,0 ,0 );
88+ const graphic3D = new Graphic3D ();
89+ scene .addChild (graphic3D );
90+ Physics .initDebugDrawer (graphic3D , { enable: true });
7091```
7192
93+ ::: details 使用 dat 控制调试器
94+ ``` ts
95+ import dat from " dat.gui" ;
96+
97+ let gui = new dat .GUI ();
98+ let f = gui .addFolder (" PhysicsDebugDrawer" );
99+ f .add (Physics .debugDrawer , ' enable' ).listen (); // 开启或关闭调试功能
100+ f .add (Physics .debugDrawer , ' debugMode' , Physics .debugDrawer .debugModeList ); // 调试模式
101+ f .add (Physics .debugDrawer , ' updateFreq' , 1 , 360 , 1 ); // 线条渲染的频率(每帧)
102+ f .add (Physics .debugDrawer , ' maxLineCount' , 100 , 33000 , 100 ); // 设置渲染的最大线条数量
103+ ```
104+ :::
105+
106+ - ** 物理对象交互** :如果需要使用鼠标与刚体进行拖拽控制,可以在 ` init() ` 中将此功能开启:
107+
108+ ``` ts
109+ await Physics .init ({ useDrag: true });
110+ ```
111+ ::: tip
112+ 可以通过 ` Physics.physicsDragger ` 进行相关设置,详见 [ PhysicsDragger] ( /physics/classes/PhysicsDragger )
113+ :::
114+
115+ ## 物理工具
116+ 物理系统提供了一些工具,帮助开发者更灵活地进行定制开发。
117+ - [ CollisionShapeUtil] ( /physics/classes/CollisionShapeUtil ) :提供多种方法来创建不同类型的碰撞形状。
118+ - [ ContactProcessedUtil] ( /physics/classes/ContactProcessedUtil ) :用于注册和管理物理对象之间碰撞事件的工具类。
119+ - [ RigidBodyMapping] ( /physics/classes/RigidBodyMapping ) :管理 ` Ammo ` 刚体与三维模型对象映射关系的工具类,需手动指定映射。
120+ - [ RigidBodyUtil] ( /physics/classes/RigidBodyUtil ) :提供多种与 ` Ammo ` 刚体相关的实用方法,简化刚体的创建和各项操作。
121+ - [ TempPhyMath] ( /physics/classes/TempPhyMath ) :临时物理数学工具类,提供 ` Ammo ` 数学对象(如向量和四元数)的实例,并支持与引擎数据类型相互转换。
122+
123+
72124## 原生扩展
73125当前引擎只封装了几个常用的组件,如果需要实现复杂的物理模拟,用户可以直接引用 ` Ammo ` 来使用原生的物理世界对象,通过 ` Ammo.js ` 自身提供的原生 ` API ` 实现更多自定化需求:
74126``` ts
@@ -89,45 +141,43 @@ let transform = new Ammo.btTransform();
89141更多用法详见 [ Ammo API] ( /physics/modules/Ammo )
90142
91143## 简单示例
92- 这里我们通过模拟一个正方体掉落在地上的过程,看一下物理系统具体可以提供哪下效果 。
144+ 这里我们通过模拟一个正方体掉落在地上的过程,看一下物理系统具体可以提供哪些效果 。
93145
94146<Demo src =" /demos/physics/demo1.ts " ></Demo >
95147
96148<<< @/public/demos/physics/demo1.ts
97149
98150依照前面章节所介绍的流程,我们首先将场景、相机、环境贴图、光照等基础组件初始化并设定好参数。
99- 接下来,我们创建一个立方体,并为其添加刚体与碰撞体组件,使之拥有质量并能正确响应重力与碰撞。
100- ``` ts
151+ 接下来,我们创建一个立方体,并为其添加刚体组件并指定碰撞形状,使之拥有质量并能正确响应重力与碰撞。
152+
153+ ``` ts {7-9}
101154const obj = new Object3D ();
102155let mr = obj .addComponent (MeshRenderer );
103156mr .geometry = new BoxGeometry (5 , 5 , 5 );
104157mr .material = new LitMaterial ();
105- // 响应重力
158+
159+ // 响应重力并设置碰撞形状
106160let rigidbody = obj .addComponent (Rigidbody );
107161rigidbody .mass = 10 ;
108- // 设置碰撞盒子
109- let collider = obj .addComponent (ColliderComponent );
110- collider .shape = new BoxColliderShape ();
111- collider .shape .size = new Vector3 (5 , 5 , 5 );
162+ rigidbody .shape = Rigidbody .collisionShape .createShapeFromObject (obj );
112163
113164scene3D .addChild (obj );
114165```
115166
116- 之后,我们在正方体下方创建一个平面,作为地面,同样为其添加刚体与碰撞体组件。由于地面是静止的,所以我们设置其质量为 ` 0 ` 。
117- ``` ts
167+ 之后,我们在正方体下方创建一个平面,作为地面,同样为其添加刚体组件并指定碰撞形状。由于地面是静止的,所以我们设置其质量为 ` 0 ` 。
168+
169+ ``` ts {7-9}
118170const obj = new Object3D ();
119171let mr = obj .addComponent (MeshRenderer );
120172mr .geometry = new PlaneGeometry (size .x , size .y );
121173mr .material = new LitMaterial ();
122- // 静态钢体,不响应重力
174+
175+ // 静态刚体,不响应重力
123176let rigidbody = obj .addComponent (Rigidbody );
124177rigidbody .mass = 0 ;
125- // 设置碰撞盒子
126- let collider = obj .addComponent (ColliderComponent );
127- collider .shape = new BoxColliderShape ();
128- collider .shape .size = new Vector3 (size .x , 0.1 , size .y );
178+ rigidbody .shape = Rigidbody .collisionShape .createShapeFromObject (obj );
129179
130180scene .addChild (obj );
131181```
132182
133- 物理系统启动后,引擎立即根据物体质量响应其重力感应,当立方体和地面的碰撞体形状产生交集时,我们可以看到真实的物体落地碰撞效果。 更多[ 物理示例] ( /example/physics/Dominoes ) 。
183+ 物理系统启动后,引擎立即根据物体质量响应其重力感应,当立方体和地面的碰撞体形状产生交集时,我们可以看到真实的物体落地碰撞效果, 更多[ 物理示例] ( /example/physics/Dominoes ) 。
0 commit comments