Always apply the predictive contact term, even for bouncing contacts
This commit is contained in:
@@ -239,11 +239,10 @@ impl VelocityConstraint {
|
|||||||
+ gcross1.gdot(gcross1)
|
+ gcross1.gdot(gcross1)
|
||||||
+ gcross2.gdot(gcross2));
|
+ gcross2.gdot(gcross2));
|
||||||
|
|
||||||
let rhs = if manifold_point.is_bouncy() {
|
let is_bouncy = manifold_point.is_bouncy() as u32 as Real;
|
||||||
(1.0 + manifold_point.restitution) * (vel1 - vel2).dot(&force_dir1)
|
let rhs = (1.0 + is_bouncy * manifold_point.restitution)
|
||||||
} else {
|
* (vel1 - vel2).dot(&force_dir1)
|
||||||
(vel1 - vel2).dot(&force_dir1) + manifold_point.dist.max(0.0) * inv_dt
|
+ manifold_point.dist.max(0.0) * inv_dt;
|
||||||
};
|
|
||||||
|
|
||||||
let impulse = manifold_point.data.impulse * warmstart_coeff;
|
let impulse = manifold_point.data.impulse * warmstart_coeff;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ use super::{AnyVelocityConstraint, DeltaVel};
|
|||||||
use crate::dynamics::{IntegrationParameters, RigidBodySet};
|
use crate::dynamics::{IntegrationParameters, RigidBodySet};
|
||||||
use crate::geometry::{ContactManifold, ContactManifoldIndex};
|
use crate::geometry::{ContactManifold, ContactManifoldIndex};
|
||||||
use crate::math::{
|
use crate::math::{
|
||||||
AngVector, AngularInertia, Point, Real, SimdBool, SimdReal, Vector, DIM, MAX_MANIFOLD_POINTS,
|
AngVector, AngularInertia, Point, Real, SimdReal, Vector, DIM, MAX_MANIFOLD_POINTS, SIMD_WIDTH,
|
||||||
SIMD_WIDTH,
|
|
||||||
};
|
};
|
||||||
use crate::utils::{WAngularInertia, WBasis, WCross, WDot};
|
use crate::utils::{WAngularInertia, WBasis, WCross, WDot};
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
@@ -124,11 +123,11 @@ impl WVelocityConstraint {
|
|||||||
for k in 0..num_points {
|
for k in 0..num_points {
|
||||||
let friction =
|
let friction =
|
||||||
SimdReal::from(array![|ii| manifold_points[ii][k].friction; SIMD_WIDTH]);
|
SimdReal::from(array![|ii| manifold_points[ii][k].friction; SIMD_WIDTH]);
|
||||||
let restitution_plus_1 = SimdReal::from(
|
let restitution =
|
||||||
array![|ii| manifold_points[ii][k].restitution + 1.0; SIMD_WIDTH],
|
SimdReal::from(array![|ii| manifold_points[ii][k].restitution; SIMD_WIDTH]);
|
||||||
|
let is_bouncy = SimdReal::from(
|
||||||
|
array![|ii| manifold_points[ii][k].is_bouncy() as u32 as Real; SIMD_WIDTH],
|
||||||
);
|
);
|
||||||
let is_bouncy =
|
|
||||||
SimdBool::from(array![|ii| manifold_points[ii][k].is_bouncy(); SIMD_WIDTH]);
|
|
||||||
let point = Point::from(array![|ii| manifold_points[ii][k].point; SIMD_WIDTH]);
|
let point = Point::from(array![|ii| manifold_points[ii][k].point; SIMD_WIDTH]);
|
||||||
let dist = SimdReal::from(array![|ii| manifold_points[ii][k].dist; SIMD_WIDTH]);
|
let dist = SimdReal::from(array![|ii| manifold_points[ii][k].dist; SIMD_WIDTH]);
|
||||||
|
|
||||||
@@ -151,9 +150,8 @@ impl WVelocityConstraint {
|
|||||||
let r = SimdReal::splat(1.0)
|
let r = SimdReal::splat(1.0)
|
||||||
/ (im1 + im2 + gcross1.gdot(gcross1) + gcross2.gdot(gcross2));
|
/ (im1 + im2 + gcross1.gdot(gcross1) + gcross2.gdot(gcross2));
|
||||||
let projected_velocity = (vel1 - vel2).dot(&force_dir1);
|
let projected_velocity = (vel1 - vel2).dot(&force_dir1);
|
||||||
let rhs_resting = projected_velocity + dist.simd_max(SimdReal::zero()) * inv_dt;
|
let rhs = (SimdReal::splat(1.0) + is_bouncy * restitution) * projected_velocity
|
||||||
let rhs_bouncing = projected_velocity * restitution_plus_1;
|
+ dist.simd_max(SimdReal::zero()) * inv_dt;
|
||||||
let rhs = rhs_bouncing.select(is_bouncy, rhs_resting);
|
|
||||||
|
|
||||||
constraint.elements[k].normal_part = WVelocityConstraintElementPart {
|
constraint.elements[k].normal_part = WVelocityConstraintElementPart {
|
||||||
gcross1,
|
gcross1,
|
||||||
|
|||||||
@@ -154,11 +154,10 @@ impl VelocityGroundConstraint {
|
|||||||
|
|
||||||
let r = 1.0 / (rb2.effective_inv_mass + gcross2.gdot(gcross2));
|
let r = 1.0 / (rb2.effective_inv_mass + gcross2.gdot(gcross2));
|
||||||
|
|
||||||
let rhs = if manifold_point.is_bouncy() {
|
let is_bouncy = manifold_point.is_bouncy() as u32 as Real;
|
||||||
(1.0 + manifold_point.restitution) * (vel1 - vel2).dot(&force_dir1)
|
let rhs = (1.0 + is_bouncy * manifold_point.restitution)
|
||||||
} else {
|
* (vel1 - vel2).dot(&force_dir1)
|
||||||
(vel1 - vel2).dot(&force_dir1) + manifold_point.dist.max(0.0) * inv_dt
|
+ manifold_point.dist.max(0.0) * inv_dt;
|
||||||
};
|
|
||||||
|
|
||||||
let impulse = manifold_point.data.impulse * warmstart_coeff;
|
let impulse = manifold_point.data.impulse * warmstart_coeff;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ use super::{AnyVelocityConstraint, DeltaVel};
|
|||||||
use crate::dynamics::{IntegrationParameters, RigidBodySet};
|
use crate::dynamics::{IntegrationParameters, RigidBodySet};
|
||||||
use crate::geometry::{ContactManifold, ContactManifoldIndex};
|
use crate::geometry::{ContactManifold, ContactManifoldIndex};
|
||||||
use crate::math::{
|
use crate::math::{
|
||||||
AngVector, AngularInertia, Point, Real, SimdBool, SimdReal, Vector, DIM, MAX_MANIFOLD_POINTS,
|
AngVector, AngularInertia, Point, Real, SimdReal, Vector, DIM, MAX_MANIFOLD_POINTS, SIMD_WIDTH,
|
||||||
SIMD_WIDTH,
|
|
||||||
};
|
};
|
||||||
use crate::utils::{WAngularInertia, WBasis, WCross, WDot};
|
use crate::utils::{WAngularInertia, WBasis, WCross, WDot};
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
@@ -119,11 +118,11 @@ impl WVelocityGroundConstraint {
|
|||||||
for k in 0..num_points {
|
for k in 0..num_points {
|
||||||
let friction =
|
let friction =
|
||||||
SimdReal::from(array![|ii| manifold_points[ii][k].friction; SIMD_WIDTH]);
|
SimdReal::from(array![|ii| manifold_points[ii][k].friction; SIMD_WIDTH]);
|
||||||
let restitution_plus_1 = SimdReal::from(
|
let restitution =
|
||||||
array![|ii| manifold_points[ii][k].restitution + 1.0; SIMD_WIDTH],
|
SimdReal::from(array![|ii| manifold_points[ii][k].restitution; SIMD_WIDTH]);
|
||||||
|
let is_bouncy = SimdReal::from(
|
||||||
|
array![|ii| manifold_points[ii][k].is_bouncy() as u32 as Real; SIMD_WIDTH],
|
||||||
);
|
);
|
||||||
let is_bouncy =
|
|
||||||
SimdBool::from(array![|ii| manifold_points[ii][k].is_bouncy(); SIMD_WIDTH]);
|
|
||||||
let point = Point::from(array![|ii| manifold_points[ii][k].point; SIMD_WIDTH]);
|
let point = Point::from(array![|ii| manifold_points[ii][k].point; SIMD_WIDTH]);
|
||||||
let dist = SimdReal::from(array![|ii| manifold_points[ii][k].dist; SIMD_WIDTH]);
|
let dist = SimdReal::from(array![|ii| manifold_points[ii][k].dist; SIMD_WIDTH]);
|
||||||
|
|
||||||
@@ -143,9 +142,8 @@ impl WVelocityGroundConstraint {
|
|||||||
|
|
||||||
let r = SimdReal::splat(1.0) / (im2 + gcross2.gdot(gcross2));
|
let r = SimdReal::splat(1.0) / (im2 + gcross2.gdot(gcross2));
|
||||||
let projected_velocity = (vel1 - vel2).dot(&force_dir1);
|
let projected_velocity = (vel1 - vel2).dot(&force_dir1);
|
||||||
let rhs_resting = projected_velocity + dist.simd_max(SimdReal::zero()) * inv_dt;
|
let rhs = (SimdReal::splat(1.0) + is_bouncy * restitution) * projected_velocity
|
||||||
let rhs_bouncing = projected_velocity * restitution_plus_1;
|
+ dist.simd_max(SimdReal::zero()) * inv_dt;
|
||||||
let rhs = rhs_bouncing.select(is_bouncy, rhs_resting);
|
|
||||||
|
|
||||||
constraint.elements[k].normal_part = WVelocityGroundConstraintElementPart {
|
constraint.elements[k].normal_part = WVelocityGroundConstraintElementPart {
|
||||||
gcross2,
|
gcross2,
|
||||||
|
|||||||
Reference in New Issue
Block a user