Files
esengine/thirdparty/rapier.js/src/geometry/collider.rs

994 lines
36 KiB
Rust
Raw Normal View History

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
use crate::geometry::shape::SharedShapeUtility;
use crate::geometry::{
RawColliderSet, RawColliderShapeCastHit, RawPointProjection, RawRayIntersection, RawShape,
RawShapeCastHit, RawShapeContact, RawShapeType,
};
use crate::math::{RawRotation, RawVector};
use crate::utils::{self, FlatHandle};
use rapier::dynamics::MassProperties;
use rapier::geometry::{ActiveCollisionTypes, ShapeType};
use rapier::math::{Isometry, Point, Real, Vector};
use rapier::parry::query;
use rapier::parry::query::ShapeCastOptions;
use rapier::pipeline::{ActiveEvents, ActiveHooks};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
impl RawColliderSet {
/// The world-space translation of this collider.
pub fn coTranslation(&self, handle: FlatHandle) -> RawVector {
self.map(handle, |co| co.position().translation.vector.into())
}
/// The world-space orientation of this collider.
pub fn coRotation(&self, handle: FlatHandle) -> RawRotation {
self.map(handle, |co| co.position().rotation.into())
}
/// The translation of this collider relative to its parent rigid-body.
///
/// Returns the `None` if it doesnt have a parent.
pub fn coTranslationWrtParent(&self, handle: FlatHandle) -> Option<RawVector> {
self.map(handle, |co| {
co.position_wrt_parent()
.map(|pose| pose.translation.vector.into())
})
}
/// The orientation of this collider relative to its parent rigid-body.
///
/// Returns the `None` if it doesnt have a parent.
pub fn coRotationWrtParent(&self, handle: FlatHandle) -> Option<RawRotation> {
self.map(handle, |co| {
co.position_wrt_parent().map(|pose| pose.rotation.into())
})
}
/// Sets the translation of this collider.
///
/// # Parameters
/// - `x`: the world-space position of the collider along the `x` axis.
/// - `y`: the world-space position of the collider along the `y` axis.
/// - `z`: the world-space position of the collider along the `z` axis.
/// - `wakeUp`: forces the collider to wake-up so it is properly affected by forces if it
/// wasn't moving before modifying its position.
#[cfg(feature = "dim3")]
pub fn coSetTranslation(&mut self, handle: FlatHandle, x: f32, y: f32, z: f32) {
self.map_mut(handle, |co| {
co.set_translation(na::Vector3::new(x, y, z));
})
}
/// Sets the translation of this collider.
///
/// # Parameters
/// - `x`: the world-space position of the collider along the `x` axis.
/// - `y`: the world-space position of the collider along the `y` axis.
/// - `wakeUp`: forces the collider to wake-up so it is properly affected by forces if it
/// wasn't moving before modifying its position.
#[cfg(feature = "dim2")]
pub fn coSetTranslation(&mut self, handle: FlatHandle, x: f32, y: f32) {
self.map_mut(handle, |co| {
co.set_translation(na::Vector2::new(x, y));
})
}
#[cfg(feature = "dim3")]
pub fn coSetTranslationWrtParent(&mut self, handle: FlatHandle, x: f32, y: f32, z: f32) {
self.map_mut(handle, |co| {
co.set_translation_wrt_parent(na::Vector3::new(x, y, z));
})
}
#[cfg(feature = "dim2")]
pub fn coSetTranslationWrtParent(&mut self, handle: FlatHandle, x: f32, y: f32) {
self.map_mut(handle, |co| {
co.set_translation_wrt_parent(na::Vector2::new(x, y));
})
}
/// Sets the rotation quaternion of this collider.
///
/// This does nothing if a zero quaternion is provided.
///
/// # Parameters
/// - `x`: the first vector component of the quaternion.
/// - `y`: the second vector component of the quaternion.
/// - `z`: the third vector component of the quaternion.
/// - `w`: the scalar component of the quaternion.
/// - `wakeUp`: forces the collider to wake-up so it is properly affected by forces if it
/// wasn't moving before modifying its position.
#[cfg(feature = "dim3")]
pub fn coSetRotation(&mut self, handle: FlatHandle, x: f32, y: f32, z: f32, w: f32) {
if let Some(q) = na::Unit::try_new(na::Quaternion::new(w, x, y, z), 0.0) {
self.map_mut(handle, |co| co.set_rotation(q))
}
}
/// Sets the rotation angle of this collider.
///
/// # Parameters
/// - `angle`: the rotation angle, in radians.
/// - `wakeUp`: forces the collider to wake-up so it is properly affected by forces if it
/// wasn't moving before modifying its position.
#[cfg(feature = "dim2")]
pub fn coSetRotation(&mut self, handle: FlatHandle, angle: f32) {
self.map_mut(handle, |co| co.set_rotation(na::UnitComplex::new(angle)))
}
#[cfg(feature = "dim3")]
pub fn coSetRotationWrtParent(&mut self, handle: FlatHandle, x: f32, y: f32, z: f32, w: f32) {
if let Some(q) = na::Unit::try_new(na::Quaternion::new(w, x, y, z), 0.0) {
self.map_mut(handle, |co| co.set_rotation_wrt_parent(q.scaled_axis()))
}
}
#[cfg(feature = "dim2")]
pub fn coSetRotationWrtParent(&mut self, handle: FlatHandle, angle: f32) {
self.map_mut(handle, |co| co.set_rotation_wrt_parent(angle))
}
/// Is this collider a sensor?
pub fn coIsSensor(&self, handle: FlatHandle) -> bool {
self.map(handle, |co| co.is_sensor())
}
/// The type of the shape of this collider.
pub fn coShapeType(&self, handle: FlatHandle) -> RawShapeType {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::Ball => RawShapeType::Ball,
ShapeType::Cuboid => RawShapeType::Cuboid,
ShapeType::Capsule => RawShapeType::Capsule,
ShapeType::Segment => RawShapeType::Segment,
ShapeType::Polyline => RawShapeType::Polyline,
ShapeType::Triangle => RawShapeType::Triangle,
ShapeType::TriMesh => RawShapeType::TriMesh,
ShapeType::HeightField => RawShapeType::HeightField,
ShapeType::Compound => RawShapeType::Compound,
ShapeType::HalfSpace => RawShapeType::HalfSpace,
ShapeType::Voxels => RawShapeType::Voxels,
#[cfg(feature = "dim3")]
ShapeType::ConvexPolyhedron => RawShapeType::ConvexPolyhedron,
#[cfg(feature = "dim2")]
ShapeType::ConvexPolygon => RawShapeType::ConvexPolygon,
#[cfg(feature = "dim3")]
ShapeType::Cylinder => RawShapeType::Cylinder,
#[cfg(feature = "dim3")]
ShapeType::Cone => RawShapeType::Cone,
ShapeType::RoundCuboid => RawShapeType::RoundCuboid,
ShapeType::RoundTriangle => RawShapeType::RoundTriangle,
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => RawShapeType::RoundCylinder,
#[cfg(feature = "dim3")]
ShapeType::RoundCone => RawShapeType::RoundCone,
#[cfg(feature = "dim3")]
ShapeType::RoundConvexPolyhedron => RawShapeType::RoundConvexPolyhedron,
#[cfg(feature = "dim2")]
ShapeType::RoundConvexPolygon => RawShapeType::RoundConvexPolygon,
ShapeType::Custom => panic!("Not yet implemented."),
})
}
pub fn coHalfspaceNormal(&self, handle: FlatHandle) -> Option<RawVector> {
self.map(handle, |co| {
co.shape()
.as_halfspace()
.map(|h| h.normal.into_inner().into())
})
}
/// The half-extents of this collider if it is has a cuboid shape.
pub fn coHalfExtents(&self, handle: FlatHandle) -> Option<RawVector> {
self.map(handle, |co| {
co.shape()
.as_cuboid()
.map(|c| c.half_extents.into())
.or_else(|| {
co.shape()
.as_round_cuboid()
.map(|c| c.inner_shape.half_extents.into())
})
})
}
/// Set the half-extents of this collider if it has a cuboid shape.
pub fn coSetHalfExtents(&mut self, handle: FlatHandle, newHalfExtents: &RawVector) {
self.map_mut(handle, |co| match co.shape().shape_type() {
ShapeType::Cuboid => co
.shape_mut()
.as_cuboid_mut()
.map(|b| b.half_extents = newHalfExtents.0.into()),
ShapeType::RoundCuboid => co
.shape_mut()
.as_round_cuboid_mut()
.map(|b| b.inner_shape.half_extents = newHalfExtents.0.into()),
_ => None,
});
}
/// The radius of this collider if it is a ball, capsule, cylinder, or cone shape.
pub fn coRadius(&self, handle: FlatHandle) -> Option<f32> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::Ball => co.shape().as_ball().map(|b| b.radius),
ShapeType::Capsule => co.shape().as_capsule().map(|b| b.radius),
#[cfg(feature = "dim3")]
ShapeType::Cylinder => co.shape().as_cylinder().map(|b| b.radius),
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => {
co.shape().as_round_cylinder().map(|b| b.inner_shape.radius)
}
#[cfg(feature = "dim3")]
ShapeType::Cone => co.shape().as_cone().map(|b| b.radius),
_ => None,
})
}
/// Set the radius of this collider if it is a ball, capsule, cylinder, or cone shape.
pub fn coSetRadius(&mut self, handle: FlatHandle, newRadius: Real) {
self.map_mut(handle, |co| match co.shape().shape_type() {
ShapeType::Ball => co.shape_mut().as_ball_mut().map(|b| b.radius = newRadius),
ShapeType::Capsule => co
.shape_mut()
.as_capsule_mut()
.map(|b| b.radius = newRadius),
#[cfg(feature = "dim3")]
ShapeType::Cylinder => co
.shape_mut()
.as_cylinder_mut()
.map(|b| b.radius = newRadius),
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => co
.shape_mut()
.as_round_cylinder_mut()
.map(|b| b.inner_shape.radius = newRadius),
#[cfg(feature = "dim3")]
ShapeType::Cone => co.shape_mut().as_cone_mut().map(|b| b.radius = newRadius),
_ => None,
});
}
/// The half height of this collider if it is a capsule, cylinder, or cone shape.
pub fn coHalfHeight(&self, handle: FlatHandle) -> Option<f32> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::Capsule => co.shape().as_capsule().map(|b| b.half_height()),
#[cfg(feature = "dim3")]
ShapeType::Cylinder => co.shape().as_cylinder().map(|b| b.half_height),
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => co
.shape()
.as_round_cylinder()
.map(|b| b.inner_shape.half_height),
#[cfg(feature = "dim3")]
ShapeType::Cone => co.shape().as_cone().map(|b| b.half_height),
_ => None,
})
}
/// Set the half height of this collider if it is a capsule, cylinder, or cone shape.
pub fn coSetHalfHeight(&mut self, handle: FlatHandle, newHalfheight: Real) {
self.map_mut(handle, |co| match co.shape().shape_type() {
ShapeType::Capsule => {
let point = Point::from(Vector::y() * newHalfheight);
co.shape_mut().as_capsule_mut().map(|b| {
b.segment.a = -point;
b.segment.b = point;
})
}
#[cfg(feature = "dim3")]
ShapeType::Cylinder => co
.shape_mut()
.as_cylinder_mut()
.map(|b| b.half_height = newHalfheight),
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => co
.shape_mut()
.as_round_cylinder_mut()
.map(|b| b.inner_shape.half_height = newHalfheight),
#[cfg(feature = "dim3")]
ShapeType::Cone => co
.shape_mut()
.as_cone_mut()
.map(|b| b.half_height = newHalfheight),
_ => None,
});
}
/// The radius of the round edges of this collider.
pub fn coRoundRadius(&self, handle: FlatHandle) -> Option<f32> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::RoundCuboid => co.shape().as_round_cuboid().map(|b| b.border_radius),
ShapeType::RoundTriangle => co.shape().as_round_triangle().map(|b| b.border_radius),
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => co.shape().as_round_cylinder().map(|b| b.border_radius),
#[cfg(feature = "dim3")]
ShapeType::RoundCone => co.shape().as_round_cone().map(|b| b.border_radius),
#[cfg(feature = "dim3")]
ShapeType::RoundConvexPolyhedron => co
.shape()
.as_round_convex_polyhedron()
.map(|b| b.border_radius),
#[cfg(feature = "dim2")]
ShapeType::RoundConvexPolygon => co
.shape()
.as_round_convex_polygon()
.map(|b| b.border_radius),
_ => None,
})
}
/// Set the radius of the round edges of this collider.
pub fn coSetRoundRadius(&mut self, handle: FlatHandle, newBorderRadius: Real) {
self.map_mut(handle, |co| match co.shape().shape_type() {
ShapeType::RoundCuboid => co
.shape_mut()
.as_round_cuboid_mut()
.map(|b| b.border_radius = newBorderRadius),
ShapeType::RoundTriangle => co
.shape_mut()
.as_round_triangle_mut()
.map(|b| b.border_radius = newBorderRadius),
#[cfg(feature = "dim3")]
ShapeType::RoundCylinder => co
.shape_mut()
.as_round_cylinder_mut()
.map(|b| b.border_radius = newBorderRadius),
#[cfg(feature = "dim3")]
ShapeType::RoundCone => co
.shape_mut()
.as_round_cone_mut()
.map(|b| b.border_radius = newBorderRadius),
#[cfg(feature = "dim3")]
ShapeType::RoundConvexPolyhedron => co
.shape_mut()
.as_round_convex_polyhedron_mut()
.map(|b| b.border_radius = newBorderRadius),
#[cfg(feature = "dim2")]
ShapeType::RoundConvexPolygon => co
.shape_mut()
.as_round_convex_polygon_mut()
.map(|b| b.border_radius = newBorderRadius),
_ => None,
});
}
pub fn coVoxelData(&self, handle: FlatHandle) -> Option<Vec<i32>> {
self.map(handle, |co| {
let vox = co.shape().as_voxels()?;
let coords = vox
.voxels()
.filter_map(|vox| (!vox.state.is_empty()).then_some(vox.grid_coords))
.flat_map(|ids| ids.coords.data.0[0])
.collect();
Some(coords)
})
}
pub fn coVoxelSize(&self, handle: FlatHandle) -> Option<RawVector> {
self.map(handle, |co| {
let vox = co.shape().as_voxels()?;
Some(RawVector(vox.voxel_size()))
})
}
#[cfg(feature = "dim2")]
pub fn coSetVoxel(&mut self, handle: FlatHandle, ix: i32, iy: i32, filled: bool) {
self.map_mut(handle, |co| {
if let Some(vox) = co.shape_mut().as_voxels_mut() {
vox.set_voxel(Point::new(ix, iy), filled);
}
})
}
#[cfg(feature = "dim3")]
pub fn coSetVoxel(&mut self, handle: FlatHandle, ix: i32, iy: i32, iz: i32, filled: bool) {
self.map_mut(handle, |co| {
if let Some(vox) = co.shape_mut().as_voxels_mut() {
vox.set_voxel(Point::new(ix, iy, iz), filled);
}
})
}
#[cfg(feature = "dim2")]
pub fn coPropagateVoxelChange(
&mut self,
handle1: FlatHandle,
handle2: FlatHandle,
ix: i32,
iy: i32,
shift_x: i32,
shift_y: i32,
) {
self.map_pair_mut(handle1, handle2, |co1, co2| {
if let (Some(co1), Some(co2)) = (co1, co2) {
if let (Some(vox1), Some(vox2)) = (
co1.shape_mut().as_voxels_mut(),
co2.shape_mut().as_voxels_mut(),
) {
vox1.propagate_voxel_change(
vox2,
Point::new(ix, iy),
Vector::new(shift_x, shift_y),
);
}
}
})
}
#[cfg(feature = "dim3")]
pub fn coPropagateVoxelChange(
&mut self,
handle1: FlatHandle,
handle2: FlatHandle,
ix: i32,
iy: i32,
iz: i32,
shift_x: i32,
shift_y: i32,
shift_z: i32,
) {
self.map_pair_mut(handle1, handle2, |co1, co2| {
if let (Some(co1), Some(co2)) = (co1, co2) {
if let (Some(vox1), Some(vox2)) = (
co1.shape_mut().as_voxels_mut(),
co2.shape_mut().as_voxels_mut(),
) {
vox1.propagate_voxel_change(
vox2,
Point::new(ix, iy, iz),
Vector::new(shift_x, shift_y, shift_z),
);
}
}
})
}
#[cfg(feature = "dim2")]
pub fn coCombineVoxelStates(
&mut self,
handle1: FlatHandle,
handle2: FlatHandle,
shift_x: i32,
shift_y: i32,
) {
self.map_pair_mut(handle1, handle2, |co1, co2| {
if let (Some(co1), Some(co2)) = (co1, co2) {
if let (Some(vox1), Some(vox2)) = (
co1.shape_mut().as_voxels_mut(),
co2.shape_mut().as_voxels_mut(),
) {
vox1.combine_voxel_states(vox2, Vector::new(shift_x, shift_y));
}
}
})
}
#[cfg(feature = "dim3")]
pub fn coCombineVoxelStates(
&mut self,
handle1: FlatHandle,
handle2: FlatHandle,
shift_x: i32,
shift_y: i32,
shift_z: i32,
) {
self.map_pair_mut(handle1, handle2, |co1, co2| {
if let (Some(co1), Some(co2)) = (co1, co2) {
if let (Some(vox1), Some(vox2)) = (
co1.shape_mut().as_voxels_mut(),
co2.shape_mut().as_voxels_mut(),
) {
vox1.combine_voxel_states(vox2, Vector::new(shift_x, shift_y, shift_z));
}
}
})
}
/// The vertices of this triangle mesh, polyline, convex polyhedron, segment, triangle or convex polyhedron, if it is one.
pub fn coVertices(&self, handle: FlatHandle) -> Option<Vec<f32>> {
let flatten =
|vertices: &[Point<f32>]| vertices.iter().flat_map(|p| p.iter()).copied().collect();
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::TriMesh => co.shape().as_trimesh().map(|t| flatten(t.vertices())),
#[cfg(feature = "dim2")]
ShapeType::Polyline => co.shape().as_polyline().map(|p| flatten(p.vertices())),
#[cfg(feature = "dim3")]
ShapeType::ConvexPolyhedron => co
.shape()
.as_convex_polyhedron()
.map(|p| flatten(p.points())),
#[cfg(feature = "dim3")]
ShapeType::RoundConvexPolyhedron => co
.shape()
.as_round_convex_polyhedron()
.map(|p| flatten(p.inner_shape.points())),
#[cfg(feature = "dim2")]
ShapeType::ConvexPolygon => co.shape().as_convex_polygon().map(|p| flatten(p.points())),
#[cfg(feature = "dim2")]
ShapeType::RoundConvexPolygon => co
.shape()
.as_round_convex_polygon()
.map(|p| flatten(p.inner_shape.points())),
ShapeType::Segment => co.shape().as_segment().map(|s| flatten(&[s.a, s.b])),
ShapeType::RoundTriangle => co
.shape()
.as_round_triangle()
.map(|t| flatten(&[t.inner_shape.a, t.inner_shape.b, t.inner_shape.c])),
ShapeType::Triangle => co.shape().as_triangle().map(|t| flatten(&[t.a, t.b, t.c])),
_ => None,
})
}
/// The indices of this triangle mesh, polyline, or convex polyhedron, if it is one.
pub fn coIndices(&self, handle: FlatHandle) -> Option<Vec<u32>> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::TriMesh => co
.shape()
.as_trimesh()
.map(|t| t.indices().iter().flat_map(|p| p.iter()).copied().collect()),
ShapeType::Polyline => co
.shape()
.as_polyline()
.map(|p| p.indices().iter().flat_map(|p| p.iter()).copied().collect()),
#[cfg(feature = "dim3")]
ShapeType::ConvexPolyhedron => co.shape().as_convex_polyhedron().map(|p| {
// TODO: avoid the `.to_trimesh()`.
p.to_trimesh()
.1
.iter()
.flat_map(|p| p.iter())
.copied()
.collect()
}),
#[cfg(feature = "dim3")]
ShapeType::RoundConvexPolyhedron => co.shape().as_round_convex_polyhedron().map(|p| {
// TODO: avoid the `.to_trimesh()`.
p.inner_shape
.to_trimesh()
.1
.iter()
.flat_map(|p| p.iter())
.copied()
.collect()
}),
_ => None,
})
}
pub fn coTriMeshFlags(&self, handle: FlatHandle) -> Option<u32> {
self.map(handle, |co| {
co.shape().as_trimesh().map(|tri| tri.flags().bits() as u32)
})
}
#[cfg(feature = "dim3")]
pub fn coHeightFieldFlags(&self, handle: FlatHandle) -> Option<u32> {
self.map(handle, |co| {
co.shape()
.as_heightfield()
.map(|hf| hf.flags().bits() as u32)
})
}
/// The height of this heightfield if it is one.
pub fn coHeightfieldHeights(&self, handle: FlatHandle) -> Option<Vec<f32>> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::HeightField => co
.shape()
.as_heightfield()
.map(|h| h.heights().as_slice().to_vec()),
_ => None,
})
}
/// The scaling factor applied of this heightfield if it is one.
pub fn coHeightfieldScale(&self, handle: FlatHandle) -> Option<RawVector> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::HeightField => co.shape().as_heightfield().map(|h| RawVector(*h.scale())),
_ => None,
})
}
/// The number of rows on this heightfield's height matrix, if it is one.
#[cfg(feature = "dim3")]
pub fn coHeightfieldNRows(&self, handle: FlatHandle) -> Option<usize> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::HeightField => co.shape().as_heightfield().map(|h| h.nrows()),
_ => None,
})
}
/// The number of columns on this heightfield's height matrix, if it is one.
#[cfg(feature = "dim3")]
pub fn coHeightfieldNCols(&self, handle: FlatHandle) -> Option<usize> {
self.map(handle, |co| match co.shape().shape_type() {
ShapeType::HeightField => co.shape().as_heightfield().map(|h| h.ncols()),
_ => None,
})
}
/// The unique integer identifier of the collider this collider is attached to.
pub fn coParent(&self, handle: FlatHandle) -> Option<FlatHandle> {
self.map(handle, |co| co.parent().map(|p| utils::flat_handle(p.0)))
}
pub fn coSetEnabled(&mut self, handle: FlatHandle, enabled: bool) {
self.map_mut(handle, |co| co.set_enabled(enabled))
}
pub fn coIsEnabled(&self, handle: FlatHandle) -> bool {
self.map(handle, |co| co.is_enabled())
}
pub fn coSetContactSkin(&mut self, handle: FlatHandle, contact_skin: f32) {
self.map_mut(handle, |co| co.set_contact_skin(contact_skin))
}
pub fn coContactSkin(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.contact_skin())
}
/// The friction coefficient of this collider.
pub fn coFriction(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.material().friction)
}
/// The restitution coefficient of this collider.
pub fn coRestitution(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.material().restitution)
}
/// The density of this collider.
pub fn coDensity(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.density())
}
/// The mass of this collider.
pub fn coMass(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.mass())
}
/// The volume of this collider.
pub fn coVolume(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.volume())
}
/// The collision groups of this collider.
pub fn coCollisionGroups(&self, handle: FlatHandle) -> u32 {
self.map(handle, |co| {
super::pack_interaction_groups(co.collision_groups())
})
}
/// The solver groups of this collider.
pub fn coSolverGroups(&self, handle: FlatHandle) -> u32 {
self.map(handle, |co| {
super::pack_interaction_groups(co.solver_groups())
})
}
/// The physics hooks enabled for this collider.
pub fn coActiveHooks(&self, handle: FlatHandle) -> u32 {
self.map(handle, |co| co.active_hooks().bits())
}
/// The collision types enabled for this collider.
pub fn coActiveCollisionTypes(&self, handle: FlatHandle) -> u16 {
self.map(handle, |co| co.active_collision_types().bits())
}
/// The events enabled for this collider.
pub fn coActiveEvents(&self, handle: FlatHandle) -> u32 {
self.map(handle, |co| co.active_events().bits())
}
/// The total force magnitude beyond which a contact force event can be emitted.
pub fn coContactForceEventThreshold(&self, handle: FlatHandle) -> f32 {
self.map(handle, |co| co.contact_force_event_threshold())
}
pub fn coContainsPoint(&self, handle: FlatHandle, point: &RawVector) -> bool {
self.map(handle, |co| {
co.shared_shape()
.containsPoint(co.position(), &point.0.into())
})
}
pub fn coCastShape(
&self,
handle: FlatHandle,
colliderVel: &RawVector,
shape2: &RawShape,
shape2Pos: &RawVector,
shape2Rot: &RawRotation,
shape2Vel: &RawVector,
target_distance: f32,
maxToi: f32,
stop_at_penetration: bool,
) -> Option<RawShapeCastHit> {
let pos2 = Isometry::from_parts(shape2Pos.0.into(), shape2Rot.0);
self.map(handle, |co| {
let pos1 = co.position();
co.shared_shape().castShape(
pos1,
&colliderVel.0.into(),
&*shape2.0,
&pos2,
&shape2Vel.0.into(),
target_distance,
maxToi,
stop_at_penetration,
)
})
}
pub fn coCastCollider(
&self,
handle: FlatHandle,
collider1Vel: &RawVector,
collider2handle: FlatHandle,
collider2Vel: &RawVector,
target_distance: f32,
max_toi: f32,
stop_at_penetration: bool,
) -> Option<RawColliderShapeCastHit> {
let handle2 = utils::collider_handle(collider2handle);
let co2 = self
.0
.get(handle2)
.expect("Invalid Collider reference. It may have been removed from the physics World.");
self.map(handle, |co| {
query::cast_shapes(
co.position(),
&collider1Vel.0,
co.shape(),
co2.position(),
&collider2Vel.0,
co2.shape(),
ShapeCastOptions {
max_time_of_impact: max_toi,
stop_at_penetration,
target_distance,
compute_impact_geometry_on_penetration: true,
},
)
.unwrap_or(None)
.map_or(None, |hit| {
Some(RawColliderShapeCastHit {
handle: handle2,
hit,
})
})
})
}
pub fn coIntersectsShape(
&self,
handle: FlatHandle,
shape2: &RawShape,
shapePos2: &RawVector,
shapeRot2: &RawRotation,
) -> bool {
let pos2 = Isometry::from_parts(shapePos2.0.into(), shapeRot2.0);
self.map(handle, |co| {
co.shared_shape()
.intersectsShape(co.position(), &*shape2.0, &pos2)
})
}
pub fn coContactShape(
&self,
handle: FlatHandle,
shape2: &RawShape,
shapePos2: &RawVector,
shapeRot2: &RawRotation,
prediction: f32,
) -> Option<RawShapeContact> {
let pos2 = Isometry::from_parts(shapePos2.0.into(), shapeRot2.0);
self.map(handle, |co| {
co.shared_shape()
.contactShape(co.position(), &*shape2.0, &pos2, prediction)
})
}
pub fn coContactCollider(
&self,
handle: FlatHandle,
collider2handle: FlatHandle,
prediction: f32,
) -> Option<RawShapeContact> {
let co2 = self
.0
.get(utils::collider_handle(collider2handle))
.expect("Invalid Collider reference. It may have been removed from the physics World.");
self.map(handle, |co| {
query::contact(
co.position(),
co.shape(),
&co2.position(),
co2.shape(),
prediction,
)
.ok()
.flatten()
.map(|contact| RawShapeContact { contact })
})
}
pub fn coProjectPoint(
&self,
handle: FlatHandle,
point: &RawVector,
solid: bool,
) -> RawPointProjection {
self.map(handle, |co| {
co.shared_shape()
.projectPoint(co.position(), &point.0.into(), solid)
})
}
pub fn coIntersectsRay(
&self,
handle: FlatHandle,
rayOrig: &RawVector,
rayDir: &RawVector,
maxToi: f32,
) -> bool {
self.map(handle, |co| {
co.shared_shape().intersectsRay(
co.position(),
rayOrig.0.into(),
rayDir.0.into(),
maxToi,
)
})
}
pub fn coCastRay(
&self,
handle: FlatHandle,
rayOrig: &RawVector,
rayDir: &RawVector,
maxToi: f32,
solid: bool,
) -> f32 {
self.map(handle, |co| {
co.shared_shape().castRay(
co.position(),
rayOrig.0.into(),
rayDir.0.into(),
maxToi,
solid,
)
})
}
pub fn coCastRayAndGetNormal(
&self,
handle: FlatHandle,
rayOrig: &RawVector,
rayDir: &RawVector,
maxToi: f32,
solid: bool,
) -> Option<RawRayIntersection> {
self.map(handle, |co| {
co.shared_shape().castRayAndGetNormal(
co.position(),
rayOrig.0.into(),
rayDir.0.into(),
maxToi,
solid,
)
})
}
pub fn coSetSensor(&mut self, handle: FlatHandle, is_sensor: bool) {
self.map_mut(handle, |co| co.set_sensor(is_sensor))
}
pub fn coSetRestitution(&mut self, handle: FlatHandle, restitution: f32) {
self.map_mut(handle, |co| co.set_restitution(restitution))
}
pub fn coSetFriction(&mut self, handle: FlatHandle, friction: f32) {
self.map_mut(handle, |co| co.set_friction(friction))
}
pub fn coFrictionCombineRule(&self, handle: FlatHandle) -> u32 {
self.map(handle, |co| co.friction_combine_rule() as u32)
}
pub fn coSetFrictionCombineRule(&mut self, handle: FlatHandle, rule: u32) {
let rule = super::combine_rule_from_u32(rule);
self.map_mut(handle, |co| co.set_friction_combine_rule(rule))
}
pub fn coRestitutionCombineRule(&self, handle: FlatHandle) -> u32 {
self.map(handle, |co| co.restitution_combine_rule() as u32)
}
pub fn coSetRestitutionCombineRule(&mut self, handle: FlatHandle, rule: u32) {
let rule = super::combine_rule_from_u32(rule);
self.map_mut(handle, |co| co.set_restitution_combine_rule(rule))
}
pub fn coSetCollisionGroups(&mut self, handle: FlatHandle, groups: u32) {
let groups = super::unpack_interaction_groups(groups);
self.map_mut(handle, |co| co.set_collision_groups(groups))
}
pub fn coSetSolverGroups(&mut self, handle: FlatHandle, groups: u32) {
let groups = super::unpack_interaction_groups(groups);
self.map_mut(handle, |co| co.set_solver_groups(groups))
}
pub fn coSetActiveHooks(&mut self, handle: FlatHandle, hooks: u32) {
let hooks = ActiveHooks::from_bits(hooks).unwrap_or(ActiveHooks::empty());
self.map_mut(handle, |co| co.set_active_hooks(hooks));
}
pub fn coSetActiveEvents(&mut self, handle: FlatHandle, events: u32) {
let events = ActiveEvents::from_bits(events).unwrap_or(ActiveEvents::empty());
self.map_mut(handle, |co| co.set_active_events(events))
}
pub fn coSetActiveCollisionTypes(&mut self, handle: FlatHandle, types: u16) {
let types = ActiveCollisionTypes::from_bits(types).unwrap_or(ActiveCollisionTypes::empty());
self.map_mut(handle, |co| co.set_active_collision_types(types));
}
pub fn coSetShape(&mut self, handle: FlatHandle, shape: &RawShape) {
self.map_mut(handle, |co| co.set_shape(shape.0.clone()));
}
pub fn coSetContactForceEventThreshold(&mut self, handle: FlatHandle, threshold: f32) {
self.map_mut(handle, |co| co.set_contact_force_event_threshold(threshold))
}
pub fn coSetDensity(&mut self, handle: FlatHandle, density: f32) {
self.map_mut(handle, |co| co.set_density(density))
}
pub fn coSetMass(&mut self, handle: FlatHandle, mass: f32) {
self.map_mut(handle, |co| co.set_mass(mass))
}
#[cfg(feature = "dim3")]
pub fn coSetMassProperties(
&mut self,
handle: FlatHandle,
mass: f32,
centerOfMass: &RawVector,
principalAngularInertia: &RawVector,
angularInertiaFrame: &RawRotation,
) {
self.map_mut(handle, |co| {
let mprops = MassProperties::with_principal_inertia_frame(
centerOfMass.0.into(),
mass,
principalAngularInertia.0,
angularInertiaFrame.0,
);
co.set_mass_properties(mprops)
})
}
#[cfg(feature = "dim2")]
pub fn coSetMassProperties(
&mut self,
handle: FlatHandle,
mass: f32,
centerOfMass: &RawVector,
principalAngularInertia: f32,
) {
self.map_mut(handle, |co| {
let props = MassProperties::new(centerOfMass.0.into(), mass, principalAngularInertia);
co.set_mass_properties(props)
})
}
}