mirror of
https://github.com/FyroxEngine/Fyrox.git
synced 2026-10-12 02:02:20 +00:00
migrate to rapier 0.32
This commit is contained in:
@@ -14,6 +14,6 @@ readme = "README.md"
|
||||
include = ["/src/**/*", "/Cargo.toml", "/LICENSE", "/README.md"]
|
||||
|
||||
[dependencies]
|
||||
nalgebra = { version = "0.34", features = ["bytemuck"] }
|
||||
nalgebra = { version = "0.34", features = ["bytemuck", "convert-glam030"] }
|
||||
fxhash = "0.2.1"
|
||||
rand = "0.8"
|
||||
|
||||
@@ -21,7 +21,7 @@ base64 = "0.22.1"
|
||||
byteorder = "1.4.3"
|
||||
rand = "0.8"
|
||||
memoffset = "0.9.0"
|
||||
nalgebra = { version = "0.34", features = ["bytemuck"] }
|
||||
nalgebra = { version = "0.34", features = ["bytemuck", "convert-glam030"] }
|
||||
arrayvec = "0.7.2"
|
||||
futures = { version = "0.3.17", features = ["thread-pool"] }
|
||||
uuid = { version = "1", features = ["v4", "js"] }
|
||||
|
||||
@@ -27,8 +27,8 @@ fyrox-graphics-gl = { path = "../fyrox-graphics-gl", version = "1.0.0" }
|
||||
fyrox-texture = { path = "../fyrox-texture", version = "1.0.0" }
|
||||
fyrox-autotile = { path = "../fyrox-autotile", version = "1.0.0" }
|
||||
fyrox-material = { path = "../fyrox-material", version = "1.0.0" }
|
||||
rapier2d = { version = "0.31", features = ["debug-render"] }
|
||||
rapier3d = { version = "0.31", features = ["debug-render"] }
|
||||
rapier2d = { version = "0.32", features = ["debug-render", ] }
|
||||
rapier3d = { version = "0.32", features = ["debug-render"] }
|
||||
image = { version = "0.25.1", default-features = false, features = ["gif", "jpeg", "png", "tga", "tiff", "bmp"] }
|
||||
inflate = "0.4.5"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
@@ -1023,12 +1023,15 @@ impl NodeTrait for Collider {
|
||||
fn on_local_transform_changed(&self, context: &mut SyncContext) {
|
||||
if self.native.get() != ColliderHandle::invalid() {
|
||||
if let Some(native) = context.physics.colliders.get_mut(self.native.get()) {
|
||||
native.set_position_wrt_parent(Isometry3 {
|
||||
rotation: **self.local_transform().rotation(),
|
||||
translation: Translation3 {
|
||||
vector: **self.local_transform().position(),
|
||||
},
|
||||
});
|
||||
native.set_position_wrt_parent(
|
||||
Isometry3 {
|
||||
rotation: **self.local_transform().rotation(),
|
||||
translation: Translation3 {
|
||||
vector: **self.local_transform().position(),
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ use crate::core::{
|
||||
color::{Color, Hsl},
|
||||
math::{aabb::AxisAlignedBoundingBox, frustum::Frustum, Matrix4Ext},
|
||||
};
|
||||
use rapier2d::math::Vector;
|
||||
use rapier2d::pipeline::{DebugColor, DebugRenderObject};
|
||||
use std::ops::Range;
|
||||
|
||||
/// Colored line between two points.
|
||||
@@ -91,13 +93,7 @@ pub struct SceneDrawingContext {
|
||||
}
|
||||
|
||||
impl rapier2d::pipeline::DebugRenderBackend for SceneDrawingContext {
|
||||
fn draw_line(
|
||||
&mut self,
|
||||
_object: rapier2d::pipeline::DebugRenderObject,
|
||||
a: rapier2d::math::Point<rapier2d::math::Real>,
|
||||
b: rapier2d::math::Point<rapier2d::math::Real>,
|
||||
color: [f32; 4],
|
||||
) {
|
||||
fn draw_line(&mut self, _object: DebugRenderObject, a: Vector, b: Vector, color: DebugColor) {
|
||||
self.add_line(Line {
|
||||
begin: Vector3::new(a.x, a.y, 0.0),
|
||||
end: Vector3::new(b.x, b.y, 0.0),
|
||||
@@ -110,13 +106,13 @@ impl rapier3d::pipeline::DebugRenderBackend for SceneDrawingContext {
|
||||
fn draw_line(
|
||||
&mut self,
|
||||
_object: rapier3d::pipeline::DebugRenderObject,
|
||||
a: rapier3d::math::Point<rapier3d::math::Real>,
|
||||
b: rapier3d::math::Point<rapier3d::math::Real>,
|
||||
color: [f32; 4],
|
||||
a: rapier3d::math::Vector,
|
||||
b: rapier3d::math::Vector,
|
||||
color: rapier3d::pipeline::DebugColor,
|
||||
) {
|
||||
self.add_line(Line {
|
||||
begin: a.coords,
|
||||
end: b.coords,
|
||||
begin: a.into(),
|
||||
end: b.into(),
|
||||
color: Color::from(Hsl::new(color[0], color[1], color[2])),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -680,14 +680,17 @@ impl NodeTrait for Collider {
|
||||
fn on_local_transform_changed(&self, context: &mut SyncContext) {
|
||||
if self.native.get() != ColliderHandle::invalid() {
|
||||
if let Some(native) = context.physics2d.colliders.get_mut(self.native.get()) {
|
||||
native.set_position_wrt_parent(Isometry2 {
|
||||
rotation: UnitComplex::from_angle(
|
||||
self.local_transform().rotation().euler_angles().2,
|
||||
),
|
||||
translation: Translation2 {
|
||||
vector: self.local_transform().position().xy(),
|
||||
},
|
||||
});
|
||||
native.set_position_wrt_parent(
|
||||
Isometry2 {
|
||||
rotation: UnitComplex::from_angle(
|
||||
self.local_transform().rotation().euler_angles().2,
|
||||
),
|
||||
translation: Translation2 {
|
||||
vector: self.local_transform().position().xy(),
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
pub use rapier2d::geometry::shape::*;
|
||||
use rapier2d::math::{Pose2, Vec2};
|
||||
use rapier2d::parry::query::DefaultQueryDispatcher;
|
||||
use rapier2d::{
|
||||
dynamics::{
|
||||
@@ -256,15 +257,15 @@ impl ContactPair {
|
||||
.points
|
||||
.iter()
|
||||
.map(|p| ContactData {
|
||||
local_p1: p.local_p1.coords,
|
||||
local_p2: p.local_p2.coords,
|
||||
local_p1: p.local_p1.into(),
|
||||
local_p2: p.local_p2.into(),
|
||||
dist: p.dist,
|
||||
impulse: p.data.impulse,
|
||||
tangent_impulse: p.data.tangent_impulse.x,
|
||||
})
|
||||
.collect(),
|
||||
local_n1: m.local_n1,
|
||||
local_n2: m.local_n2,
|
||||
local_n1: m.local_n1.into(),
|
||||
local_n2: m.local_n2.into(),
|
||||
rigid_body1: m.data.rigid_body1.and_then(|h| {
|
||||
physics
|
||||
.bodies
|
||||
@@ -277,11 +278,11 @@ impl ContactPair {
|
||||
.get(h)
|
||||
.map(|b| Handle::decode_from_u128(b.user_data))
|
||||
})?,
|
||||
normal: m.data.normal,
|
||||
normal: m.data.normal.into(),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
has_any_active_contact: c.has_any_active_contact,
|
||||
has_any_active_contact: c.has_any_active_contact(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -337,8 +338,8 @@ fn convert_joint_params(
|
||||
};
|
||||
|
||||
let mut joint = GenericJointBuilder::new(locked_axis)
|
||||
.local_frame1(local_frame1)
|
||||
.local_frame2(local_frame2)
|
||||
.local_frame1(local_frame1.into())
|
||||
.local_frame2(local_frame2.into())
|
||||
.build();
|
||||
|
||||
match params {
|
||||
@@ -402,7 +403,7 @@ fn tile_map_to_collider_shape(
|
||||
}
|
||||
}
|
||||
|
||||
SharedShape::trimesh(vertices, triangles).ok()
|
||||
SharedShape::trimesh(vertices.into_iter().map(Vec2::from).collect(), triangles).ok()
|
||||
}
|
||||
|
||||
// Converts descriptor in a shared shape.
|
||||
@@ -413,22 +414,22 @@ fn collider_shape_into_native_shape(
|
||||
) -> Option<SharedShape> {
|
||||
match shape {
|
||||
ColliderShape::Ball(ball) => Some(SharedShape::ball(ball.radius)),
|
||||
ColliderShape::Cuboid(cuboid) => {
|
||||
Some(SharedShape(Arc::new(Cuboid::new(cuboid.half_extents))))
|
||||
}
|
||||
ColliderShape::Cuboid(cuboid) => Some(SharedShape(Arc::new(Cuboid::new(
|
||||
cuboid.half_extents.into(),
|
||||
)))),
|
||||
ColliderShape::Capsule(capsule) => Some(SharedShape::capsule(
|
||||
Point2::from(capsule.begin),
|
||||
Point2::from(capsule.end),
|
||||
capsule.begin.into(),
|
||||
capsule.end.into(),
|
||||
capsule.radius,
|
||||
)),
|
||||
ColliderShape::Segment(segment) => Some(SharedShape::segment(
|
||||
Point2::from(segment.begin),
|
||||
Point2::from(segment.end),
|
||||
segment.begin.into(),
|
||||
segment.end.into(),
|
||||
)),
|
||||
ColliderShape::Triangle(triangle) => Some(SharedShape::triangle(
|
||||
Point2::from(triangle.a),
|
||||
Point2::from(triangle.b),
|
||||
Point2::from(triangle.c),
|
||||
triangle.a.into(),
|
||||
triangle.b.into(),
|
||||
triangle.c.into(),
|
||||
)),
|
||||
ColliderShape::Trimesh(_) => {
|
||||
None // TODO
|
||||
@@ -675,7 +676,7 @@ impl PhysicsWorld {
|
||||
};
|
||||
|
||||
self.pipeline.step(
|
||||
&self.gravity,
|
||||
(*self.gravity).into(),
|
||||
&integration_parameters,
|
||||
&mut self.islands,
|
||||
&mut self.broad_phase,
|
||||
@@ -774,16 +775,17 @@ impl PhysicsWorld {
|
||||
|
||||
query_buffer.clear();
|
||||
let ray = Ray::new(
|
||||
opts.ray_origin,
|
||||
opts.ray_origin.into(),
|
||||
opts.ray_direction
|
||||
.try_normalize(f32::EPSILON)
|
||||
.unwrap_or_default(),
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
);
|
||||
for (_, collider, intersection) in query.intersect_ray(ray, opts.max_len, true) {
|
||||
query_buffer.push(Intersection {
|
||||
collider: Handle::decode_from_u128(collider.user_data),
|
||||
normal: intersection.normal,
|
||||
position: ray.point_at(intersection.time_of_impact),
|
||||
normal: intersection.normal.into(),
|
||||
position: ray.point_at(intersection.time_of_impact).into(),
|
||||
feature: intersection.feature.into(),
|
||||
toi: intersection.time_of_impact,
|
||||
});
|
||||
@@ -882,16 +884,16 @@ impl PhysicsWorld {
|
||||
};
|
||||
|
||||
query
|
||||
.cast_shape(shape_pos, shape_vel, shape, opts)
|
||||
.cast_shape(&Pose2::from(*shape_pos), (*shape_vel).into(), shape, opts)
|
||||
.map(|(handle, toi)| {
|
||||
(
|
||||
Handle::decode_from_u128(self.colliders.get(handle).unwrap().user_data),
|
||||
TOI {
|
||||
toi: toi.time_of_impact,
|
||||
witness1: toi.witness1,
|
||||
witness2: toi.witness2,
|
||||
normal1: toi.normal1,
|
||||
normal2: toi.normal2,
|
||||
witness1: toi.witness1.into(),
|
||||
witness2: toi.witness2.into(),
|
||||
normal1: UnitVector2::new_normalize(toi.normal1.into()),
|
||||
normal2: UnitVector2::new_normalize(toi.normal2.into()),
|
||||
status: toi.status.into(),
|
||||
},
|
||||
)
|
||||
@@ -905,7 +907,7 @@ impl PhysicsWorld {
|
||||
) {
|
||||
if let Some(native) = self.bodies.get_mut(rigid_body.native.get()) {
|
||||
native.set_position(
|
||||
isometry_from_global_transform(new_global_transform),
|
||||
isometry_from_global_transform(new_global_transform).into(),
|
||||
// Do not wake up body, it is too expensive and must be done **only** by explicit
|
||||
// `wake_up` call!
|
||||
false,
|
||||
@@ -924,7 +926,7 @@ impl PhysicsWorld {
|
||||
let local_transform: Matrix4<f32> = parent_transform
|
||||
.try_inverse()
|
||||
.unwrap_or_else(Matrix4::identity)
|
||||
* isometry2_to_mat4(native.position());
|
||||
* isometry2_to_mat4(&Isometry2::from(*native.position()));
|
||||
|
||||
let new_local_rotation = UnitQuaternion::from_matrix_eps(
|
||||
&local_transform.basis(),
|
||||
@@ -953,7 +955,7 @@ impl PhysicsWorld {
|
||||
|
||||
rigid_body
|
||||
.lin_vel
|
||||
.set_value_with_flags(*native.linvel(), VariableFlags::MODIFIED);
|
||||
.set_value_with_flags(native.linvel().into(), VariableFlags::MODIFIED);
|
||||
rigid_body
|
||||
.ang_vel
|
||||
.set_value_with_flags(native.angvel(), VariableFlags::MODIFIED);
|
||||
@@ -988,7 +990,7 @@ impl PhysicsWorld {
|
||||
.try_sync_model(|v| native.set_body_type(v.into(), false));
|
||||
rigid_body_node
|
||||
.lin_vel
|
||||
.try_sync_model(|v| native.set_linvel(v, true));
|
||||
.try_sync_model(|v| native.set_linvel(v.into(), true));
|
||||
rigid_body_node
|
||||
.ang_vel
|
||||
.try_sync_model(|v| native.set_angvel(v, true));
|
||||
@@ -1034,7 +1036,7 @@ impl PhysicsWorld {
|
||||
while let Some(action) = actions.pop_front() {
|
||||
match action {
|
||||
ApplyAction::Force(force) => {
|
||||
native.add_force(force, false);
|
||||
native.add_force(force.into(), false);
|
||||
rigid_body_node.reset_forces.set(true);
|
||||
}
|
||||
ApplyAction::Torque(torque) => {
|
||||
@@ -1042,25 +1044,27 @@ impl PhysicsWorld {
|
||||
rigid_body_node.reset_forces.set(true);
|
||||
}
|
||||
ApplyAction::ForceAtPoint { force, point } => {
|
||||
native.add_force_at_point(force, Point2::from(point), false);
|
||||
native.add_force_at_point(force.into(), point.into(), false);
|
||||
rigid_body_node.reset_forces.set(true);
|
||||
}
|
||||
ApplyAction::Impulse(impulse) => native.apply_impulse(impulse, false),
|
||||
ApplyAction::Impulse(impulse) => {
|
||||
native.apply_impulse(impulse.into(), false)
|
||||
}
|
||||
ApplyAction::TorqueImpulse(impulse) => {
|
||||
native.apply_torque_impulse(impulse, false)
|
||||
}
|
||||
ApplyAction::ImpulseAtPoint { impulse, point } => {
|
||||
native.apply_impulse_at_point(impulse, Point2::from(point), false)
|
||||
native.apply_impulse_at_point(impulse.into(), point.into(), false)
|
||||
}
|
||||
ApplyAction::WakeUp => native.wake_up(true),
|
||||
ApplyAction::NextTranslation(position) => {
|
||||
native.set_next_kinematic_translation(position)
|
||||
native.set_next_kinematic_translation(position.into())
|
||||
}
|
||||
ApplyAction::NextRotation(rotation) => {
|
||||
native.set_next_kinematic_rotation(rotation)
|
||||
native.set_next_kinematic_rotation(rotation.into())
|
||||
}
|
||||
ApplyAction::NextPosition(position) => {
|
||||
native.set_next_kinematic_position(position)
|
||||
native.set_next_kinematic_position(position.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1068,13 +1072,11 @@ impl PhysicsWorld {
|
||||
}
|
||||
} else {
|
||||
let mut builder = RigidBodyBuilder::new(rigid_body_node.body_type().into())
|
||||
.pose(isometry_from_global_transform(
|
||||
&rigid_body_node.global_transform(),
|
||||
))
|
||||
.pose(isometry_from_global_transform(&rigid_body_node.global_transform()).into())
|
||||
.ccd_enabled(rigid_body_node.is_ccd_enabled())
|
||||
.additional_mass(rigid_body_node.mass())
|
||||
.angvel(*rigid_body_node.ang_vel)
|
||||
.linvel(*rigid_body_node.lin_vel)
|
||||
.linvel((*rigid_body_node.lin_vel).into())
|
||||
.linear_damping(*rigid_body_node.lin_damping)
|
||||
.angular_damping(*rigid_body_node.ang_damping)
|
||||
.can_sleep(rigid_body_node.is_can_sleep())
|
||||
@@ -1191,14 +1193,17 @@ impl PhysicsWorld {
|
||||
nodes,
|
||||
) {
|
||||
let mut builder = ColliderBuilder::new(shape)
|
||||
.position(Isometry2 {
|
||||
rotation: UnitComplex::from_angle(
|
||||
collider_node.local_transform().rotation().euler_angles().2,
|
||||
),
|
||||
translation: Translation2 {
|
||||
vector: collider_node.local_transform().position().xy(),
|
||||
},
|
||||
})
|
||||
.position(
|
||||
Isometry2 {
|
||||
rotation: UnitComplex::from_angle(
|
||||
collider_node.local_transform().rotation().euler_angles().2,
|
||||
),
|
||||
translation: Translation2 {
|
||||
vector: collider_node.local_transform().position().xy(),
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.friction(collider_node.friction())
|
||||
.restitution(collider_node.restitution())
|
||||
.collision_groups(InteractionGroups::new(
|
||||
@@ -1262,7 +1267,7 @@ impl PhysicsWorld {
|
||||
joint.params.try_sync_model(|v| {
|
||||
native.data =
|
||||
// Preserve local frames.
|
||||
convert_joint_params(v, native.data.local_frame1, native.data.local_frame2)
|
||||
convert_joint_params(v, native.data.local_frame1.into(), native.data.local_frame2.into())
|
||||
});
|
||||
joint.motor_params.try_sync_model(|v|{
|
||||
// The free axis is defined to be the x axis for both prismatic and ball joints in fyrox.
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
use crate::{
|
||||
core::{
|
||||
algebra::{
|
||||
DMatrix, Dyn, Isometry3, Matrix4, Point3, Translation, Translation3, UnitQuaternion,
|
||||
UnitVector3, VecStorage, Vector2, Vector3,
|
||||
Isometry3, Matrix4, Point3, Translation, Translation3, UnitQuaternion, UnitVector3,
|
||||
Vector2, Vector3,
|
||||
},
|
||||
arrayvec::ArrayVec,
|
||||
instant,
|
||||
@@ -54,6 +54,7 @@ use crate::{
|
||||
},
|
||||
utils::raw_mesh::{RawMeshBuilder, RawVertex},
|
||||
};
|
||||
use rapier3d::geometry::Array2;
|
||||
use rapier3d::{
|
||||
dynamics::{
|
||||
CCDSolver, GenericJoint, GenericJointBuilder, ImpulseJointHandle, ImpulseJointSet,
|
||||
@@ -80,6 +81,7 @@ use strum_macros::{AsRefStr, EnumString, VariantNames};
|
||||
|
||||
use fyrox_graph::{SceneGraph, SceneGraphNode};
|
||||
pub use rapier3d::geometry::shape::*;
|
||||
use rapier3d::math::{Pose3, Vec3};
|
||||
use rapier3d::parry::query::DefaultQueryDispatcher;
|
||||
use rapier3d::prelude::FrictionModel;
|
||||
|
||||
@@ -385,15 +387,15 @@ impl ContactPair {
|
||||
.points
|
||||
.iter()
|
||||
.map(|p| ContactData {
|
||||
local_p1: p.local_p1.coords,
|
||||
local_p2: p.local_p2.coords,
|
||||
local_p1: p.local_p1.into(),
|
||||
local_p2: p.local_p2.into(),
|
||||
dist: p.dist,
|
||||
impulse: p.data.impulse,
|
||||
tangent_impulse: p.data.tangent_impulse,
|
||||
})
|
||||
.collect(),
|
||||
local_n1: m.local_n1,
|
||||
local_n2: m.local_n2,
|
||||
local_n1: m.local_n1.into(),
|
||||
local_n2: m.local_n2.into(),
|
||||
rigid_body1: m.data.rigid_body1.and_then(|h| {
|
||||
physics
|
||||
.bodies
|
||||
@@ -406,11 +408,11 @@ impl ContactPair {
|
||||
.get(h)
|
||||
.map(|b| Handle::decode_from_u128(b.user_data))
|
||||
})?,
|
||||
normal: m.data.normal,
|
||||
normal: m.data.normal.into(),
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
has_any_active_contact: c.has_any_active_contact,
|
||||
has_any_active_contact: c.has_any_active_contact(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -464,8 +466,8 @@ fn convert_joint_params(
|
||||
};
|
||||
|
||||
let mut joint = GenericJointBuilder::new(locked_axis)
|
||||
.local_frame1(local_frame1)
|
||||
.local_frame2(local_frame2)
|
||||
.local_frame1(local_frame1.into())
|
||||
.local_frame2(local_frame2.into())
|
||||
.build();
|
||||
|
||||
match params {
|
||||
@@ -579,10 +581,10 @@ fn make_trimesh(
|
||||
|
||||
let raw_mesh = mesh_builder.build();
|
||||
|
||||
let vertices: Vec<Point3<f32>> = raw_mesh
|
||||
let vertices: Vec<Vec3> = raw_mesh
|
||||
.vertices
|
||||
.into_iter()
|
||||
.map(|v| Point3::new(v.x, v.y, v.z))
|
||||
.map(|v| Vec3::new(v.x, v.y, v.z))
|
||||
.collect();
|
||||
|
||||
let indices = raw_mesh
|
||||
@@ -600,7 +602,7 @@ fn make_trimesh(
|
||||
),
|
||||
);
|
||||
|
||||
SharedShape::trimesh(vec![Point3::new(0.0, 0.0, 0.0)], vec![[0, 0, 0]]).ok()
|
||||
SharedShape::trimesh(vec![Vec3::new(0.0, 0.0, 0.0)], vec![[0, 0, 0]]).ok()
|
||||
} else {
|
||||
SharedShape::trimesh(vertices, indices).ok()
|
||||
}
|
||||
@@ -668,10 +670,10 @@ fn make_polyhedron_shape(owner_inv_transform: Matrix4<f32>, mesh: &Mesh) -> Shar
|
||||
|
||||
let raw_mesh = mesh_builder.build();
|
||||
|
||||
let vertices: Vec<Point3<f32>> = raw_mesh
|
||||
let vertices: Vec<Vec3> = raw_mesh
|
||||
.vertices
|
||||
.into_iter()
|
||||
.map(|v| Point3::new(v.x, v.y, v.z))
|
||||
.map(|v| Vec3::new(v.x, v.y, v.z))
|
||||
.collect();
|
||||
|
||||
let indices = raw_mesh
|
||||
@@ -731,16 +733,10 @@ fn make_heightfield(terrain: &Terrain) -> Option<SharedShape> {
|
||||
let x_pos = terrain.chunk_size().x * scale.x * chunk_min.x as f32;
|
||||
let z_pos = terrain.chunk_size().y * scale.z * chunk_min.y as f32;
|
||||
let mut hf = HeightField::new(
|
||||
DMatrix::from_data(VecStorage::new(
|
||||
Dyn(nrows as usize),
|
||||
Dyn(ncols as usize),
|
||||
data,
|
||||
)),
|
||||
Vector3::new(x_scale, 1.0, z_scale),
|
||||
Array2::new(nrows as usize, ncols as usize, data),
|
||||
Vec3::new(x_scale, 1.0, z_scale),
|
||||
);
|
||||
if terrain.holes_enabled() {
|
||||
hf.cells_statuses_mut()
|
||||
.fill(HeightFieldCellStatus::CELL_REMOVED);
|
||||
let hole_mask_size = terrain.hole_mask_size();
|
||||
for chunk in terrain.chunks_ref() {
|
||||
let texture = chunk.hole_mask().map(|t| t.data_ref());
|
||||
@@ -754,7 +750,13 @@ fn make_heightfield(terrain: &Terrain) -> Option<SharedShape> {
|
||||
.map(|m| m[(iy * hole_mask_size.x + ix) as usize] < 128)
|
||||
.unwrap_or_default();
|
||||
let (x, y) = (ox + ix, oy + iy);
|
||||
if !is_hole {
|
||||
if is_hole {
|
||||
hf.set_cell_status(
|
||||
y as usize,
|
||||
x as usize,
|
||||
HeightFieldCellStatus::CELL_REMOVED,
|
||||
);
|
||||
} else {
|
||||
hf.set_cell_status(y as usize, x as usize, HeightFieldCellStatus::empty());
|
||||
}
|
||||
}
|
||||
@@ -764,7 +766,7 @@ fn make_heightfield(terrain: &Terrain) -> Option<SharedShape> {
|
||||
// HeightField colliders naturally have their origin at their centers,
|
||||
// so to position the collider correctly we must add half of the size to x and z.
|
||||
Some(SharedShape::compound(vec![(
|
||||
Isometry3::translation(x_scale * 0.5 + x_pos, 0.0, z_scale * 0.5 + z_pos),
|
||||
Pose3::translation(x_scale * 0.5 + x_pos, 0.0, z_scale * 0.5 + z_pos),
|
||||
SharedShape::new(hf),
|
||||
)]))
|
||||
}
|
||||
@@ -783,22 +785,22 @@ fn collider_shape_into_native_shape(
|
||||
Some(SharedShape::cylinder(cylinder.half_height, cylinder.radius))
|
||||
}
|
||||
ColliderShape::Cone(cone) => Some(SharedShape::cone(cone.half_height, cone.radius)),
|
||||
ColliderShape::Cuboid(cuboid) => {
|
||||
Some(SharedShape(Arc::new(Cuboid::new(cuboid.half_extents))))
|
||||
}
|
||||
ColliderShape::Cuboid(cuboid) => Some(SharedShape(Arc::new(Cuboid::new(
|
||||
cuboid.half_extents.into(),
|
||||
)))),
|
||||
ColliderShape::Capsule(capsule) => Some(SharedShape::capsule(
|
||||
Point3::from(capsule.begin),
|
||||
Point3::from(capsule.end),
|
||||
capsule.begin.into(),
|
||||
capsule.end.into(),
|
||||
capsule.radius,
|
||||
)),
|
||||
ColliderShape::Segment(segment) => Some(SharedShape::segment(
|
||||
Point3::from(segment.begin),
|
||||
Point3::from(segment.end),
|
||||
segment.begin.into(),
|
||||
segment.end.into(),
|
||||
)),
|
||||
ColliderShape::Triangle(triangle) => Some(SharedShape::triangle(
|
||||
Point3::from(triangle.a),
|
||||
Point3::from(triangle.b),
|
||||
Point3::from(triangle.c),
|
||||
triangle.a.into(),
|
||||
triangle.b.into(),
|
||||
triangle.c.into(),
|
||||
)),
|
||||
ColliderShape::Trimesh(trimesh) => {
|
||||
if trimesh.sources.is_empty() {
|
||||
@@ -1137,7 +1139,7 @@ impl PhysicsWorld {
|
||||
};
|
||||
|
||||
self.pipeline.step(
|
||||
&self.gravity,
|
||||
(*self.gravity).into(),
|
||||
&integration_parameters,
|
||||
&mut self.islands,
|
||||
&mut self.broad_phase,
|
||||
@@ -1236,16 +1238,17 @@ impl PhysicsWorld {
|
||||
|
||||
query_buffer.clear();
|
||||
let ray = Ray::new(
|
||||
opts.ray_origin,
|
||||
opts.ray_origin.into(),
|
||||
opts.ray_direction
|
||||
.try_normalize(f32::EPSILON)
|
||||
.unwrap_or_default(),
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
);
|
||||
for (_, collider, intersection) in query.intersect_ray(ray, opts.max_len, true) {
|
||||
query_buffer.push(Intersection {
|
||||
collider: Handle::decode_from_u128(collider.user_data),
|
||||
normal: intersection.normal,
|
||||
position: ray.point_at(intersection.time_of_impact),
|
||||
normal: intersection.normal.into(),
|
||||
position: ray.point_at(intersection.time_of_impact).into(),
|
||||
feature: intersection.feature.into(),
|
||||
toi: intersection.time_of_impact,
|
||||
});
|
||||
@@ -1344,16 +1347,16 @@ impl PhysicsWorld {
|
||||
};
|
||||
|
||||
query
|
||||
.cast_shape(shape_pos, shape_vel, shape, opts)
|
||||
.cast_shape(&Pose3::from(*shape_pos), (*shape_vel).into(), shape, opts)
|
||||
.map(|(handle, toi)| {
|
||||
(
|
||||
Handle::decode_from_u128(self.colliders.get(handle).unwrap().user_data),
|
||||
TOI {
|
||||
toi: toi.time_of_impact,
|
||||
witness1: toi.witness1,
|
||||
witness2: toi.witness2,
|
||||
normal1: toi.normal1,
|
||||
normal2: toi.normal2,
|
||||
witness1: toi.witness1.into(),
|
||||
witness2: toi.witness2.into(),
|
||||
normal1: UnitVector3::new_normalize(toi.normal1.into()),
|
||||
normal2: UnitVector3::new_normalize(toi.normal2.into()),
|
||||
status: toi.status.into(),
|
||||
},
|
||||
)
|
||||
@@ -1367,7 +1370,7 @@ impl PhysicsWorld {
|
||||
) {
|
||||
if let Some(native) = self.bodies.get_mut(rigid_body.native.get()) {
|
||||
native.set_position(
|
||||
isometry_from_global_transform(new_global_transform),
|
||||
isometry_from_global_transform(new_global_transform).into(),
|
||||
// Do not wake up body, it is too expensive and must be done **only** by explicit
|
||||
// `wake_up` call!
|
||||
false,
|
||||
@@ -1386,7 +1389,7 @@ impl PhysicsWorld {
|
||||
let local_transform: Matrix4<f32> = parent_transform
|
||||
.try_inverse()
|
||||
.unwrap_or_else(Matrix4::identity)
|
||||
* native.position().to_homogeneous();
|
||||
* Isometry3::from(*native.position()).to_homogeneous();
|
||||
|
||||
let new_local_rotation = UnitQuaternion::from_matrix_eps(
|
||||
&local_transform.basis(),
|
||||
@@ -1415,10 +1418,10 @@ impl PhysicsWorld {
|
||||
|
||||
rigid_body
|
||||
.lin_vel
|
||||
.set_value_with_flags(*native.linvel(), VariableFlags::MODIFIED);
|
||||
.set_value_with_flags(native.linvel().into(), VariableFlags::MODIFIED);
|
||||
rigid_body
|
||||
.ang_vel
|
||||
.set_value_with_flags(*native.angvel(), VariableFlags::MODIFIED);
|
||||
.set_value_with_flags(native.angvel().into(), VariableFlags::MODIFIED);
|
||||
rigid_body.sleeping = native.is_sleeping();
|
||||
}
|
||||
}
|
||||
@@ -1450,10 +1453,10 @@ impl PhysicsWorld {
|
||||
.try_sync_model(|v| native.set_body_type(v.into(), false));
|
||||
rigid_body_node
|
||||
.lin_vel
|
||||
.try_sync_model(|v| native.set_linvel(v, true));
|
||||
.try_sync_model(|v| native.set_linvel(v.into(), true));
|
||||
rigid_body_node
|
||||
.ang_vel
|
||||
.try_sync_model(|v| native.set_angvel(v, true));
|
||||
.try_sync_model(|v| native.set_angvel(v.into(), true));
|
||||
rigid_body_node.mass.try_sync_model(|v| {
|
||||
match *rigid_body_node.mass_properties_type {
|
||||
RigidBodyMassPropertiesType::Default => {
|
||||
@@ -1465,9 +1468,9 @@ impl PhysicsWorld {
|
||||
} => {
|
||||
native.set_additional_mass_properties(
|
||||
MassProperties::new(
|
||||
Point3::from(center_of_mass),
|
||||
center_of_mass.into(),
|
||||
v,
|
||||
principal_inertia,
|
||||
principal_inertia.into(),
|
||||
),
|
||||
false,
|
||||
);
|
||||
@@ -1485,9 +1488,9 @@ impl PhysicsWorld {
|
||||
} => {
|
||||
native.set_additional_mass_properties(
|
||||
MassProperties::new(
|
||||
Point3::from(center_of_mass),
|
||||
center_of_mass.into(),
|
||||
*rigid_body_node.mass,
|
||||
principal_inertia,
|
||||
principal_inertia.into(),
|
||||
),
|
||||
false,
|
||||
);
|
||||
@@ -1554,33 +1557,35 @@ impl PhysicsWorld {
|
||||
while let Some(action) = actions.pop_front() {
|
||||
match action {
|
||||
ApplyAction::Force(force) => {
|
||||
native.add_force(force, false);
|
||||
native.add_force(force.into(), false);
|
||||
rigid_body_node.reset_forces.set(true);
|
||||
}
|
||||
ApplyAction::Torque(torque) => {
|
||||
native.add_torque(torque, false);
|
||||
native.add_torque(torque.into(), false);
|
||||
rigid_body_node.reset_forces.set(true);
|
||||
}
|
||||
ApplyAction::ForceAtPoint { force, point } => {
|
||||
native.add_force_at_point(force, Point3::from(point), false);
|
||||
native.add_force_at_point(force.into(), point.into(), false);
|
||||
rigid_body_node.reset_forces.set(true);
|
||||
}
|
||||
ApplyAction::Impulse(impulse) => native.apply_impulse(impulse, false),
|
||||
ApplyAction::Impulse(impulse) => {
|
||||
native.apply_impulse(impulse.into(), false)
|
||||
}
|
||||
ApplyAction::TorqueImpulse(impulse) => {
|
||||
native.apply_torque_impulse(impulse, false)
|
||||
native.apply_torque_impulse(impulse.into(), false)
|
||||
}
|
||||
ApplyAction::ImpulseAtPoint { impulse, point } => {
|
||||
native.apply_impulse_at_point(impulse, Point3::from(point), false)
|
||||
native.apply_impulse_at_point(impulse.into(), point.into(), false)
|
||||
}
|
||||
ApplyAction::WakeUp => native.wake_up(true),
|
||||
ApplyAction::NextTranslation(position) => {
|
||||
native.set_next_kinematic_translation(position)
|
||||
native.set_next_kinematic_translation(position.into())
|
||||
}
|
||||
ApplyAction::NextRotation(rotation) => {
|
||||
native.set_next_kinematic_rotation(rotation)
|
||||
native.set_next_kinematic_rotation(rotation.into())
|
||||
}
|
||||
ApplyAction::NextPosition(position) => {
|
||||
native.set_next_kinematic_position(position)
|
||||
native.set_next_kinematic_position(position.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1588,13 +1593,11 @@ impl PhysicsWorld {
|
||||
}
|
||||
} else {
|
||||
let mut builder = RigidBodyBuilder::new(rigid_body_node.body_type().into())
|
||||
.pose(isometry_from_global_transform(
|
||||
&rigid_body_node.global_transform(),
|
||||
))
|
||||
.pose(isometry_from_global_transform(&rigid_body_node.global_transform()).into())
|
||||
.ccd_enabled(rigid_body_node.is_ccd_enabled())
|
||||
.additional_mass(rigid_body_node.mass())
|
||||
.angvel(*rigid_body_node.ang_vel)
|
||||
.linvel(*rigid_body_node.lin_vel)
|
||||
.angvel((*rigid_body_node.ang_vel).into())
|
||||
.linvel((*rigid_body_node.lin_vel).into())
|
||||
.linear_damping(*rigid_body_node.lin_damping)
|
||||
.angular_damping(*rigid_body_node.ang_damping)
|
||||
.can_sleep(rigid_body_node.is_can_sleep())
|
||||
@@ -1615,9 +1618,9 @@ impl PhysicsWorld {
|
||||
principal_inertia,
|
||||
} => {
|
||||
builder = builder.additional_mass_properties(MassProperties::new(
|
||||
Point3::from(center_of_mass),
|
||||
center_of_mass.into(),
|
||||
*rigid_body_node.mass,
|
||||
principal_inertia,
|
||||
principal_inertia.into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
@@ -1728,12 +1731,15 @@ impl PhysicsWorld {
|
||||
nodes,
|
||||
) {
|
||||
let mut builder = ColliderBuilder::new(shape)
|
||||
.position(Isometry3 {
|
||||
rotation: **collider_node.local_transform().rotation(),
|
||||
translation: Translation3 {
|
||||
vector: **collider_node.local_transform().position(),
|
||||
},
|
||||
})
|
||||
.position(
|
||||
Isometry3 {
|
||||
rotation: **collider_node.local_transform().rotation(),
|
||||
translation: Translation3 {
|
||||
vector: **collider_node.local_transform().position(),
|
||||
},
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.friction(collider_node.friction())
|
||||
.restitution(collider_node.restitution())
|
||||
.collision_groups(InteractionGroups::new(
|
||||
@@ -1797,7 +1803,7 @@ impl PhysicsWorld {
|
||||
joint.params.try_sync_model(|v| {
|
||||
native.data =
|
||||
// Preserve local frames.
|
||||
convert_joint_params(v, native.data.local_frame1, native.data.local_frame2)
|
||||
convert_joint_params(v, native.data.local_frame1.into(), native.data.local_frame2.into())
|
||||
});
|
||||
joint.motor_params.try_sync_model(|v|{
|
||||
// For prismatic and revolute joints, the free axis is defined to be the x axis.
|
||||
|
||||
@@ -24,15 +24,17 @@
|
||||
//! is a resource that contains triangles to allow an arbitrary shape to be constructed for
|
||||
//! any tile.
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
asset::{Resource, ResourceData},
|
||||
core::{
|
||||
algebra::{Matrix4, Point2, Point3, Vector2},
|
||||
algebra::{Matrix4, Point3, Vector2},
|
||||
reflect::prelude::*,
|
||||
type_traits::prelude::*,
|
||||
visitor::prelude::*,
|
||||
},
|
||||
};
|
||||
use fyrox_core::algebra::Point2;
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{Debug, Display, Formatter},
|
||||
@@ -42,8 +44,6 @@ use std::{
|
||||
};
|
||||
use strum_macros::{AsRefStr, EnumString, VariantNames};
|
||||
|
||||
use super::*;
|
||||
|
||||
/// Supported collider types for tiles.
|
||||
#[derive(
|
||||
Clone,
|
||||
|
||||
@@ -15,7 +15,7 @@ rust-version = "1.87"
|
||||
|
||||
[dependencies]
|
||||
rectutils = "0.5.0"
|
||||
nalgebra = { version = "0.34", features = ["bytemuck"] }
|
||||
nalgebra = { version = "0.34", features = ["bytemuck", "convert-glam030"] }
|
||||
arrayvec = "0.7.4"
|
||||
num-traits = "0.2.18"
|
||||
uuid = { version = "1", features = ["v4"] }
|
||||
|
||||
Reference in New Issue
Block a user