Rust 3D碰撞检测库parry3d的使用,parry3d提供高性能的3D几何形状碰撞检测与物理模拟功能
2D Documentation | 3D Documentation | User Guide
什么是Parry?
Parry是一套2维和3维几何与碰撞检测库。
这些库包括parry2d
、parry3d
、parry2d-f64
和parry3d-f64
。它们由
Dimforge组织使用Rust编程语言编写。它永远免费
且开源!我们定期在我们的博客上更新我们的进展。
资源与讨论
- Dimforge:查看我们正在开发的所有开源项目!关注我们的公告 在我们的博客上。
- 用户指南:(进行中)通过阅读官方用户指南学习在您的项目中使用Parry。
- Discord:来和我们聊天,获取帮助,提出功能建议,在Discord上!
// 完整示例代码:使用parry3d进行3D碰撞检测
use parry3d::math::Vector;
use parry3d::shape::{Ball, Cuboid};
use parry3d::query::details::ContactManifold;
fn main() {
// 创建一个球体,半径为1.0
let ball = Ball::new(1.0);
// 创建一个立方体,半尺寸为(1.0, 1.0, 1.0)
let cuboid = Cuboid::new(Vector::new(1.0, 1.0, 1.0));
// 定义球体的位置和方向(单位四元数表示无旋转)
let ball_pos = Vector::new(0.0, 0.0, 0.0);
let ball_rot = Vector::zeros(); // 无旋转
// 定义立方体的位置和方向
let cuboid_pos = Vector::new(2.0, 0.0, 0.0); // 在x轴上偏移2个单位
let cuboid_rot = Vector::zeros(); // 无旋转
// 检测碰撞
let contact = parry3d::query::contact(
&ball_pos, &ball_rot, &ball,
&cuboid_pos, &cuboid_rot, &cuboid,
0.0 // 预测距离
);
// 输出碰撞结果
match contact {
Some(contact) => {
println!("碰撞检测到!");
println!("碰撞点: {:?}", contact.point1);
println!("法向量: {:?}", contact.normal1);
println!("穿透深度: {}", contact.dist);
}
None => {
println!("未检测到碰撞");
}
}
}
// 完整示例代码:使用parry2d进行2D碰撞检测
use parry2d::math::Vector;
use parry2d::shape::{Ball, Cuboid};
use parry2d::query::contact;
fn main() {
// 创建一个圆形,半径为1.0
let circle = Ball::new(1.0);
// 创建一个矩形,半尺寸为(1.0, 1.0)
let rectangle = Cuboid::new(Vector::new(1.0, 1.0));
// 定义圆形的位置和角度(无旋转)
let circle_pos = Vector::new(0.0, 0.0);
let circle_rot = 0.0; // 无旋转
// 定义矩形的位置和角度
let rectangle_pos = Vector::new(1.5, 0.0); // 在x轴上偏移1.5个单位
let rectangle_rot = 0.0; // 无旋转
// 检测碰撞
let contact = contact(
&circle_pos, &circle_rot, &circle,
&rectangle_pos, &rectangle_rot, &rectangle,
0.0 // 预测距离
);
// 输出碰撞结果
match contact {
Some(contact) => {
println!("2D碰撞检测到!");
println!("碰撞点: {:?}", contact.point1);
println!("法向量: {:?}", contact.normal1);
println!("穿透深度: {}", contact.dist);
}
None => {
println!("未检测到2D碰撞");
}
}
}
1 回复
parry3d:高性能Rust 3D碰撞检测与物理模拟库
简介
parry3d是一个专为Rust语言设计的高性能3D碰撞检测和物理模拟库。它提供了多种几何形状的碰撞检测、接触点计算、距离查询以及物理模拟功能,特别适合游戏开发、机器人仿真和计算机图形学应用。
主要特性
- 支持多种3D几何形状(球体、立方体、胶囊体、凸多面体等)
- 高效的碰撞检测算法
- 精确的接触点生成
- 距离和最近点计算
- 连续碰撞检测(CCD)
- 物理模拟集成
安装方法
在Cargo.toml中添加依赖:
[dependencies]
parry3d = "0.13"
nalgebra = "0.32"
基础使用方法
1. 基本碰撞检测
use parry3d::query;
use parry3d::shape::{Ball, Cuboid};
use nalgebra::Vector3;
fn main() {
// 创建几何形状
let ball = Ball::new(1.0);
let cube = Cuboid::new(Vector3::new(1.0, 1.0, 1.0));
// 设置变换
let ball_pos = na::Isometry3::translation(0.0, 0.0, 0.0);
let cube_pos = na::Isometry3::translation(2.0, 0.0, 0.0);
// 检测碰撞
let collision = query::contact(
&ball_pos,
&ball,
&cube_pos,
&cube,
0.0
);
if let Some(contact) = collision {
println!("碰撞发生!穿透深度: {}", contact.dist);
}
}
2. 距离计算
use parry3d::query::distance;
fn compute_distance() {
let sphere1 = Ball::new(1.0);
let sphere2 = Ball::new(0.5);
let pos1 = na::Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = na::Isometry3::translation(3.0, 0.0, 0.0);
let dist = distance(&pos1, &sphere1, &pos2, &sphere2).unwrap();
println!("两球体距离: {}", dist);
}
3. 物理模拟集成示例
use parry3d::dynamics::{RigidBody, RigidBodySet};
use parry3d::geometry::{Collider, ColliderSet};
use parry3d::pipeline::PhysicsPipeline;
fn physics_simulation() {
let mut rigid_bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let mut pipeline = PhysicsPipeline::new();
// 创建刚体
let rigid_body = RigidBody::new_dynamic(
na::Isometry3::identity(),
Vector3::zeros(),
Vector3::zeros(),
1.0
);
let handle = rigid_bodies.insert(rigid_body);
// 添加碰撞体
let collider = Collider::new(Ball::new(0.5));
colliders.insert(collider, handle, &mut rigid_bodies);
}
高级功能
连续碰撞检测
use parry3d::query::time_of_impact;
fn ccd_example() {
let shape = Ball::new(0.5);
let pos1 = na::Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = na::Isometry3::translation(10.0, 0.0, 0.0);
let toi = time_of_impact(
&pos1,
&Vector3::x() * 10.0, // 速度
&shape,
&pos2,
&Vector3::zeros(),
&shape,
1.0
);
if let Some(time) = toi {
println!("碰撞将在 {} 秒后发生", time);
}
}
完整示例demo
use parry3d::query::{contact, distance, time_of_impact};
use parry3d::shape::{Ball, Cuboid};
use parry3d::dynamics::{RigidBody, RigidBodySet};
use parry3d::geometry::{Collider, ColliderSet};
use parry3d::pipeline::PhysicsPipeline;
use nalgebra::{Vector3, Isometry3};
fn main() {
// 示例1: 基本碰撞检测
println!("=== 基本碰撞检测示例 ===");
let ball = Ball::new(1.0);
let cube = Cuboid::new(Vector3::new(1.0, 1.0, 1.0));
let ball_pos = Isometry3::translation(0.0, 0.0, 0.0);
let cube_pos = Isometry3::translation(2.0, 0.0, 0.0);
let collision = contact(&ball_pos, &ball, &cube_pos, &cube, 0.0);
if let Some(contact) = collision {
println!("碰撞发生!穿透深度: {}", contact.dist);
} else {
println!("未发生碰撞");
}
// 示例2: 距离计算
println!("\n=== 距离计算示例 ===");
let sphere1 = Ball::new(1.0);
let sphere2 = Ball::new(0.5);
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(3.0, 0.0, 0.0);
if let Ok(dist) = distance(&pos1, &sphere1, &pos2, &sphere2) {
println!("两球体距离: {}", dist);
}
// 示例3: 连续碰撞检测
println!("\n=== 连续碰撞检测示例 ===");
let shape = Ball::new(0.5);
let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
let pos2 = Isometry3::translation(10.0, 0.0, 0.0);
let toi = time_of_impact(
&pos1,
&Vector3::x() * 10.0,
&shape,
&pos2,
&Vector3::zeros(),
&shape,
1.0
);
if let Some(time) = toi {
println!("碰撞将在 {} 秒后发生", time);
}
// 示例4: 物理模拟集成
println!("\n=== 物理模拟集成示例 ===");
let mut rigid_bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let mut pipeline = PhysicsPipeline::new();
// 创建动态刚体
let rigid_body = RigidBody::new_dynamic(
Isometry3::identity(),
Vector3::zeros(),
Vector3::zeros(),
1.0
);
let handle = rigid_bodies.insert(rigid_body);
// 添加球体碰撞体
let collider = Collider::new(Ball::new(0.5));
colliders.insert(collider, handle, &mut rigid_bodies);
println!("物理场景创建完成,包含 {} 个刚体", rigid_bodies.len());
}
性能建议
- 对于静态几何体,使用
Collider
缓存查询结果 - 批量处理碰撞检测以提高性能
- 合理使用空间划分数据结构进行优化
注意事项
- 确保正确管理几何形状的生命周期
- 注意数值精度问题,特别是在处理小尺寸物体时
- 定期更新到最新版本以获得性能改进和bug修复
parry3d提供了强大而灵活的3D碰撞检测功能,通过合理的API设计和高效的算法实现,能够满足大多数3D应用的物理模拟需求。