Files
esengine/thirdparty/rapier.js/src/dynamics/joint.rs
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

315 lines
9.1 KiB
Rust

use crate::math::{RawRotation, RawVector};
use na::Unit;
use rapier::dynamics::{
FixedJointBuilder, GenericJoint, JointAxesMask, JointAxis, MotorModel, PrismaticJointBuilder,
RevoluteJointBuilder, RopeJointBuilder, SpringJointBuilder,
};
#[cfg(feature = "dim3")]
use rapier::dynamics::{GenericJointBuilder, SphericalJointBuilder};
use rapier::math::Isometry;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[cfg(feature = "dim2")]
pub enum RawJointType {
Revolute,
Fixed,
Prismatic,
Rope,
Spring,
Generic,
}
#[wasm_bindgen]
#[cfg(feature = "dim3")]
pub enum RawJointType {
Revolute,
Fixed,
Prismatic,
Rope,
Spring,
Spherical,
Generic,
}
/// The type of this joint.
#[cfg(feature = "dim2")]
impl From<JointAxesMask> for RawJointType {
fn from(ty: JointAxesMask) -> RawJointType {
let rev_axes = JointAxesMask::LIN_X | JointAxesMask::LIN_Y;
let pri_axes = JointAxesMask::LIN_Y | JointAxesMask::ANG_X;
let fix_axes = JointAxesMask::LIN_X | JointAxesMask::LIN_Y | JointAxesMask::ANG_X;
if ty == rev_axes {
RawJointType::Revolute
} else if ty == pri_axes {
RawJointType::Prismatic
} else if ty == fix_axes {
RawJointType::Fixed
} else {
RawJointType::Generic
}
}
}
/// The type of this joint.
#[cfg(feature = "dim3")]
impl From<JointAxesMask> for RawJointType {
fn from(ty: JointAxesMask) -> RawJointType {
let rev_axes = JointAxesMask::LIN_X
| JointAxesMask::LIN_Y
| JointAxesMask::LIN_Z
| JointAxesMask::ANG_Y
| JointAxesMask::ANG_Z;
let pri_axes = JointAxesMask::LIN_Y
| JointAxesMask::LIN_Z
| JointAxesMask::ANG_X
| JointAxesMask::ANG_Y
| JointAxesMask::ANG_Z;
let sph_axes = JointAxesMask::ANG_X | JointAxesMask::ANG_Y | JointAxesMask::ANG_Z;
let fix_axes = JointAxesMask::LIN_X
| JointAxesMask::LIN_Y
| JointAxesMask::LIN_Z
| JointAxesMask::ANG_X
| JointAxesMask::ANG_Y
| JointAxesMask::ANG_Z;
if ty == rev_axes {
RawJointType::Revolute
} else if ty == pri_axes {
RawJointType::Prismatic
} else if ty == sph_axes {
RawJointType::Spherical
} else if ty == fix_axes {
RawJointType::Fixed
} else {
RawJointType::Generic
}
}
}
#[wasm_bindgen]
pub enum RawMotorModel {
AccelerationBased,
ForceBased,
}
impl From<RawMotorModel> for MotorModel {
fn from(model: RawMotorModel) -> MotorModel {
match model {
RawMotorModel::AccelerationBased => MotorModel::AccelerationBased,
RawMotorModel::ForceBased => MotorModel::ForceBased,
}
}
}
#[cfg(feature = "dim2")]
#[wasm_bindgen]
#[derive(Copy, Clone)]
pub enum RawJointAxis {
LinX,
LinY,
AngX,
}
#[cfg(feature = "dim3")]
#[wasm_bindgen]
#[derive(Copy, Clone)]
pub enum RawJointAxis {
LinX,
LinY,
LinZ,
AngX,
AngY,
AngZ,
}
impl From<RawJointAxis> for JointAxis {
fn from(axis: RawJointAxis) -> JointAxis {
match axis {
RawJointAxis::LinX => JointAxis::LinX,
RawJointAxis::LinY => JointAxis::LinY,
#[cfg(feature = "dim3")]
RawJointAxis::LinZ => JointAxis::LinZ,
RawJointAxis::AngX => JointAxis::AngX,
#[cfg(feature = "dim3")]
RawJointAxis::AngY => JointAxis::AngY,
#[cfg(feature = "dim3")]
RawJointAxis::AngZ => JointAxis::AngZ,
}
}
}
#[wasm_bindgen]
pub struct RawGenericJoint(pub(crate) GenericJoint);
#[wasm_bindgen]
impl RawGenericJoint {
/// Creates a new joint descriptor that builds generic joints.
///
/// Generic joints allow arbitrary axes of freedom to be selected
/// for the joint from the available 6 degrees of freedom.
#[cfg(feature = "dim3")]
pub fn generic(
anchor1: &RawVector,
anchor2: &RawVector,
axis: &RawVector,
lockedAxes: u8,
) -> Option<RawGenericJoint> {
let axesMask: JointAxesMask = JointAxesMask::from_bits(lockedAxes)?;
let axis = Unit::try_new(axis.0, 0.0)?;
let joint: GenericJoint = GenericJointBuilder::new(axesMask)
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into())
.local_axis1(axis)
.local_axis2(axis)
.into();
Some(Self(joint))
}
pub fn spring(
rest_length: f32,
stiffness: f32,
damping: f32,
anchor1: &RawVector,
anchor2: &RawVector,
) -> Self {
Self(
SpringJointBuilder::new(rest_length, stiffness, damping)
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into())
.into(),
)
}
pub fn rope(length: f32, anchor1: &RawVector, anchor2: &RawVector) -> Self {
Self(
RopeJointBuilder::new(length)
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into())
.into(),
)
}
/// Create a new joint descriptor that builds spherical joints.
///
/// A spherical joints allows three relative rotational degrees of freedom
/// by preventing any relative translation between the anchors of the
/// two attached rigid-bodies.
#[cfg(feature = "dim3")]
pub fn spherical(anchor1: &RawVector, anchor2: &RawVector) -> Self {
Self(
SphericalJointBuilder::new()
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into())
.into(),
)
}
/// Creates a new joint descriptor that builds a Prismatic joint.
///
/// A prismatic joint removes all the degrees of freedom between the
/// affected bodies, except for the translation along one axis.
///
/// Returns `None` if any of the provided axes cannot be normalized.
#[cfg(feature = "dim2")]
pub fn prismatic(
anchor1: &RawVector,
anchor2: &RawVector,
axis: &RawVector,
limitsEnabled: bool,
limitsMin: f32,
limitsMax: f32,
) -> Option<RawGenericJoint> {
let axis = Unit::try_new(axis.0, 0.0)?;
let mut joint = PrismaticJointBuilder::new(axis)
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into());
if limitsEnabled {
joint = joint.limits([limitsMin, limitsMax]);
}
Some(Self(joint.into()))
}
/// Creates a new joint descriptor that builds a Prismatic joint.
///
/// A prismatic joint removes all the degrees of freedom between the
/// affected bodies, except for the translation along one axis.
///
/// Returns `None` if any of the provided axes cannot be normalized.
#[cfg(feature = "dim3")]
pub fn prismatic(
anchor1: &RawVector,
anchor2: &RawVector,
axis: &RawVector,
limitsEnabled: bool,
limitsMin: f32,
limitsMax: f32,
) -> Option<RawGenericJoint> {
let axis = Unit::try_new(axis.0, 0.0)?;
let mut joint = PrismaticJointBuilder::new(axis)
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into());
if limitsEnabled {
joint = joint.limits([limitsMin, limitsMax]);
}
Some(Self(joint.into()))
}
/// Creates a new joint descriptor that builds a Fixed joint.
///
/// A fixed joint removes all the degrees of freedom between the affected bodies.
pub fn fixed(
anchor1: &RawVector,
axes1: &RawRotation,
anchor2: &RawVector,
axes2: &RawRotation,
) -> RawGenericJoint {
let pos1 = Isometry::from_parts(anchor1.0.into(), axes1.0);
let pos2 = Isometry::from_parts(anchor2.0.into(), axes2.0);
Self(
FixedJointBuilder::new()
.local_frame1(pos1)
.local_frame2(pos2)
.into(),
)
}
/// Create a new joint descriptor that builds Revolute joints.
///
/// A revolute joint removes all degrees of freedom between the affected
/// bodies except for the rotation.
#[cfg(feature = "dim2")]
pub fn revolute(anchor1: &RawVector, anchor2: &RawVector) -> Option<RawGenericJoint> {
Some(Self(
RevoluteJointBuilder::new()
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into())
.into(),
))
}
/// Create a new joint descriptor that builds Revolute joints.
///
/// A revolute joint removes all degrees of freedom between the affected
/// bodies except for the rotation along one axis.
#[cfg(feature = "dim3")]
pub fn revolute(
anchor1: &RawVector,
anchor2: &RawVector,
axis: &RawVector,
) -> Option<RawGenericJoint> {
let axis = Unit::try_new(axis.0, 0.0)?;
Some(Self(
RevoluteJointBuilder::new(axis)
.local_anchor1(anchor1.0.into())
.local_anchor2(anchor2.0.into())
.into(),
))
}
}