1use crate::ffi;
2use static_assertions::{assert_eq_align, assert_eq_size};
3use std::mem::transmute;
4
5pub use crate::ffi::{CameraMode, CameraProjection};
6
7pub type Vector2 = mint::Vector2<f32>;
9assert_eq_size!(Vector2, ffi::Vector2);
10assert_eq_align!(Vector2, ffi::Vector2);
11
12impl From<Vector2> for ffi::Vector2 {
13 #[inline]
14 fn from(val: Vector2) -> Self {
15 unsafe { transmute(val) }
16 }
17}
18
19impl From<ffi::Vector2> for Vector2 {
20 #[inline]
21 fn from(value: ffi::Vector2) -> Self {
22 unsafe { transmute(value) }
23 }
24}
25
26pub type Vector3 = mint::Vector3<f32>;
28assert_eq_size!(Vector3, ffi::Vector3);
29assert_eq_align!(Vector3, ffi::Vector3);
30
31impl From<Vector3> for ffi::Vector3 {
32 #[inline]
33 fn from(val: Vector3) -> Self {
34 unsafe { transmute(val) }
35 }
36}
37
38impl From<ffi::Vector3> for Vector3 {
39 #[inline]
40 fn from(value: ffi::Vector3) -> Self {
41 unsafe { transmute(value) }
42 }
43}
44
45pub type Vector4 = mint::Vector4<f32>;
47assert_eq_size!(Vector4, ffi::Vector4);
48assert_eq_align!(Vector4, ffi::Vector4);
49
50impl From<Vector4> for ffi::Vector4 {
51 #[inline]
52 fn from(val: Vector4) -> Self {
53 unsafe { transmute(val) }
54 }
55}
56
57impl From<ffi::Vector4> for Vector4 {
58 #[inline]
59 fn from(value: ffi::Vector4) -> Self {
60 unsafe { transmute(value) }
61 }
62}
63
64pub type Quaternion = mint::Quaternion<f32>;
66assert_eq_size!(Quaternion, ffi::Quaternion);
67assert_eq_align!(Quaternion, ffi::Quaternion);
68
69impl From<Quaternion> for ffi::Vector4 {
70 #[inline]
71 fn from(val: Quaternion) -> Self {
72 unsafe { transmute(val) }
73 }
74}
75
76impl From<ffi::Vector4> for Quaternion {
77 #[inline]
78 fn from(value: ffi::Vector4) -> Self {
79 unsafe { transmute(value) }
80 }
81}
82
83pub type Matrix = mint::ColumnMatrix4<f32>;
85assert_eq_size!(Matrix, ffi::Matrix);
86assert_eq_align!(Matrix, ffi::Matrix);
87
88impl From<Matrix> for ffi::Matrix {
89 #[inline]
90 fn from(val: Matrix) -> Self {
91 unsafe { transmute(val) }
92 }
93}
94
95impl From<ffi::Matrix> for Matrix {
96 #[inline]
97 fn from(value: ffi::Matrix) -> Self {
98 unsafe { transmute(value) }
99 }
100}
101
102#[repr(C)]
104#[derive(Clone, Copy, Debug, PartialEq)]
105#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
106pub struct Rectangle {
107 pub x: f32,
109 pub y: f32,
111 pub width: f32,
113 pub height: f32,
115}
116
117assert_eq_size!(Rectangle, ffi::Rectangle);
118assert_eq_align!(Rectangle, ffi::Rectangle);
119
120impl Rectangle {
121 #[inline]
123 pub const fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
124 Self {
125 x,
126 y,
127 width,
128 height,
129 }
130 }
131}
132
133impl From<Rectangle> for ffi::Rectangle {
134 #[inline]
135 fn from(val: Rectangle) -> Self {
136 unsafe { transmute(val) }
137 }
138}
139
140impl From<ffi::Rectangle> for Rectangle {
141 #[inline]
142 fn from(value: ffi::Rectangle) -> Self {
143 unsafe { transmute(value) }
144 }
145}
146
147#[repr(C)]
149#[derive(Clone, Copy, Debug, PartialEq)]
150pub struct Ray {
151 pub position: Vector3,
153 pub direction: Vector3,
155}
156
157assert_eq_size!(Ray, ffi::Ray);
158assert_eq_align!(Ray, ffi::Ray);
159
160impl From<Ray> for ffi::Ray {
161 #[inline]
162 fn from(val: Ray) -> Self {
163 unsafe { transmute(val) }
164 }
165}
166
167impl From<ffi::Ray> for Ray {
168 #[inline]
169 fn from(value: ffi::Ray) -> Self {
170 unsafe { transmute(value) }
171 }
172}
173
174#[repr(C)]
176#[derive(Clone, Copy, Debug, PartialEq)]
177pub struct RayCollision {
178 pub hit: bool,
180 pub distance: f32,
182 pub point: Vector3,
184 pub normal: Vector3,
186}
187
188assert_eq_size!(RayCollision, ffi::RayCollision);
189assert_eq_align!(RayCollision, ffi::RayCollision);
190
191impl From<RayCollision> for ffi::RayCollision {
192 #[inline]
193 fn from(val: RayCollision) -> Self {
194 unsafe { transmute(val) }
195 }
196}
197
198impl From<ffi::RayCollision> for RayCollision {
199 #[inline]
200 fn from(value: ffi::RayCollision) -> Self {
201 unsafe { transmute(value) }
202 }
203}
204
205#[repr(C)]
207#[derive(Clone, Copy, Debug, PartialEq)]
208pub struct BoundingBox {
209 pub min: Vector3,
211 pub max: Vector3,
213}
214
215assert_eq_size!(Ray, ffi::BoundingBox);
216assert_eq_align!(Ray, ffi::BoundingBox);
217
218impl From<BoundingBox> for ffi::BoundingBox {
219 #[inline]
220 fn from(val: BoundingBox) -> Self {
221 unsafe { transmute(val) }
222 }
223}
224
225impl From<ffi::BoundingBox> for BoundingBox {
226 #[inline]
227 fn from(value: ffi::BoundingBox) -> Self {
228 unsafe { transmute(value) }
229 }
230}
231
232#[repr(C)]
234#[derive(Clone, Copy, Debug, PartialEq)]
235pub struct Transform {
236 pub translation: Vector3,
238 pub rotation: Quaternion,
240 pub scale: Vector3,
242}
243
244assert_eq_size!(Transform, ffi::Transform);
245assert_eq_align!(Transform, ffi::Transform);
246
247impl From<Transform> for ffi::Transform {
248 #[inline]
249 fn from(val: Transform) -> Self {
250 unsafe { transmute(val) }
251 }
252}
253
254impl From<ffi::Transform> for Transform {
255 #[inline]
256 fn from(value: ffi::Transform) -> Self {
257 unsafe { transmute(value) }
258 }
259}
260
261#[repr(C)]
263#[derive(Clone, Copy, Debug, PartialEq)]
264#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
265pub struct Camera2D {
266 pub offset: Vector2,
268 pub target: Vector2,
270 pub rotation: f32,
272 pub zoom: f32,
274}
275
276assert_eq_size!(Camera2D, ffi::Camera2D);
277assert_eq_align!(Camera2D, ffi::Camera2D);
278
279impl Camera2D {
280 #[inline]
282 pub fn get_matrix(&self) -> Matrix {
283 unsafe { ffi::GetCameraMatrix2D((*self).into()).into() }
284 }
285
286 #[inline]
288 pub fn screen_to_world(&self, position: Vector2) -> Vector2 {
289 unsafe { ffi::GetScreenToWorld2D(position.into(), (*self).into()).into() }
290 }
291
292 #[inline]
294 pub fn world_to_screen(&self, position: Vector2) -> Vector2 {
295 unsafe { ffi::GetWorldToScreen2D(position.into(), (*self).into()).into() }
296 }
297}
298
299impl From<Camera2D> for ffi::Camera2D {
300 #[inline]
301 fn from(val: Camera2D) -> Self {
302 unsafe { transmute(val) }
303 }
304}
305
306impl From<ffi::Camera2D> for Camera2D {
307 #[inline]
308 fn from(value: ffi::Camera2D) -> Self {
309 unsafe { transmute(value) }
310 }
311}
312
313#[repr(C)]
315#[derive(Clone, Copy, Debug, PartialEq)]
316#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
317pub struct Camera3D {
318 pub position: Vector3,
320 pub target: Vector3,
322 pub up: Vector3,
324 pub fovy: f32,
326 pub projection: CameraProjection,
328}
329
330assert_eq_size!(Camera3D, ffi::Camera3D);
331assert_eq_align!(Camera3D, ffi::Camera3D);
332
333impl Camera3D {
334 #[inline]
336 pub fn update(&mut self, mode: CameraMode) {
337 unsafe { ffi::UpdateCamera(self as *mut Camera3D as *mut ffi::Camera3D, mode as _) }
338 }
339
340 #[inline]
342 pub fn update_pro(&mut self, movement: Vector3, rotation: Vector3, zoom: f32) {
343 unsafe {
344 ffi::UpdateCameraPro(
345 self as *mut Camera3D as *mut ffi::Camera3D,
346 movement.into(),
347 rotation.into(),
348 zoom,
349 )
350 }
351 }
352
353 #[inline]
355 pub fn get_mouse_ray(&self, mouse_position: Vector2) -> Ray {
356 unsafe { ffi::GetMouseRay(mouse_position.into(), (*self).into()).into() }
357 }
358
359 #[inline]
361 pub fn get_matrix(&self) -> Matrix {
362 unsafe { ffi::GetCameraMatrix((*self).into()).into() }
363 }
364
365 #[inline]
367 pub fn world_to_screen(&self, position: Vector3) -> Vector2 {
368 unsafe { ffi::GetWorldToScreen(position.into(), (*self).into()).into() }
369 }
370
371 #[inline]
373 pub fn world_to_screen_ex(&self, position: Vector3, width: u32, height: u32) -> Vector2 {
374 unsafe {
375 ffi::GetWorldToScreenEx(
376 position.into(),
377 (*self).into(),
378 width as _,
379 height as _,
380 )
381 .into()
382 }
383 }
384}
385
386impl From<Camera3D> for ffi::Camera3D {
387 #[inline]
388 fn from(val: Camera3D) -> Self {
389 unsafe { transmute(val) }
390 }
391}
392
393impl From<ffi::Camera3D> for Camera3D {
394 #[inline]
395 fn from(value: ffi::Camera3D) -> Self {
396 if value.projection != CameraProjection::Orthographic as i32
397 && value.projection != CameraProjection::Perspective as i32
398 {
399 panic!(
400 "Attempted to convert a ffi::Camera3D with an invalid projection value: {}",
401 value.projection
402 );
403 }
404
405 unsafe { transmute(value) }
406 }
407}
408
409pub type Camera = Camera3D;