Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save lotus128/b1a88bda032199ee716eaef109e90476 to your computer and use it in GitHub Desktop.

Select an option

Save lotus128/b1a88bda032199ee716eaef109e90476 to your computer and use it in GitHub Desktop.
cast_ball_triangle
// /// Casts a moving ball against a static triangle and returns the first time of impact, if any.
// ///
// /// Checks all triangle features (face, edge, vertex) manually.
// pub fn cast_ball_triangle(
// pos12: &Isometry<f32>,
// vel12: &Vector<f32>,
// g1: &Triangle,
// g2: &Ball,
// options: ShapeCastOptions,
// ) -> Option<(ShapeCastHit, FeatureId)> {
// // TOOD support other options
// let triangle_normal = (g1.b - g1.a).cross(&(g1.c - g1.a)).normalize();
// // Plane equation: dot((p - a), n) = 0
// let plane_d = triangle_normal.dot(&g1.a.coords);
// let start_dist = triangle_normal.dot(&pos12.translation.vector) - plane_d;
// let velocity_dot_normal = triangle_normal.dot(&vel12);
// if velocity_dot_normal.abs() < 1e-5 {
// // Sphere is moving parallel to the triangle's plane
// return None;
// }
// // Time of intersection with plane offset by radius
// let t = (g2.radius - start_dist) / velocity_dot_normal;
// if t < 0.0 || t > options.max_time_of_impact {
// return None;
// }
// // Sphere center at time of impact
// let sphere_center_at_impact = pos12.translation.vector + (vel12 * t);
// // Project sphere center onto triangle plane
// let projected_point = sphere_center_at_impact - triangle_normal * ((sphere_center_at_impact - g1.a.coords).dot(&triangle_normal));
// // Distances to vertices
// let d_a = (projected_point - g1.a.coords).norm_squared();
// let d_b = (projected_point - g1.b.coords).norm_squared();
// let d_c = (projected_point - g1.c.coords).norm_squared();
// // Distances to edges
// let (edge1_dist, _edge1_proj) = point_segment_distance_squared(&projected_point.into(), &g1.a, &g1.b);
// let (edge2_dist, _edge2_proj) = point_segment_distance_squared(&projected_point.into(), &g1.b, &g1.c);
// let (edge3_dist, _edge3_proj) = point_segment_distance_squared(&projected_point.into(), &g1.c, &g1.a);
// // Distance to face (project point onto triangle's plane and check if inside)
// let face_normal = (g1.b - g1.a).cross(&(g1.c - g1.a)).normalize();
// let v0 = g1.b - g1.a;
// let v1 = g1.c - g1.a;
// let v2 = projected_point - g1.a.coords;
// let dot00 = v0.dot(&v0);
// let dot01 = v0.dot(&v1);
// let dot02 = v0.dot(&v2);
// let dot11 = v1.dot(&v1);
// let dot12 = v1.dot(&v2);
// let denom = dot00 * dot11 - dot01 * dot01;
// let (u, v) = if denom != 0.0 {
// let inv_denom = 1.0 / denom;
// let u = (dot11 * dot02 - dot01 * dot12) * inv_denom;
// let v = (dot00 * dot12 - dot01 * dot02) * inv_denom;
// (u, v)
// } else {
// (-1.0, -1.0) // Degenerate triangle
// };
// let in_triangle = u >= 0.0 && v >= 0.0 && u + v <= 1.0;
// if !in_triangle {
// return None;
// }
// let face_dist = ((projected_point - g1.a.coords).dot(&face_normal)).abs();
// // Determine the closest feature
// let mut min_dist = d_a;
// let mut feature = FeatureId::Vertex(0);
// if d_b < min_dist {
// min_dist = d_b;
// feature = FeatureId::Vertex(1);
// }
// if d_c < min_dist {
// min_dist = d_c;
// feature = FeatureId::Vertex(2);
// }
// if edge1_dist < min_dist {
// min_dist = edge1_dist;
// feature = FeatureId::Edge(0);
// }
// if edge2_dist < min_dist {
// min_dist = edge2_dist;
// feature = FeatureId::Edge(1);
// }
// if edge3_dist < min_dist {
// min_dist = edge3_dist;
// feature = FeatureId::Edge(2);
// }
// if in_triangle && face_dist < min_dist {
// feature = FeatureId::Face(0);
// }
// let point_on_triangle = projected_point;
// let point_on_sphere = sphere_center_at_impact - triangle_normal * g2.radius;
// let triangle_normal_as_unit = Unit::new_unchecked(triangle_normal);
// let shape_cast_hit = ShapeCastHit {
// witness1: point_on_triangle.into(),
// witness2: point_on_sphere.into(),
// normal1: triangle_normal_as_unit,
// normal2: -triangle_normal_as_unit,
// time_of_impact: t,
// status: ShapeCastStatus::Converged, // TOOD return penetrating or within target distance
// };
// return Some((shape_cast_hit, feature));
// }
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment