box2d_rs/private/collision/
b2_edge_shape.rs

1use crate::b2_collision::*;
2use crate::shapes::b2_edge_shape::*;
3use crate::b2_math::*;
4use crate::b2_common::*;
5use crate::b2_shape::*;
6
7pub fn b2_set_one_sided(self_: &mut B2edgeShape, v0: B2vec2, v1: B2vec2, v2: B2vec2, v3: B2vec2) {
8	self_.m_vertex0 = v0;
9	self_.m_vertex1 = v1;
10	self_.m_vertex2 = v2;
11	self_.m_vertex3 = v3;
12	self_.m_one_sided = true;
13}
14
15pub fn b2_set_two_sided(self_: &mut B2edgeShape, v1: B2vec2, v2: B2vec2) {
16	self_.m_vertex1 = v1;
17	self_.m_vertex2 = v2;
18	self_.m_one_sided = false;
19}
20
21pub fn b2_shape_dyn_trait_clone(self_: &B2edgeShape) -> Box<dyn B2shapeDynTrait> {
22	return Box::new(B2edgeShape::clone(&self_));
23}
24
25pub fn b2_shape_dyn_trait_get_child_count(_self: &B2edgeShape) -> usize {
26	return 1;
27}
28
29pub fn b2_shape_dyn_trait_test_point(_self: &B2edgeShape, xf: B2Transform, p: B2vec2) -> bool {
30	b2_not_used(xf);
31	b2_not_used(p);
32	return false;
33}
34
35// p = p1 + t * d
36// v = v1 + s * e
37// p1 + t * d = v1 + s * e
38// s * e - t * d = p1 - v1
39pub fn b2_shape_dyn_trait_ray_cast(
40	self_: &B2edgeShape,
41	output: &mut B2rayCastOutput,
42	input: &B2rayCastInput,
43	xf: B2Transform,
44	child_index: usize,
45) -> bool {
46	b2_not_used(child_index);
47
48	// Put the ray into the edge's frame of reference.
49	let p1: B2vec2 = b2_mul_t_rot_by_vec2(xf.q, input.p1 - xf.p);
50	let p2: B2vec2 = b2_mul_t_rot_by_vec2(xf.q, input.p2 - xf.p);
51	let d: B2vec2 = p2 - p1;
52
53	let v1: B2vec2 = self_.m_vertex1;
54	let v2: B2vec2 = self_.m_vertex2;
55	let e: B2vec2 = v2 - v1;
56	// Normal points to the right, looking from v1 at v2
57	let mut normal = B2vec2 { x: e.y, y: -e.x };
58	normal.normalize();
59
60	// q = p1 + t * d
61	// dot(normal, q - v1) = 0
62	// dot(normal, p1 - v1) + t * dot(normal, d) = 0
63	let numerator: f32 = b2_dot(normal, v1 - p1);
64	
65	if self_.m_one_sided && numerator > 0.0 {
66		return false;
67	}
68
69	let denominator: f32 = b2_dot(normal, d);
70	if denominator == 0.0
71	{
72		return false;
73	}
74	let t: f32 = numerator / denominator;
75	if t < 0.0 || input.max_fraction < t
76	{
77		return false;
78	}
79
80	let q: B2vec2 = p1 + t * d;
81
82	// q = v1 + s * r
83	// s = dot(q - v1, r) / dot(r, r)
84	let r: B2vec2 = v2 - v1;
85	let rr: f32 = b2_dot(r, r);
86	if rr == 0.0 {
87		return false;
88	}
89
90	let s: f32 = b2_dot(q - v1, r) / rr;
91	if s < 0.0 || 1.0 < s {
92		return false;
93	}
94
95	output.fraction = t;
96	if numerator > 0.0 {
97		output.normal = -b2_mul_rot_by_vec2(xf.q, normal);
98	} else {
99		output.normal = b2_mul_rot_by_vec2(xf.q, normal);
100	}
101	return true;
102}
103
104pub fn b2_shape_dyn_trait_compute_aabb(
105	self_: &B2edgeShape,
106	aabb: &mut B2AABB,
107	xf: B2Transform,
108	child_index: usize,
109) {
110	b2_not_used(child_index);
111
112	let v1: B2vec2 = b2_mul_transform_by_vec2(xf, self_.m_vertex1);
113	let v2: B2vec2 = b2_mul_transform_by_vec2(xf, self_.m_vertex2);
114
115	let lower: B2vec2 = b2_min_vec2(v1, v2);
116	let upper: B2vec2 = b2_max_vec2(v1, v2);
117
118	let r = B2vec2 {
119		x: self_.base.m_radius,
120		y: self_.base.m_radius,
121	};
122	aabb.lower_bound = lower - r;
123	aabb.upper_bound = upper + r;
124}
125
126pub fn b2_shape_dyn_trait_compute_mass(self_: &B2edgeShape, mass_data: &mut B2massData, density: f32) {
127	b2_not_used(density);
128
129	mass_data.mass = 0.0;
130	mass_data.center = 0.5 * (self_.m_vertex1 + self_.m_vertex2);
131	mass_data.i = 0.0;
132}