dora_ssr/dora/
body.rs

1/* Copyright (c) 2016-2025 Li Jin <dragon-fly@qq.com>
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
5The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
7THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
8
9extern "C" {
10	fn body_type() -> i32;
11	fn body_get_world(slf: i64) -> i64;
12	fn body_get_body_def(slf: i64) -> i64;
13	fn body_get_mass(slf: i64) -> f32;
14	fn body_is_sensor(slf: i64) -> i32;
15	fn body_set_velocity_x(slf: i64, val: f32);
16	fn body_get_velocity_x(slf: i64) -> f32;
17	fn body_set_velocity_y(slf: i64, val: f32);
18	fn body_get_velocity_y(slf: i64) -> f32;
19	fn body_set_velocity(slf: i64, val: i64);
20	fn body_get_velocity(slf: i64) -> i64;
21	fn body_set_angular_rate(slf: i64, val: f32);
22	fn body_get_angular_rate(slf: i64) -> f32;
23	fn body_set_group(slf: i64, val: i32);
24	fn body_get_group(slf: i64) -> i32;
25	fn body_set_linear_damping(slf: i64, val: f32);
26	fn body_get_linear_damping(slf: i64) -> f32;
27	fn body_set_angular_damping(slf: i64, val: f32);
28	fn body_get_angular_damping(slf: i64) -> f32;
29	fn body_set_owner(slf: i64, val: i64);
30	fn body_get_owner(slf: i64) -> i64;
31	fn body_set_receiving_contact(slf: i64, val: i32);
32	fn body_is_receiving_contact(slf: i64) -> i32;
33	fn body_apply_linear_impulse(slf: i64, impulse: i64, pos: i64);
34	fn body_apply_angular_impulse(slf: i64, impulse: f32);
35	fn body_get_sensor_by_tag(slf: i64, tag: i32) -> i64;
36	fn body_remove_sensor_by_tag(slf: i64, tag: i32) -> i32;
37	fn body_remove_sensor(slf: i64, sensor: i64) -> i32;
38	fn body_attach(slf: i64, fixture_def: i64);
39	fn body_attach_sensor(slf: i64, tag: i32, fixture_def: i64) -> i64;
40	fn body_on_contact_filter(slf: i64, func0: i32, stack0: i64);
41	fn body_new(def: i64, world: i64, pos: i64, rot: f32) -> i64;
42}
43use crate::dora::IObject;
44use crate::dora::INode;
45impl INode for Body { }
46/// A struct represents a physics body in the world.
47pub struct Body { raw: i64 }
48crate::dora_object!(Body);
49impl IBody for Body { }
50pub trait IBody: INode {
51	/// Gets the physics world that the body belongs to.
52	fn get_world(&self) -> crate::dora::PhysicsWorld {
53		return unsafe { crate::dora::PhysicsWorld::from(body_get_world(self.raw())).unwrap() };
54	}
55	/// Gets the definition of the body.
56	fn get_body_def(&self) -> crate::dora::BodyDef {
57		return unsafe { crate::dora::BodyDef::from(body_get_body_def(self.raw())).unwrap() };
58	}
59	/// Gets the mass of the body.
60	fn get_mass(&self) -> f32 {
61		return unsafe { body_get_mass(self.raw()) };
62	}
63	/// Gets whether the body is used as a sensor or not.
64	fn is_sensor(&self) -> bool {
65		return unsafe { body_is_sensor(self.raw()) != 0 };
66	}
67	/// Sets the x-axis velocity of the body.
68	fn set_velocity_x(&mut self, val: f32) {
69		unsafe { body_set_velocity_x(self.raw(), val) };
70	}
71	/// Gets the x-axis velocity of the body.
72	fn get_velocity_x(&self) -> f32 {
73		return unsafe { body_get_velocity_x(self.raw()) };
74	}
75	/// Sets the y-axis velocity of the body.
76	fn set_velocity_y(&mut self, val: f32) {
77		unsafe { body_set_velocity_y(self.raw(), val) };
78	}
79	/// Gets the y-axis velocity of the body.
80	fn get_velocity_y(&self) -> f32 {
81		return unsafe { body_get_velocity_y(self.raw()) };
82	}
83	/// Sets the velocity of the body as a `Vec2`.
84	fn set_velocity(&mut self, val: &crate::dora::Vec2) {
85		unsafe { body_set_velocity(self.raw(), val.into_i64()) };
86	}
87	/// Gets the velocity of the body as a `Vec2`.
88	fn get_velocity(&self) -> crate::dora::Vec2 {
89		return unsafe { crate::dora::Vec2::from(body_get_velocity(self.raw())) };
90	}
91	/// Sets the angular rate of the body.
92	fn set_angular_rate(&mut self, val: f32) {
93		unsafe { body_set_angular_rate(self.raw(), val) };
94	}
95	/// Gets the angular rate of the body.
96	fn get_angular_rate(&self) -> f32 {
97		return unsafe { body_get_angular_rate(self.raw()) };
98	}
99	/// Sets the collision group that the body belongs to.
100	fn set_group(&mut self, val: i32) {
101		unsafe { body_set_group(self.raw(), val) };
102	}
103	/// Gets the collision group that the body belongs to.
104	fn get_group(&self) -> i32 {
105		return unsafe { body_get_group(self.raw()) };
106	}
107	/// Sets the linear damping of the body.
108	fn set_linear_damping(&mut self, val: f32) {
109		unsafe { body_set_linear_damping(self.raw(), val) };
110	}
111	/// Gets the linear damping of the body.
112	fn get_linear_damping(&self) -> f32 {
113		return unsafe { body_get_linear_damping(self.raw()) };
114	}
115	/// Sets the angular damping of the body.
116	fn set_angular_damping(&mut self, val: f32) {
117		unsafe { body_set_angular_damping(self.raw(), val) };
118	}
119	/// Gets the angular damping of the body.
120	fn get_angular_damping(&self) -> f32 {
121		return unsafe { body_get_angular_damping(self.raw()) };
122	}
123	/// Sets the reference for an owner of the body.
124	fn set_owner(&mut self, val: &dyn crate::dora::IObject) {
125		unsafe { body_set_owner(self.raw(), val.raw()) };
126	}
127	/// Gets the reference for an owner of the body.
128	fn get_owner(&self) -> crate::dora::Object {
129		return unsafe { crate::dora::Object::from(body_get_owner(self.raw())).unwrap() };
130	}
131	/// Sets whether the body is currently receiving contact events or not.
132	fn set_receiving_contact(&mut self, val: bool) {
133		unsafe { body_set_receiving_contact(self.raw(), if val { 1 } else { 0 }) };
134	}
135	/// Gets whether the body is currently receiving contact events or not.
136	fn is_receiving_contact(&self) -> bool {
137		return unsafe { body_is_receiving_contact(self.raw()) != 0 };
138	}
139	/// Applies a linear impulse to the body at a specified position.
140	///
141	/// # Arguments
142	///
143	/// * `impulse` - The linear impulse to apply.
144	/// * `pos` - The position at which to apply the impulse.
145	fn apply_linear_impulse(&mut self, impulse: &crate::dora::Vec2, pos: &crate::dora::Vec2) {
146		unsafe { body_apply_linear_impulse(self.raw(), impulse.into_i64(), pos.into_i64()); }
147	}
148	/// Applies an angular impulse to the body.
149	///
150	/// # Arguments
151	///
152	/// * `impulse` - The angular impulse to apply.
153	fn apply_angular_impulse(&mut self, impulse: f32) {
154		unsafe { body_apply_angular_impulse(self.raw(), impulse); }
155	}
156	/// Returns the sensor with the given tag.
157	///
158	/// # Arguments
159	///
160	/// * `tag` - The tag of the sensor to get.
161	///
162	/// # Returns
163	///
164	/// * `Sensor` - The sensor with the given tag.
165	fn get_sensor_by_tag(&mut self, tag: i32) -> crate::dora::Sensor {
166		unsafe { return crate::dora::Sensor::from(body_get_sensor_by_tag(self.raw(), tag)).unwrap(); }
167	}
168	/// Removes the sensor with the specified tag from the body.
169	///
170	/// # Arguments
171	///
172	/// * `tag` - The tag of the sensor to remove.
173	///
174	/// # Returns
175	///
176	/// * `bool` - Whether a sensor with the specified tag was found and removed.
177	fn remove_sensor_by_tag(&mut self, tag: i32) -> bool {
178		unsafe { return body_remove_sensor_by_tag(self.raw(), tag) != 0; }
179	}
180	/// Removes the given sensor from the body's sensor list.
181	///
182	/// # Arguments
183	///
184	/// * `sensor` - The sensor to remove.
185	///
186	/// # Returns
187	///
188	/// * `bool` - `true` if the sensor was successfully removed, `false` otherwise.
189	fn remove_sensor(&mut self, sensor: &crate::dora::Sensor) -> bool {
190		unsafe { return body_remove_sensor(self.raw(), sensor.raw()) != 0; }
191	}
192	/// Attaches a fixture to the body.
193	///
194	/// # Arguments
195	///
196	/// * `fixture_def` - The fixture definition for the fixture to attach.
197	fn attach(&mut self, fixture_def: &crate::dora::FixtureDef) {
198		unsafe { body_attach(self.raw(), fixture_def.raw()); }
199	}
200	/// Attaches a new sensor with the given tag and fixture definition to the body.
201	///
202	/// # Arguments
203	///
204	/// * `tag` - The tag of the sensor to attach.
205	/// * `fixture_def` - The fixture definition of the sensor.
206	///
207	/// # Returns
208	///
209	/// * `Sensor` - The newly attached sensor.
210	fn attach_sensor(&mut self, tag: i32, fixture_def: &crate::dora::FixtureDef) -> crate::dora::Sensor {
211		unsafe { return crate::dora::Sensor::from(body_attach_sensor(self.raw(), tag, fixture_def.raw())).unwrap(); }
212	}
213	/// Registers a function to be called when the body begins to receive contact events. Return `false` from this function to prevent colliding.
214	///
215	/// # Arguments
216	///
217	/// * `filter` - The filter function to set.
218	fn on_contact_filter(&mut self, mut filter: Box<dyn FnMut(&dyn crate::dora::IBody) -> bool>) {
219		let mut stack0 = crate::dora::CallStack::new();
220		let stack_raw0 = stack0.raw();
221		let func_id0 = crate::dora::push_function(Box::new(move || {
222			let result = filter(&stack0.pop_cast::<crate::dora::Body>().unwrap());
223			stack0.push_bool(result);
224		}));
225		unsafe { body_on_contact_filter(self.raw(), func_id0, stack_raw0); }
226	}
227}
228impl Body {
229	pub(crate) fn type_info() -> (i32, fn(i64) -> Option<Box<dyn IObject>>) {
230		(unsafe { body_type() }, |raw: i64| -> Option<Box<dyn IObject>> {
231			match raw {
232				0 => None,
233				_ => Some(Box::new(Body { raw: raw }))
234			}
235		})
236	}
237	/// Creates a new instance of `Body`.
238	///
239	/// # Arguments
240	///
241	/// * `def` - The definition for the body to be created.
242	/// * `world` - The physics world where the body belongs.
243	/// * `pos` - The initial position of the body.
244	/// * `rot` - The initial rotation angle of the body in degrees.
245	///
246	/// # Returns
247	///
248	/// * A new `Body` instance.
249	pub fn new(def: &crate::dora::BodyDef, world: &dyn crate::dora::IPhysicsWorld, pos: &crate::dora::Vec2, rot: f32) -> Body {
250		unsafe { return Body { raw: body_new(def.raw(), world.raw(), pos.into_i64(), rot) }; }
251	}
252}