JoltPhysics.js
本项目使JavaScript能够使用Jolt Physics。
演示
访问演示页面查看项目实际运行效果。
使用方法
本库提供三种版本:
wasm-compat
- WASM版本,WASM文件(以base64编码)嵌入捆绑包中wasm
- WASM版本,带有单独的WASM文件asm
- 使用asm.js的JavaScript版本
查看falling_shapes.html获取库的使用示例。
文档
库的接口与JoltPhysics的C++接口相同,因此可以使用C++文档作为参考。
几乎所有Jolt接口都已暴露。查看JoltJS.idl以确认特定接口是否已暴露。如果没有,请编辑JoltJS.idl和JoltJS.h并提交拉取请求,或提出问题。
安装
本库作为ECMAScript模块在npm上分发:
npm install jolt-physics
不同版本可通过npm包的入口点获得:
// WASM嵌入捆绑包
import Jolt from 'jolt-physics';
import Jolt from 'jolt-physics/wasm-compat';
// WASM
import Jolt from 'jolt-physics/wasm';
// asm.js
import Jolt from 'jolt-physics/asm';
也可以使用unpkg导入esm捆绑包:
<script type="module">
// 导入最新版本
import Jolt from 'https://www.unpkg.com/jolt-physics/dist/jolt-physics.wasm-compat.js';
// 或导入特定版本
import Jolt from 'https://www.unpkg.com/jolt-physics@x.y.z/dist/jolt-physics.wasm-compat.js';
</script>
其中x.y.z
是你要使用的库版本。
使用WASM版本
要使用wasm
版本,你必须将WASM文件jolt-physics.wasm.wasm
与jolt-physics.wasm.js
一起提供服务,或使用支持将资产作为URL导入的打包工具,并告诉Jolt在哪里找到WASM文件。
要指定从何处检索WASM文件,可以向jolt-physics/wasm
的默认导出传递一个locateFile
函数。例如,使用vite时,这将如下所示:
import initJolt from "jolt-physics";
import joltWasmUrl from "jolt-physics/jolt-physics.wasm.wasm?url";
const Jolt = await initJolt({
locateFile: () => joltWasmUrl,
});
有关locateFile
函数的更多信息,请参阅Emscripten文档。
构建
本项目仅在Linux下编译过。
- 安装emscripten并确保其环境变量已设置
- 安装cmake
- 运行
./build.sh Distribution
进行优化构建,运行./build.sh Debug
进行调试构建。
可以向build.sh
提供额外选项:
-DENABLE_MEMORY_PROFILER=ON
将启用内存跟踪以检测泄漏。-DDOUBLE_PRECISION=ON
将启用双精度模式。这允许创建大于几公里的世界。-DENABLE_SIMD=ON
将启用SIMD指令。Safari 16.4是最后一个支持这个功能的主要浏览器(2023年3月)。-DENABLE_MULTI_THREADING=ON
将启用多线程。请注意,由于Safari的一个bug,目前在该浏览器中无法正常工作。它也与任何从Web Worker触发的JavaScript回调函数不兼容。详见此处。-DBUILD_WASM_COMPAT_ONLY=ON
通过只编译示例使用的WASM兼容版本来加快构建速度。
运行
默认情况下,示例使用Jolt的WASM版本。这需要使用Web服务器来提供html文件,而不是直接打开html文件。
在此文件夹中打开终端并运行以下命令:
npm install
npm run examples
然后导航到:http://localhost:3000/
如果你需要调试C++代码,请查看WASM调试。
内存管理
这些示例在清理方面做得很糟糕(基本上没有清理)。当使用emscripten将库移植到WASM时,没有任何东西会自动清理,所以你用new Jolt.XXX
创建的所有东西都需要通过Jolt.destroy(...)
销毁。
此外,Jolt对许多类使用引用计数(所有继承自RefTarget的类)。最重要的类有:
- ShapeSettings
- Shape
- ConstraintSettings
- Constraint
- PhysicsMaterial
- GroupFilter
- SoftBodySharedSettings
- VehicleCollisionTester
- VehicleController
- WheelSettings
- CharacterBaseSettings
- CharacterBase
引用计数对象的初始引用计数为0。如果你想保持对对象的所有权,你需要调用object.AddRef()
,这将增加引用计数。如果你想释放所有权,你需要调用object.Release()
,这将减少引用计数,如果引用计数达到0,对象将被销毁。如果在创建后,你将一个引用计数对象传递给另一个对象(例如将ShapeSettings传递给CompoundShapeSettings或将Shape传递给Body),那么另一个对象将获取一个引用,在这种情况下不需要自己事先获取引用,所以你可以跳过AddRef/Release
的调用。请注意,对于引用计数对象,也可以在new Jolt.XXX
之后直接调用Jolt.destroy(...)
,如果没有人获取引用的话。
Body类也是一个特殊情况,它通过BodyInterface.DestroyBody(body.GetID())销毁(内部销毁Body)。
几乎所有其他东西都可以在传递给Jolt后立即销毁。这里有一个展示如何正确清理Jolt的示例。
使用JoltPhysics.js的项目
- Babylon.js插件 - 一个用Jolt替换默认物理引擎的插件。
- react-three-jolt - 封装Jolt以便在react-three-fiber中轻松使用。
- r3f-jolt - 另一个用于react-three-fiber的封装器。
许可证
该项目在MIT许可证下分发。