il2cpp_bridge_rs/structs/components/rendering/
camera.rs1use super::screen::Screen;
3use crate::api::cache;
4use crate::structs::collections::Il2cppArray;
5use crate::structs::components::{Component, ComponentTrait};
6use crate::structs::math::{Matrix4x4, Ray, Vector2, Vector3};
7use std::ffi::c_void;
8use std::ops::Deref;
9
10#[repr(i32)]
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum CameraEye {
13 Left = 0,
14 Right = 1,
15 Mono = 2,
16}
17
18#[repr(C)]
19#[derive(Debug, Clone, Copy)]
20pub struct Camera {
21 pub component: Component,
23}
24
25impl ComponentTrait for Camera {
26 fn from_ptr(ptr: *mut c_void) -> Self {
27 Self {
28 component: Component::from_ptr(ptr),
29 }
30 }
31}
32
33impl Deref for Camera {
34 type Target = Component;
35 fn deref(&self) -> &Self::Target {
36 &self.component
37 }
38}
39
40impl Camera {
41 pub fn get_class() -> Option<crate::structs::core::Class> {
46 cache::coremodule().class("UnityEngine.Camera")
47 }
48
49 pub fn get_main() -> Result<Option<Camera>, String> {
54 let class = Self::get_class().ok_or("Class 'UnityEngine.Camera' not found")?;
55 let method = class
56 .method("get_main")
57 .ok_or("Method 'get_main' not found")?;
58 unsafe {
59 let ptr = method.call::<*mut c_void>(&[])?;
60 if ptr.is_null() {
61 Ok(None)
62 } else {
63 Ok(Some(Camera::from_ptr(ptr)))
64 }
65 }
66 }
67
68 pub fn get_current() -> Result<Option<Camera>, String> {
73 let class = Self::get_class().ok_or("Class 'UnityEngine.Camera' not found")?;
74 let method = class
75 .method("get_current")
76 .ok_or("Method 'get_current' not found")?;
77 unsafe {
78 let ptr = method.call::<*mut c_void>(&[])?;
79 if ptr.is_null() {
80 Ok(None)
81 } else {
82 Ok(Some(Camera::from_ptr(ptr)))
83 }
84 }
85 }
86
87 pub fn get_all_count() -> Result<i32, String> {
92 let class = Self::get_class().ok_or("Class 'UnityEngine.Camera' not found")?;
93 let method = class
94 .method("get_allCamerasCount")
95 .ok_or("Method 'get_allCamerasCount' not found")?;
96 unsafe { method.call::<i32>(&[]) }
97 }
98
99 pub fn get_all_cameras() -> Result<Vec<Camera>, String> {
104 let class = Self::get_class().ok_or("Class 'UnityEngine.Camera' not found")?;
105 let method = class
106 .method("GetAllCameras")
107 .ok_or("Method 'GetAllCameras' not found")?;
108
109 let count = Self::get_all_count()?;
110 if count == 0 {
111 return Ok(Vec::new());
112 }
113
114 let array_ptr = Il2cppArray::<*mut c_void>::new(&class, count as usize);
115 if array_ptr.is_null() {
116 return Err("Failed to create array".to_string());
117 }
118
119 unsafe {
120 method.call::<i32>(&[array_ptr as *mut c_void])?;
121
122 let array = &*array_ptr;
123 let mut cameras = Vec::with_capacity(count as usize);
124 for i in 0..count as usize {
125 let ptr = array.at(i);
126 if !ptr.is_null() {
127 cameras.push(Camera::from_ptr(ptr));
128 }
129 }
130 Ok(cameras)
131 }
132 }
133
134 pub fn get_depth(&self) -> Result<f32, String> {
139 unsafe {
140 self.method("get_depth")
141 .ok_or("Method 'get_depth' not found")?
142 .call::<f32>(&[])
143 }
144 }
145
146 pub fn set_depth(&self, depth: f32) -> Result<(), String> {
154 unsafe {
155 self.method("set_depth")
156 .ok_or("Method 'set_depth' not found")?
157 .call::<()>(&[&depth as *const f32 as *mut c_void])?;
158 }
159 Ok(())
160 }
161
162 pub fn get_field_of_view(&self) -> Result<f32, String> {
167 unsafe {
168 self.method("get_fieldOfView")
169 .ok_or("Method 'get_fieldOfView' not found")?
170 .call::<f32>(&[])
171 }
172 }
173
174 pub fn set_field_of_view(&self, fov: f32) -> Result<(), String> {
182 unsafe {
183 self.method("set_fieldOfView")
184 .ok_or("Method 'set_fieldOfView' not found")?
185 .call::<()>(&[&fov as *const f32 as *mut c_void])?;
186 }
187 Ok(())
188 }
189
190 pub fn world_to_screen_point(
199 &self,
200 position: Vector3,
201 eye: CameraEye,
202 ) -> Result<Vector3, String> {
203 unsafe {
204 self.method("WorldToScreenPoint")
205 .ok_or("Method 'WorldToScreenPoint' not found")?
206 .call::<Vector3>(&[
207 &position as *const Vector3 as *mut c_void,
208 &eye as *const CameraEye as *mut c_void,
209 ])
210 }
211 }
212
213 pub fn screen_to_world_point(
222 &self,
223 position: Vector3,
224 eye: CameraEye,
225 ) -> Result<Vector3, String> {
226 unsafe {
227 self.method("ScreenToWorldPoint")
228 .ok_or("Method 'ScreenToWorldPoint' not found")?
229 .call::<Vector3>(&[
230 &position as *const Vector3 as *mut c_void,
231 &eye as *const CameraEye as *mut c_void,
232 ])
233 }
234 }
235
236 pub fn camera_to_world_matrix(&self) -> Result<Matrix4x4, String> {
241 unsafe {
242 self.method("get_cameraToWorldMatrix")
243 .ok_or("Method 'get_cameraToWorldMatrix' not found")?
244 .call::<Matrix4x4>(&[])
245 }
246 }
247
248 pub fn world_to_screen(
257 &self,
258 position: Vector3,
259 eye: CameraEye,
260 ) -> Result<(Vector2, bool), String> {
261 let mut screen_point = self.world_to_screen_point(position, eye)?;
262
263 if screen_point.z < 0.01 {
264 return Ok((Vector2 { x: 0.0, y: 0.0 }, false));
265 }
266
267 let screen_width = Screen::get_width()? as f32;
268 let screen_height = Screen::get_height()? as f32;
269
270 screen_point.y = screen_height - screen_point.y;
271
272 let on_screen = screen_point.x > 0.0
273 && screen_point.x < screen_width
274 && screen_point.y > 0.0
275 && screen_point.y < screen_height;
276
277 Ok((
278 Vector2 {
279 x: screen_point.x,
280 y: screen_point.y,
281 },
282 on_screen,
283 ))
284 }
285
286 pub fn screen_point_to_ray(&self, position: Vector2, eye: CameraEye) -> Result<Ray, String> {
295 unsafe {
296 self.method("ScreenPointToRay")
297 .ok_or("Method 'ScreenPointToRay' not found")?
298 .call::<Ray>(&[
299 &position as *const Vector2 as *mut c_void,
300 &eye as *const CameraEye as *mut c_void,
301 ])
302 }
303 }
304}