pybevy_math/bounding/
raycast.rs1use bevy::math::{
2 Ray3d, Vec2, Vec3,
3 bounding::{IntersectsVolume, RayCast2d, RayCast3d},
4};
5use pyo3::prelude::*;
6
7use super::{
8 aabb2d::PyAabb2d, aabb3d::PyAabb3d, bounding_circle::PyBoundingCircle,
9 bounding_sphere::PyBoundingSphere,
10};
11use crate::{
12 dir2::PyDir2,
13 dir3::PyDir3,
14 ray::{PyRay2d, PyRay3d},
15 vec2::PyVec2,
16 vec3::PyVec3,
17};
18
19#[pyclass(name = "RayCast2d")]
20#[derive(Debug, Clone)]
21pub struct PyRayCast2d {
22 ray_cast: RayCast2d,
23}
24
25impl From<PyRayCast2d> for RayCast2d {
26 fn from(py_raycast: PyRayCast2d) -> Self {
27 py_raycast.ray_cast
28 }
29}
30
31impl From<&PyRayCast2d> for RayCast2d {
32 fn from(py_raycast: &PyRayCast2d) -> Self {
33 py_raycast.ray_cast.clone()
34 }
35}
36
37impl From<RayCast2d> for PyRayCast2d {
38 fn from(ray_cast: RayCast2d) -> Self {
39 PyRayCast2d { ray_cast }
40 }
41}
42
43#[pymethods]
44impl PyRayCast2d {
45 #[new]
46 pub fn new(origin: PyVec2, direction: PyDir2, max: f32) -> Self {
47 let origin_vec: Vec2 = origin.into();
48 let dir = direction.get();
49 PyRayCast2d {
50 ray_cast: RayCast2d::new(origin_vec, dir, max),
51 }
52 }
53
54 #[staticmethod]
55 pub fn from_ray(ray: &PyRay2d, max: f32) -> Self {
56 PyRayCast2d {
57 ray_cast: RayCast2d::from_ray(ray.to_ray2d(), max),
58 }
59 }
60
61 #[getter]
62 pub fn ray(&self) -> PyRay2d {
63 PyRay2d::from_ray2d(self.ray_cast.ray)
64 }
65
66 #[getter]
67 pub fn max(&self) -> f32 {
68 self.ray_cast.max
69 }
70
71 pub fn intersects_aabb(&self, aabb: &PyAabb2d) -> bool {
72 let aabb_2d: bevy::math::bounding::Aabb2d = aabb.into();
73 self.ray_cast.intersects(&aabb_2d)
74 }
75
76 pub fn intersects_circle(&self, circle: &PyBoundingCircle) -> bool {
77 let bounding_circle: bevy::math::bounding::BoundingCircle = circle.into();
78 self.ray_cast.intersects(&bounding_circle)
79 }
80
81 pub fn aabb_intersection_at(&self, aabb: &PyAabb2d) -> Option<f32> {
82 let aabb_2d: bevy::math::bounding::Aabb2d = aabb.into();
83 self.ray_cast.aabb_intersection_at(&aabb_2d)
84 }
85
86 pub fn circle_intersection_at(&self, circle: &PyBoundingCircle) -> Option<f32> {
87 let bounding_circle: bevy::math::bounding::BoundingCircle = circle.into();
88 self.ray_cast.circle_intersection_at(&bounding_circle)
89 }
90
91 pub fn direction_recip(&self) -> PyVec2 {
92 PyVec2::from_vec2(self.ray_cast.direction_recip())
93 }
94
95 fn __repr__(&self) -> String {
96 format!(
97 "RayCast2d(ray={:?}, max={})",
98 self.ray_cast.ray, self.ray_cast.max
99 )
100 }
101}
102
103#[pyclass(name = "RayCast3d")]
104#[derive(Debug, Clone)]
105pub struct PyRayCast3d {
106 ray_cast: RayCast3d,
107}
108
109impl From<PyRayCast3d> for RayCast3d {
110 fn from(py_raycast: PyRayCast3d) -> Self {
111 py_raycast.ray_cast
112 }
113}
114
115impl From<&PyRayCast3d> for RayCast3d {
116 fn from(py_raycast: &PyRayCast3d) -> Self {
117 py_raycast.ray_cast.clone()
118 }
119}
120
121impl From<RayCast3d> for PyRayCast3d {
122 fn from(ray_cast: RayCast3d) -> Self {
123 PyRayCast3d { ray_cast }
124 }
125}
126
127#[pymethods]
128impl PyRayCast3d {
129 #[new]
130 pub fn new(origin: PyVec3, direction: PyDir3, max: f32) -> Self {
131 let origin_vec: Vec3 = origin.into();
132 let dir = direction.get();
133 PyRayCast3d {
134 ray_cast: RayCast3d::new(origin_vec, dir, max),
135 }
136 }
137
138 #[staticmethod]
139 pub fn from_ray(ray: &PyRay3d, max: f32) -> Self {
140 PyRayCast3d {
141 ray_cast: RayCast3d::from_ray(ray.to_ray3d(), max),
142 }
143 }
144
145 #[getter]
146 pub fn ray(&self) -> PyRay3d {
147 let dir3: bevy::math::Dir3 = self.ray_cast.direction.into();
148 let ray = Ray3d::new(self.ray_cast.origin.into(), dir3);
149 PyRay3d::from_ray3d(ray)
150 }
151
152 #[getter]
153 pub fn max(&self) -> f32 {
154 self.ray_cast.max
155 }
156
157 pub fn intersects_aabb(&self, aabb: &PyAabb3d) -> bool {
158 let aabb_3d: bevy::math::bounding::Aabb3d = aabb.into();
159 self.ray_cast.intersects(&aabb_3d)
160 }
161
162 pub fn intersects_sphere(&self, sphere: &PyBoundingSphere) -> bool {
163 let bounding_sphere: bevy::math::bounding::BoundingSphere = sphere.into();
164 self.ray_cast.intersects(&bounding_sphere)
165 }
166
167 pub fn aabb_intersection_at(&self, aabb: &PyAabb3d) -> Option<f32> {
168 let aabb_3d: bevy::math::bounding::Aabb3d = aabb.into();
169 self.ray_cast.aabb_intersection_at(&aabb_3d)
170 }
171
172 pub fn sphere_intersection_at(&self, sphere: &PyBoundingSphere) -> Option<f32> {
173 let bounding_sphere: bevy::math::bounding::BoundingSphere = sphere.into();
174 self.ray_cast.sphere_intersection_at(&bounding_sphere)
175 }
176
177 pub fn direction_recip(&self) -> PyVec3 {
178 PyVec3::from_vec3(self.ray_cast.direction_recip().into())
179 }
180
181 fn __repr__(&self) -> String {
182 format!(
183 "RayCast3d(origin={:?}, direction={:?}, max={})",
184 self.ray_cast.origin, self.ray_cast.direction, self.ray_cast.max
185 )
186 }
187}