Files
esengine/thirdparty/rapier.js/src.ts/geometry/collider_set.ts
YHH 63f006ab62 feat: 添加跨平台运行时、资产系统和UI适配功能 (#256)
* feat(platform-common): 添加WASM加载器和环境检测API

* feat(rapier2d): 新增Rapier2D WASM绑定包

* feat(physics-rapier2d): 添加跨平台WASM加载器

* feat(asset-system): 添加运行时资产目录和bundle格式

* feat(asset-system-editor): 新增编辑器资产管理包

* feat(editor-core): 添加构建系统和模块管理

* feat(editor-app): 重构浏览器预览使用import maps

* feat(platform-web): 添加BrowserRuntime和资产读取

* feat(engine): 添加材质系统和着色器管理

* feat(material): 新增材质系统和着色器编辑器

* feat(tilemap): 增强tilemap编辑器和动画系统

* feat(modules): 添加module.json配置

* feat(core): 添加module.json和类型定义更新

* chore: 更新依赖和构建配置

* refactor(plugins): 更新插件模板使用ModuleManifest

* chore: 添加第三方依赖库

* chore: 移除BehaviourTree-ai和ecs-astar子模块

* docs: 更新README和文档主题样式

* fix: 修复Rust文档测试和添加rapier2d WASM绑定

* fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题

* feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea)

* fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖

* fix: 添加缺失的包依赖修复CI构建

* fix: 修复CodeQL检测到的代码问题

* fix: 修复构建错误和缺失依赖

* fix: 修复类型检查错误

* fix(material-system): 修复tsconfig配置支持TypeScript项目引用

* fix(editor-core): 修复Rollup构建配置添加tauri external

* fix: 修复CodeQL检测到的代码问题

* fix: 修复CodeQL检测到的代码问题
2025-12-03 22:15:22 +08:00

214 lines
6.0 KiB
TypeScript

import {RawColliderSet} from "../raw";
import {Coarena} from "../coarena";
import {RotationOps, VectorOps} from "../math";
import {Collider, ColliderDesc, ColliderHandle} from "./collider";
import {ImpulseJointHandle, IslandManager, RigidBodyHandle} from "../dynamics";
import {RigidBodySet} from "../dynamics";
/**
* A set of rigid bodies that can be handled by a physics pipeline.
*
* To avoid leaking WASM resources, this MUST be freed manually with `colliderSet.free()`
* once you are done using it (and all the rigid-bodies it created).
*/
export class ColliderSet {
raw: RawColliderSet;
private map: Coarena<Collider>;
/**
* Release the WASM memory occupied by this collider set.
*/
public free() {
if (!!this.raw) {
this.raw.free();
}
this.raw = undefined;
if (!!this.map) {
this.map.clear();
}
this.map = undefined;
}
constructor(raw?: RawColliderSet) {
this.raw = raw || new RawColliderSet();
this.map = new Coarena<Collider>();
// Initialize the map with the existing elements, if any.
if (raw) {
raw.forEachColliderHandle((handle: ColliderHandle) => {
this.map.set(handle, new Collider(this, handle, null));
});
}
}
/** @internal */
public castClosure<Res>(
f?: (collider: Collider) => Res,
): (handle: ColliderHandle) => Res | undefined {
return (handle) => {
if (!!f) {
return f(this.get(handle));
} else {
return undefined;
}
};
}
/** @internal */
public finalizeDeserialization(bodies: RigidBodySet) {
this.map.forEach((collider) =>
collider.finalizeDeserialization(bodies),
);
}
/**
* Creates a new collider and return its integer handle.
*
* @param bodies - The set of bodies where the collider's parent can be found.
* @param desc - The collider's description.
* @param parentHandle - The integer handle of the rigid-body this collider is attached to.
*/
public createCollider(
bodies: RigidBodySet,
desc: ColliderDesc,
parentHandle: RigidBodyHandle,
): Collider {
let hasParent = parentHandle != undefined && parentHandle != null;
if (hasParent && isNaN(parentHandle))
throw Error(
"Cannot create a collider with a parent rigid-body handle that is not a number.",
);
let rawShape = desc.shape.intoRaw();
let rawTra = VectorOps.intoRaw(desc.translation);
let rawRot = RotationOps.intoRaw(desc.rotation);
let rawCom = VectorOps.intoRaw(desc.centerOfMass);
// #if DIM3
let rawPrincipalInertia = VectorOps.intoRaw(
desc.principalAngularInertia,
);
let rawInertiaFrame = RotationOps.intoRaw(
desc.angularInertiaLocalFrame,
);
// #endif
let handle = this.raw.createCollider(
desc.enabled,
rawShape,
rawTra,
rawRot,
desc.massPropsMode,
desc.mass,
rawCom,
// #if DIM2
desc.principalAngularInertia,
// #endif
// #if DIM3
rawPrincipalInertia,
rawInertiaFrame,
// #endif
desc.density,
desc.friction,
desc.restitution,
desc.frictionCombineRule,
desc.restitutionCombineRule,
desc.isSensor,
desc.collisionGroups,
desc.solverGroups,
desc.activeCollisionTypes,
desc.activeHooks,
desc.activeEvents,
desc.contactForceEventThreshold,
desc.contactSkin,
hasParent,
hasParent ? parentHandle : 0,
bodies.raw,
);
rawShape.free();
rawTra.free();
rawRot.free();
rawCom.free();
// #if DIM3
rawPrincipalInertia.free();
rawInertiaFrame.free();
// #endif
let parent = hasParent ? bodies.get(parentHandle) : null;
let collider = new Collider(this, handle, parent, desc.shape);
this.map.set(handle, collider);
return collider;
}
/**
* Remove a collider from this set.
*
* @param handle - The integer handle of the collider to remove.
* @param bodies - The set of rigid-body containing the rigid-body the collider is attached to.
* @param wakeUp - If `true`, the rigid-body the removed collider is attached to will be woken-up automatically.
*/
public remove(
handle: ColliderHandle,
islands: IslandManager,
bodies: RigidBodySet,
wakeUp: boolean,
) {
this.raw.remove(handle, islands.raw, bodies.raw, wakeUp);
this.unmap(handle);
}
/**
* Internal function, do not call directly.
* @param handle
*/
public unmap(handle: ImpulseJointHandle) {
this.map.delete(handle);
}
/**
* Gets the rigid-body with the given handle.
*
* @param handle - The handle of the rigid-body to retrieve.
*/
public get(handle: ColliderHandle): Collider | null {
return this.map.get(handle);
}
/**
* The number of colliders on this set.
*/
public len(): number {
return this.map.len();
}
/**
* Does this set contain a collider with the given handle?
*
* @param handle - The collider handle to check.
*/
public contains(handle: ColliderHandle): boolean {
return this.get(handle) != null;
}
/**
* Applies the given closure to each collider contained by this set.
*
* @param f - The closure to apply.
*/
public forEach(f: (collider: Collider) => void) {
this.map.forEach(f);
}
/**
* Gets all colliders in the list.
*
* @returns collider list.
*/
public getAll(): Collider[] {
return this.map.getAll();
}
}