feat: migrate to glam whenever relevant + migrate testbed to kiss3d instead of bevy + release v0.32.0 (#909)

* feat: migrate to glam whenever relevant + migrate testbed to kiss3d instead of bevy

* chore: update changelog

* Fix warnings and tests

* Release v0.32.0
This commit is contained in:
Sébastien Crozet
2026-01-09 17:26:36 +01:00
committed by GitHub
parent 48de83817e
commit 0b7c3b34ec
265 changed files with 8501 additions and 8575 deletions

View File

@@ -1,7 +1,8 @@
#![allow(dead_code)]
use crate::ui::egui::emath::OrderedFloat;
use na::{Isometry3, Matrix4, Point3, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
use glamx::{Pose3, Vec3};
use na::{Isometry3, Matrix4, Point3, Quaternion, Unit, UnitQuaternion, Vector3};
use physx::cooking::{
ConvexMeshCookingResult, PxConvexMeshDesc, PxCookingParams, PxHeightFieldDesc,
PxTriangleMeshDesc, TriangleMeshCookingResult,
@@ -28,7 +29,7 @@ trait IntoNa {
fn into_na(self) -> Self::Output;
}
impl IntoNa for glam::Mat4 {
impl IntoNa for glamx::Mat4 {
type Output = Matrix4<f32>;
fn into_na(self) -> Self::Output {
self.to_cols_array_2d().into()
@@ -85,6 +86,20 @@ impl IntoPhysx for UnitQuaternion<f32> {
}
}
impl IntoPhysx for glamx::Vec3 {
type Output = PxVec3;
fn into_physx(self) -> Self::Output {
PxVec3::new(self.x, self.y, self.z)
}
}
impl IntoPhysx for glamx::Quat {
type Output = PxQuat;
fn into_physx(self) -> Self::Output {
PxQuat::new(self.x, self.y, self.z, self.w)
}
}
impl IntoPhysx for Isometry3<f32> {
type Output = PxTransform;
fn into_physx(self) -> Self::Output {
@@ -95,36 +110,46 @@ impl IntoPhysx for Isometry3<f32> {
}
}
impl IntoPhysx for glamx::Pose3 {
type Output = PxTransform;
fn into_physx(self) -> Self::Output {
PxTransform::from_translation_rotation(
&self.translation.into_physx(),
&self.rotation.into_physx(),
)
}
}
trait IntoGlam {
type Output;
fn into_glam(self) -> Self::Output;
}
impl IntoGlam for Vector3<f32> {
type Output = glam::Vec3;
type Output = glamx::Vec3;
fn into_glam(self) -> Self::Output {
glam::vec3(self.x, self.y, self.z)
glamx::vec3(self.x, self.y, self.z)
}
}
impl IntoGlam for Point3<f32> {
type Output = glam::Vec3;
type Output = glamx::Vec3;
fn into_glam(self) -> Self::Output {
glam::vec3(self.x, self.y, self.z)
glamx::vec3(self.x, self.y, self.z)
}
}
impl IntoGlam for Matrix4<f32> {
type Output = glam::Mat4;
type Output = glamx::Mat4;
fn into_glam(self) -> Self::Output {
glam::Mat4::from_cols_array_2d(&self.into())
glamx::Mat4::from_cols_array_2d(&self.into())
}
}
impl IntoGlam for Isometry3<f32> {
type Output = glam::Mat4;
type Output = glamx::Mat4;
fn into_glam(self) -> Self::Output {
glam::Mat4::from_cols_array_2d(&self.to_homogeneous().into())
glamx::Mat4::from_cols_array_2d(&self.to_homogeneous().into())
}
}
@@ -150,7 +175,7 @@ impl Drop for PhysxWorld {
impl PhysxWorld {
#[profiling::function]
pub fn from_rapier(
gravity: Vector3<f32>,
gravity: Vec3,
integration_parameters: &IntegrationParameters,
bodies: &RigidBodySet,
colliders: &ColliderSet,
@@ -522,14 +547,17 @@ impl PhysxWorld {
}
pub fn sync(&mut self, bodies: &mut RigidBodySet, colliders: &mut ColliderSet) {
let mut sync_pos = |handle: &RigidBodyHandle, pos: Isometry3<f32>| {
let mut sync_pos = |handle: &RigidBodyHandle, pos: Pose3| {
let rb = &mut bodies[*handle];
rb.set_position(pos, false);
for coll_handle in rb.colliders() {
let collider = &mut colliders[*coll_handle];
collider.set_position(
pos * collider.position_wrt_parent().copied().unwrap_or(na::one()),
pos * collider
.position_wrt_parent()
.copied()
.unwrap_or(Pose3::IDENTITY),
);
}
};
@@ -537,7 +565,7 @@ impl PhysxWorld {
for actor in self.scene.as_mut().unwrap().get_dynamic_actors() {
let handle = actor.get_user_data();
let pos = actor.get_global_pose().into_na();
sync_pos(handle, pos);
sync_pos(handle, pos.into());
}
/*
@@ -559,8 +587,11 @@ fn physx_collider_from_rapier_collider(
physics: &mut PxPhysicsFoundation,
collider: &Collider,
materials_cache: &mut HashMap<[OrderedFloat<f32>; 2], Owner<PxMaterial>>,
) -> Option<(Owner<PxShape>, Isometry3<f32>)> {
let mut local_pose = collider.position_wrt_parent().copied().unwrap_or(na::one());
) -> Option<(Owner<PxShape>, Pose3)> {
let mut local_pose = collider
.position_wrt_parent()
.copied()
.unwrap_or(Pose3::IDENTITY);
let cooking_params = PxCookingParams::new(physics).unwrap();
let shape = collider.shape();
let shape_flags = if collider.is_sensor() {
@@ -604,20 +635,19 @@ fn physx_collider_from_rapier_collider(
dir = -dir;
}
let rot = UnitQuaternion::rotation_between(&Vector3::x(), &dir);
local_pose = local_pose
* Translation3::from(center.coords)
* rot.unwrap_or(UnitQuaternion::identity());
let rot = glamx::Quat::from_rotation_arc(Vec3::X, dir);
local_pose = local_pose.prepend_translation(center) * rot;
let geometry = PxCapsuleGeometry::new(capsule.radius, capsule.half_height());
physics.create_shape(&geometry, materials, true, shape_flags, ())
} else if let Some(heightfield) = shape.as_heightfield() {
let heights = heightfield.heights();
let scale = heightfield.scale();
local_pose = local_pose * Translation3::new(-scale.x / 2.0, 0.0, -scale.z / 2.0);
local_pose = local_pose.prepend_translation(Vec3::new(-scale.x / 2.0, 0.0, -scale.z / 2.0));
const Y_FACTOR: f32 = 1_000f32;
let mut heightfield_desc;
unsafe {
let samples: Vec<_> = heights
.data()
.iter()
.map(|h| PxHeightFieldSample {
height: (*h * Y_FACTOR) as i16,