Skip to main content

box2d_rs/
b2_body.rs

1use std::cell::RefCell;
2use std::rc::{Rc, Weak};
3
4#[cfg(feature="serde_support")]
5use serde::{Serialize, Deserialize};
6
7use crate::b2_contact::*;
8use crate::b2_fixture::*;
9use crate::b2_joint::*;
10use crate::b2_math::*;
11use crate::b2rs_common::UserDataType;
12use crate::b2_shape::*;
13use crate::b2_world::*;
14use crate::private::dynamics::b2_body as private;
15
16use crate::b2rs_linked_list::*;
17use crate::b2rs_double_linked_list::*;
18
19use bitflags::bitflags;
20
21/// The body type.
22/// static: zero mass, zero velocity, may be manually moved
23/// kinematic: zero mass, non-zero velocity set by user, moved by solver
24/// dynamic: positive mass, non-zero velocity determined by forces, moved by solver
25#[derive(Debug, Copy, Clone, PartialEq)]
26#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
27pub enum B2bodyType {
28	B2StaticBody = 0,
29	B2KinematicBody,
30	B2DynamicBody,
31}
32
33impl Default for B2bodyType {
34	fn default() -> Self {
35		return B2bodyType::B2StaticBody;
36	}
37}
38
39impl<D: UserDataType> Default for B2bodyDef<D> {
40	/// This constructor sets the body definition default values.
41	fn default() -> Self {
42		return Self {
43			position: B2vec2::zero(),
44			angle: 0.0,
45			linear_velocity: B2vec2::zero(),
46			angular_velocity: 0.0,
47			linear_damping: 0.0,
48			angular_damping: 0.0,
49			allow_sleep: true,
50			awake: true,
51			fixed_rotation: false,
52			bullet: false,
53			body_type: B2bodyType::B2StaticBody,
54			enabled: true,
55			gravity_scale: 1.0,
56			user_data: None,
57		};
58	}
59}
60
61impl<D:UserDataType> LinkedListNode<B2body<D>> for B2body<D>
62{
63    fn get_next(&self) -> Option<BodyPtr<D>> {
64        return self.m_next.clone();
65	}
66	fn set_next(&mut self, value: Option<BodyPtr<D>>)
67    {
68        self.m_next = value;
69    }
70	fn take_next(&mut self) -> Option<BodyPtr<D>> {
71		return self.m_next.take();
72	}
73}
74
75impl<D:UserDataType> DoubleLinkedListNode<B2body<D>> for B2body<D>
76{ 	
77	fn get_prev(&self) -> Option<BodyWeakPtr<D>>
78	{
79		return self.m_prev.clone();
80	}
81	fn set_prev(&mut self, value: Option<BodyWeakPtr<D>>)
82	{
83		self.m_prev = value;
84	}
85}
86
87/// A body definition holds all the data needed to construct a rigid body.
88/// You can safely re-use body definitions. Shapes are added to a body after construction.
89#[derive(Debug, Clone)]
90#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
91pub struct B2bodyDef<D: UserDataType> {
92	/// The body type: static, kinematic, or dynamic.
93	/// Note: if a dynamic body would have zero mass, the mass is set to one.
94	pub body_type: B2bodyType,
95
96	/// The world position of the body. Avoid creating bodies at the origin
97	/// since this can lead to many overlapping shapes.
98	pub position: B2vec2,
99
100	/// The world angle of the body in radians.
101	pub angle: f32,
102
103	/// The linear velocity of the body's origin in world co-ordinates.
104	pub linear_velocity: B2vec2,
105
106	/// The angular velocity of the body.
107	pub angular_velocity: f32,
108
109	/// Linear damping is use to reduce the linear velocity. The damping parameter
110	/// can be larger than 1.0 but the damping effect becomes sensitive to the
111	/// time step when the damping parameter is large.
112	/// Units are 1/time
113	pub linear_damping: f32,
114
115	/// Angular damping is use to reduce the angular velocity. The damping parameter
116	/// can be larger than 1.0 but the damping effect becomes sensitive to the
117	/// time step when the damping parameter is large.
118	/// Units are 1/time
119	pub angular_damping: f32,
120
121	/// Set this flag to false if this body should never fall asleep. Note that
122	/// this increases CPU usage.
123	pub allow_sleep: bool,
124
125	/// Is this body initially awake or sleeping?
126	pub awake: bool,
127
128	/// Should this body be prevented from rotating? Useful for characters.
129	pub fixed_rotation: bool,
130
131	/// Is this a fast moving body that should be prevented from tunneling through
132	/// other moving bodies? Note that all bodies are prevented from tunneling through
133	/// kinematic and static bodies. This setting is only considered on dynamic bodies.
134	/// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
135	/// <strong>Warning:</strong> You should use this flag sparingly since it increases processing time.
136	/// </p>
137	pub bullet: bool,
138
139	/// Does this body start out enabled?
140	pub enabled: bool,
141
142	/// Use this to store application specific body data.
143	pub user_data: Option<D::Body>,
144
145	/// Scale the gravity applied to this body.
146	pub gravity_scale: f32,
147}
148
149pub type BodyPtr<D> = Rc<RefCell<B2body<D>>>;
150pub type BodyWeakPtr<D> = Weak<RefCell<B2body<D>>>;
151
152/// A rigid body. These are created via B2world::create_body.
153#[derive(Default)]
154pub struct B2body<D: UserDataType>
155//<BodyData>
156{
157	pub(crate) m_type: B2bodyType,
158
159	pub(crate) m_flags: BodyFlags,
160
161	pub(crate) m_island_index: i32,
162
163	/// the body origin transform
164	pub(crate) m_xf: B2Transform, 
165	/// the swept motion for CCD
166	pub(crate) m_sweep: B2Sweep,  
167
168	pub(crate) m_linear_velocity: B2vec2,
169	pub(crate) m_angular_velocity: f32,
170
171	pub(crate) m_force: B2vec2,
172	pub(crate) m_torque: f32,
173
174	pub(crate) m_world: B2worldWeakPtr<D>,
175	pub(crate) m_prev: Option<BodyWeakPtr<D>>,
176	pub(crate) m_next: Option<BodyPtr<D>>,
177
178	pub(crate) m_fixture_list: LinkedList<B2fixture<D>>,
179	pub(crate) m_fixture_count: i32,
180
181	pub(crate) m_joint_list: DoubleLinkedList<B2jointEdge<D>>,
182	pub(crate) m_contact_list: DoubleLinkedList<B2contactEdge<D>>,
183
184	pub(crate) m_mass: f32,
185	pub(crate) m_inv_mass: f32,
186
187	/// Rotational inertia about the center of mass.
188	pub(crate) m_i: f32,
189	pub(crate) m_inv_i: f32,
190
191	pub(crate) m_linear_damping: f32,
192	pub(crate) m_angular_damping: f32,
193	pub(crate) m_gravity_scale: f32,
194
195	pub(crate) m_sleep_time: f32,
196
197	pub(crate) m_user_data: Option<D::Body>,
198}
199
200
201impl<D: UserDataType> Drop for B2body<D>
202{
203    fn drop(&mut self) {
204		self.m_fixture_list.remove_all();
205    }
206}
207
208
209bitflags! {
210	/// m_flags
211	#[derive(Default)]
212	pub struct BodyFlags: u16 {
213		const E_ISLAND_FLAG		= 0x0001;
214		const E_AWAKE_FLAG			= 0x0002;
215		const E_AUTO_SLEEP_FLAG		= 0x0004;
216		const E_BULLET_FLAG		= 0x0008;
217		const E_FIXED_ROTATION_FLAG	= 0x0010;
218		const E_ENABLED_FLAG		= 0x0020;
219		const E_TOI_FLAG			= 0x0040;
220	}
221}
222
223impl<D: UserDataType> B2body<D> {
224	/// Creates a fixture and attach it to this body. Use this function if you need
225	/// to set some fixture parameters, like friction. Otherwise you can create the
226	/// fixture directly from a shape.
227	/// If the density is non-zero, this function automatically updates the mass of the body.
228	/// Contacts are not created until the next time step.
229	/// * `def` - the fixture definition.
230	/// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
231	/// <strong>Warning:</strong> This function is locked during callbacks.
232	/// </p>
233	pub fn create_fixture(self_: BodyPtr<D>, def: &B2fixtureDef<D>) -> FixturePtr<D> {
234		return private::create_fixture(self_, def);
235	}
236
237	/// Creates a fixture from a shape and attach it to this body.
238	/// This is a convenience function. Use B2fixtureDef if you need to set parameters
239	/// like friction, restitution, user data, or filtering.
240	/// If the density is non-zero, this function automatically updates the mass of the body.
241	/// * `shape` - the shape to be cloned.
242	/// * `density` - the shape density (set to zero for static bodies).
243	/// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
244	/// <strong>Warning:</strong> This function is locked during callbacks.
245	/// </p>
246	pub fn create_fixture_by_shape(self_: BodyPtr<D>, shape: ShapeDefPtr, density: f32) -> FixturePtr<D> {
247		return private::create_fixture_by_shape(self_, shape, density);
248	}
249
250	/// destroy a fixture. This removes the fixture from the broad-phase and
251	/// destroys all contacts associated with this fixture. This will
252	/// automatically adjust the mass of the body if the body is dynamic and the
253	/// fixture has positive density.
254	/// All fixtures attached to a body are implicitly destroyed when the body is destroyed.
255	/// * `fixture` - the fixture to be removed.
256	/// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
257	/// <strong>Warning:</strong> This function is locked during callbacks.
258	/// </p>
259	pub fn destroy_fixture(self_: BodyPtr<D>, fixture: FixturePtr<D>) {
260		private::destroy_fixture(self_, fixture);
261	}
262
263	/// Set the position of the body's origin and rotation.
264	/// Manipulating a body's transform may cause non-physical behavior.
265	/// Note: contacts are updated on the next call to B2world::step.
266	/// * `position` - the world position of the body's local origin.
267	/// * `angle` - the world rotation in radians.
268	pub fn set_transform(&mut self, position: B2vec2, angle: f32) {
269		private::set_transform(self, position, angle);
270	}
271
272	/// Get the body transform for the body's origin.
273	/// 
274	/// @return the world transform of the body's origin.
275	pub fn get_transform(&self) -> B2Transform {
276		return inline::get_transform(self);
277	}
278
279	/// Get the world body origin position.
280	/// 
281	/// @return the world position of the body's origin.
282	pub fn get_position(&self) -> B2vec2 {
283		return inline::get_position(self);
284	}
285
286	/// Get the angle in radians.
287	/// 
288	/// @return the current world rotation angle in radians.
289	pub fn get_angle(&self) -> f32 {
290		return inline::get_angle(self);
291	}
292
293	/// Get the world position of the center of mass.
294	pub fn get_world_center(&self) -> B2vec2 {
295		return inline::get_world_center(self);
296	}
297
298	/// Get the local position of the center of mass.
299	pub fn get_local_center(&self) -> B2vec2 {
300		return inline::get_local_center(self);
301	}
302
303	/// Set the linear velocity of the center of mass.
304	/// * `v` - the new linear velocity of the center of mass.
305	pub fn set_linear_velocity(&mut self, v: B2vec2) {
306		inline::set_linear_velocity(self, v);
307	}
308
309	/// Get the linear velocity of the center of mass.
310	/// 
311	/// @return the linear velocity of the center of mass.
312	pub fn get_linear_velocity(&self) -> B2vec2 {
313		return inline::get_linear_velocity(self);
314	}
315
316	/// Set the angular velocity.
317	/// * `omega` - the new angular velocity in radians/second.
318	pub fn set_angular_velocity(&mut self, omega: f32) {
319		inline::set_angular_velocity(self, omega);
320	}
321
322	/// Get the angular velocity.
323	/// 
324	/// @return the angular velocity in radians/second.
325	pub fn get_angular_velocity(&self) -> f32 {
326		return inline::get_angular_velocity(self);
327	}
328
329	/// Apply a force at a world point. If the force is not
330	/// applied at the center of mass, it will generate a torque and
331	/// affect the angular velocity. This wakes up the body.
332	/// * `force` - the world force vector, usually in Newtons (n).
333	/// * `point` - the world position of the point of application.
334	/// * `wake` - also wake up the body
335	pub fn apply_force(&mut self, force: B2vec2, point: B2vec2, wake: bool) {
336		inline::apply_force(self, force, point, wake);
337	}
338
339	/// Apply a force to the center of mass. This wakes up the body.
340	/// * `force` - the world force vector, usually in Newtons (n).
341	/// * `wake` - also wake up the body
342	pub fn apply_force_to_center(&mut self, force: B2vec2, wake: bool) {
343		inline::apply_force_to_center(self, force, wake);
344	}
345
346	/// Apply a torque. This affects the angular velocity
347	/// without affecting the linear velocity of the center of mass.
348	/// * `torque` - about the z-axis (out of the screen), usually in n-m.
349	/// * `wake` - also wake up the body
350	pub fn apply_torque(&mut self, torque: f32, wake: bool) {
351		inline::apply_torque(self, torque, wake);
352	}
353
354	/// Apply an impulse at a point. This immediately modifies the velocity.
355	/// It also modifies the angular velocity if the point of application
356	/// is not at the center of mass. This wakes up the body.
357	/// * `impulse` - the world impulse vector, usually in n-seconds or kg-m/s.
358	/// * `point` - the world position of the point of application.
359	/// * `wake` - also wake up the body
360	pub fn apply_linear_impulse(&mut self, impulse: B2vec2, point: B2vec2, wake: bool) {
361		inline::apply_linear_impulse(self, impulse, point, wake);
362	}
363
364	/// Apply an impulse to the center of mass. This immediately modifies the velocity.
365	/// * `impulse` - the world impulse vector, usually in n-seconds or kg-m/s.
366	/// * `wake` - also wake up the body
367	pub fn apply_linear_impulse_to_center(&mut self, impulse: B2vec2, wake: bool) {
368		inline::apply_linear_impulse_to_center(self, impulse, wake);
369	}
370
371	/// Apply an angular impulse.
372	/// * `impulse` - the angular impulse in units of kg*m*m/s
373	/// * `wake` - also wake up the body
374	pub fn apply_angular_impulse(&mut self, impulse: f32, wake: bool) {
375		inline::apply_angular_impulse(self, impulse, wake);
376	}
377
378	/// Get the total mass of the body.
379	/// 
380	/// @return the mass, usually in kilograms (kg).
381	pub fn get_mass(&self) -> f32 {
382		return inline::get_mass(self);
383	}
384
385	/// Get the rotational inertia of the body about the local origin.
386	/// 
387	/// @return the rotational inertia, usually in kg-m^2.
388	pub fn get_inertia(&self) -> f32 {
389		return inline::get_inertia(self);
390	}
391
392	/// Get the mass data of the body.
393	/// 
394	/// @return a struct containing the mass, inertia and center of the body.
395	pub fn get_mass_data(&self, data: &mut B2massData) {
396		inline::get_mass_data(self, data);
397	}
398
399	/// Set the mass properties to override the mass properties of the fixtures.
400	/// Note that this changes the center of mass position.
401	/// Note that creating or destroying fixtures can also alter the mass.
402	/// This function has no effect if the body isn't dynamic.
403	/// * `data` - the mass properties.
404	pub fn set_mass_data(&mut self, mass_data: &B2massData) {
405		private::set_mass_data(self, mass_data);
406	}
407
408	/// This resets the mass properties to the sum of the mass properties of the fixtures.
409	/// This normally does not need to be called unless you called set_mass_data to override
410	/// the mass and you later want to reset the mass.
411	pub fn reset_mass_data(&mut self) {
412		private::reset_mass_data(self);
413	}
414
415	/// Get the world coordinates of a point given the local coordinates.
416	/// * `local_point` - a point on the body measured relative the the body's origin.
417	/// 
418	/// @return the same point expressed in world coordinates.
419	pub fn get_world_point(&self, local_point: B2vec2) -> B2vec2 {
420		return inline::get_world_point(self, local_point);
421	}
422
423	/// Get the world coordinates of a vector given the local coordinates.
424	/// * `local_vector` - a vector fixed in the body.
425	/// 
426	/// @return the same vector expressed in world coordinates.
427	pub fn get_world_vector(&self, local_vector: B2vec2) -> B2vec2 {
428		return inline::get_world_vector(self, local_vector);
429	}
430
431	/// Gets a local point relative to the body's origin given a world point.
432	/// * `world_point` - a point in world coordinates.
433	/// 
434	/// @return the corresponding local point relative to the body's origin.
435	pub fn get_local_point(&self, world_point: B2vec2) -> B2vec2 {
436		return inline::get_local_point(self, world_point);
437	}
438
439	/// Gets a local vector given a world vector.
440	/// * `world_vector` - a vector in world coordinates.
441	/// 
442	/// @return the corresponding local vector.
443	pub fn get_local_vector(&self, world_vector: B2vec2) -> B2vec2 {
444		return inline::get_local_vector(self, world_vector);
445	}
446
447	/// Get the world linear velocity of a world point attached to this body.
448	/// * `world_point` - a point in world coordinates.
449	/// 
450	/// @return the world velocity of a point.
451	pub fn get_linear_velocity_from_world_point(&self, world_point: B2vec2) -> B2vec2 {
452		return inline::get_linear_velocity_from_world_point(self, world_point);
453	}
454
455	/// Get the world velocity of a local point.
456	/// * `local_point` - a point in local coordinates.
457	/// 
458	/// @return the world velocity of a point.
459	pub fn get_linear_velocity_from_local_point(&self, local_point: B2vec2) -> B2vec2 {
460		return inline::get_linear_velocity_from_local_point(self, local_point);
461	}
462
463	/// Get the linear damping of the body.
464	pub fn get_linear_damping(&self) -> f32 {
465		return inline::get_linear_damping(self);
466	}
467
468	/// Set the linear damping of the body.
469	pub fn set_linear_damping(&mut self, linear_damping: f32) {
470		inline::set_linear_damping(self, linear_damping);
471	}
472
473	/// Get the angular damping of the body.
474	pub fn get_angular_damping(&self) -> f32 {
475		return inline::get_angular_damping(self);
476	}
477
478	/// Set the angular damping of the body.
479	pub fn set_angular_damping(&mut self, angular_damping: f32) {
480		inline::set_angular_damping(self, angular_damping);
481	}
482
483	/// Get the gravity scale of the body.
484	pub fn get_gravity_scale(&self) -> f32 {
485		return inline::get_gravity_scale(self);
486	}
487
488	/// Set the gravity scale of the body.
489	pub fn set_gravity_scale(&mut self, scale: f32) {
490		inline::set_gravity_scale(self, scale);
491	}
492
493	/// Set the type of this body. This may alter the mass and velocity.
494	pub fn set_type(self_: BodyPtr<D>, body_type: B2bodyType) {
495		private::set_type(self_, body_type);
496	}
497
498	/// Get the type of this body.
499	pub fn get_type(&self) -> B2bodyType {
500		return inline::get_type(self);
501	}
502
503	/// Should this body be treated like a bullet for continuous collision detection?
504	pub fn set_bullet(&mut self, flag: bool) {
505		inline::set_bullet(self, flag);
506	}
507
508	/// Is this body treated like a bullet for continuous collision detection?
509	pub fn is_bullet(&self) -> bool {
510		return inline::is_bullet(self);
511	}
512
513	/// You can disable sleeping on this body. If you disable sleeping, the
514	/// body will be woken.
515	pub fn set_sleeping_allowed(&mut self, flag: bool) {
516		inline::set_sleeping_allowed(self, flag);
517	}
518
519	/// Is this body allowed to sleep
520	pub fn is_sleeping_allowed(&self) -> bool {
521		return inline::is_sleeping_allowed(self);
522	}
523
524	/// Set the sleep state of the body. A sleeping body has very
525	/// low CPU cost.
526	/// * `flag` - set to true to wake the body, false to put it to sleep.
527	pub fn set_awake(&mut self, flag: bool) {
528		inline::set_awake(self, flag);
529	}
530
531	/// Get the sleeping state of this body.
532	/// 
533	/// @return true if the body is awake.
534	pub fn is_awake(&self) -> bool {
535		return inline::is_awake(self);
536	}
537
538	/// Allow a body to be disabled. A disabled body is not simulated and cannot
539	/// be collided with or woken up.
540	/// If you pass a flag of true, all fixtures will be added to the broad-phase.
541	/// If you pass a flag of false, all fixtures will be removed from the
542	/// broad-phase and all contacts will be destroyed.
543	/// Fixtures and joints are otherwise unaffected. You may continue
544	/// to create/destroy fixtures and joints on disabled bodies.
545	/// Fixtures on a disabled body are implicitly disabled and will
546	/// not participate in collisions, ray-casts, or queries.
547	/// Joints connected to a disabled body are implicitly disabled.
548	/// An diabled body is still owned by a B2world object and remains
549	/// in the body list.
550	pub fn set_enabled(self_: BodyPtr<D>, flag: bool) {
551		private::set_enabled(self_, flag);
552	}
553
554	/// Get the active state of the body.
555	pub fn is_enabled(&self) -> bool {
556		return inline::is_enabled(self);
557	}
558
559	/// Set this body to have fixed rotation. This causes the mass
560	/// to be reset.
561	pub fn set_fixed_rotation(&mut self, flag: bool) {
562		private::set_fixed_rotation(self, flag);
563	}
564
565	/// Does this body have fixed rotation?
566	pub fn is_fixed_rotation(&self) -> bool {
567		return inline::is_fixed_rotation(self);
568	}
569
570	/// Get the list of all fixtures attached to this body.
571	pub fn get_fixture_list(&self) -> &LinkedList<B2fixture<D>> {
572		return inline::get_fixture_list(self);
573	}
574	// pub fn get_fixture_list_mut(&mut self) -> &mut Option<FixturePtr<D>> {
575	// 	return inline::get_fixture_list_mut(self);
576	// }
577
578	/// Get the list of all joints attached to this body.
579	pub fn get_joint_list(&self) -> &DoubleLinkedList<B2jointEdge<D>> {
580		return inline::get_joint_list(self);
581	}
582	pub fn get_joint_list_mut(&mut self) -> &mut DoubleLinkedList<B2jointEdge<D>> {
583		return inline::get_joint_list_mut(self);
584	}
585
586	/// Get the list of all contacts attached to this body.
587	/// <p style="background:rgba(255,181,77,0.16);padding:0.75em;">
588	/// <strong>Warning:</strong> this list changes during the time step and you may
589	/// miss some collisions if you don't use B2contactListener.
590	/// </p>
591	pub fn get_contact_list(&self) -> &DoubleLinkedList<B2contactEdge<D>> {
592		return inline::get_contact_list(self);
593	}
594	// pub fn get_contact_list_mut(&mut self) -> &mut Option<ContactEdgePtr<D>> {
595	// 	return inline::get_contact_list_mut(self);
596	// }
597
598	/// Get the next body in the world's body list.
599	pub fn get_next(&self) -> Option<BodyPtr<D>> {
600		return inline::get_next(self);
601	}
602
603	/// Get the user data pointer that was provided in the body definition.
604	pub fn get_user_data(&self) -> Option<D::Body> {
605		return inline::get_user_data(self);
606	}
607
608	/// Set the user data. Use this to store your application specific data.
609	pub fn set_user_data(&mut self, data: &D::Body) {
610		inline::set_user_data(self, data);
611	}
612
613	/// Get the parent world of this body.
614	pub fn get_world(&self) -> B2worldPtr<D> {
615		return inline::get_world(self);
616	}
617
618	// private:
619
620	pub(crate) fn new(bd: &B2bodyDef<D>, world: B2worldPtr<D>) -> Self {
621		return private::b2_body(bd, world);
622	}
623
624	pub(crate) fn synchronize_fixtures(&mut self) {
625		private::synchronize_fixtures(self);
626	}
627	pub(crate) fn synchronize_fixtures_by_world(&mut self, world: &B2world<D>) {
628		private::synchronize_fixtures_by_world(self, world);
629	}
630	pub(crate) fn synchronize_transform(&mut self) {
631		inline::synchronize_transform(self);
632	}
633
634	// This is used to prevent connected bodies from colliding.
635	// It may lie, depending on the collide_connected flag.
636	pub(crate) fn should_collide(&self, other: BodyPtr<D>) -> bool {
637		return private::should_collide(self, other);
638	}
639
640	pub(crate) fn advance(&mut self, t: f32) {
641		inline::advance(self, t);
642	}
643}
644
645mod inline {
646	use super::*;
647
648	pub fn get_type<D: UserDataType>(self_: &B2body<D>) -> B2bodyType {
649		return self_.m_type;
650	}
651
652	pub fn get_transform<D: UserDataType>(self_: &B2body<D>) -> B2Transform {
653		return self_.m_xf;
654	}
655
656	pub fn get_position<D: UserDataType>(self_: &B2body<D>) -> B2vec2 {
657		return self_.m_xf.p;
658	}
659
660	pub fn get_angle<D: UserDataType>(self_: &B2body<D>) -> f32 {
661		return self_.m_sweep.a;
662	}
663
664	pub fn get_world_center<D: UserDataType>(self_: &B2body<D>) -> B2vec2 {
665		return self_.m_sweep.c;
666	}
667
668	pub fn get_local_center<D: UserDataType>(self_: &B2body<D>) -> B2vec2 {
669		return self_.m_sweep.local_center;
670	}
671
672	pub fn set_linear_velocity<D: UserDataType>(self_: &mut B2body<D>, v: B2vec2) {
673		if self_.m_type == B2bodyType::B2StaticBody {
674			return;
675		}
676
677		if b2_dot(v, v) > 0.0 {
678			self_.set_awake(true);
679		}
680
681		self_.m_linear_velocity = v;
682	}
683
684	pub fn get_linear_velocity<D: UserDataType>(self_: &B2body<D>) -> B2vec2 {
685		return self_.m_linear_velocity;
686	}
687
688	pub fn set_angular_velocity<D: UserDataType>(self_: &mut B2body<D>, w: f32) {
689		if self_.m_type == B2bodyType::B2StaticBody {
690			return;
691		}
692
693		if w * w > 0.0 {
694			self_.set_awake(true);
695		}
696
697		self_.m_angular_velocity = w;
698	}
699
700	pub fn get_angular_velocity<D: UserDataType>(self_: &B2body<D>) -> f32 {
701		return self_.m_angular_velocity;
702	}
703
704	pub fn get_mass<D: UserDataType>(self_: &B2body<D>) -> f32 {
705		return self_.m_mass;
706	}
707
708	pub fn get_inertia<D: UserDataType>(self_: &B2body<D>) -> f32 {
709		return self_.m_i
710			+ self_.m_mass * b2_dot(self_.m_sweep.local_center, self_.m_sweep.local_center);
711	}
712
713	pub fn get_mass_data<D: UserDataType>(self_: &B2body<D>, data: &mut B2massData) {
714		data.mass = self_.m_mass;
715		data.i =
716			self_.m_i + self_.m_mass * b2_dot(self_.m_sweep.local_center, self_.m_sweep.local_center);
717		data.center = self_.m_sweep.local_center;
718	}
719
720	pub fn get_world_point<D: UserDataType>(self_: &B2body<D>, local_point: B2vec2) -> B2vec2 {
721		return b2_mul_transform_by_vec2(self_.m_xf, local_point);
722	}
723
724	pub fn get_world_vector<D: UserDataType>(self_: &B2body<D>, local_vector: B2vec2) -> B2vec2 {
725		return b2_mul_rot_by_vec2(self_.m_xf.q, local_vector);
726	}
727
728	pub fn get_local_point<D: UserDataType>(self_: &B2body<D>, world_point: B2vec2) -> B2vec2 {
729		return b2_mul_t_transform_by_vec2(self_.m_xf, world_point);
730	}
731
732	pub fn get_local_vector<D: UserDataType>(self_: &B2body<D>, world_vector: B2vec2) -> B2vec2 {
733		return b2_mul_t_rot_by_vec2(self_.m_xf.q, world_vector);
734	}
735
736	pub fn get_linear_velocity_from_world_point<D: UserDataType>(
737		self_: &B2body<D>,
738		world_point: B2vec2,
739	) -> B2vec2 {
740		return self_.m_linear_velocity
741			+ b2_cross_scalar_by_vec(self_.m_angular_velocity, world_point - self_.m_sweep.c);
742	}
743
744	pub fn get_linear_velocity_from_local_point<D: UserDataType>(
745		self_: &B2body<D>,
746		local_point: B2vec2,
747	) -> B2vec2 {
748		return self_.get_linear_velocity_from_world_point(self_.get_world_point(local_point));
749	}
750
751	pub fn get_linear_damping<D: UserDataType>(self_: &B2body<D>) -> f32 {
752		return self_.m_linear_damping;
753	}
754
755	pub fn set_linear_damping<D: UserDataType>(self_: &mut B2body<D>, linear_damping: f32) {
756		self_.m_linear_damping = linear_damping;
757	}
758
759	pub fn get_angular_damping<D: UserDataType>(self_: &B2body<D>) -> f32 {
760		return self_.m_angular_damping;
761	}
762
763	pub fn set_angular_damping<D: UserDataType>(self_: &mut B2body<D>, angular_damping: f32) {
764		self_.m_angular_damping = angular_damping;
765	}
766
767	pub fn get_gravity_scale<D: UserDataType>(self_: &B2body<D>) -> f32 {
768		return self_.m_gravity_scale;
769	}
770
771	pub fn set_gravity_scale<D: UserDataType>(self_: &mut B2body<D>, scale: f32) {
772		self_.m_gravity_scale = scale;
773	}
774
775	pub fn set_bullet<D: UserDataType>(self_: &mut B2body<D>, flag: bool) {
776		self_.m_flags.set(BodyFlags::E_BULLET_FLAG, flag);
777	}
778
779	pub fn is_bullet<D: UserDataType>(self_: &B2body<D>) -> bool {
780		return self_.m_flags.contains(BodyFlags::E_BULLET_FLAG);
781	}
782
783	pub fn set_awake<D: UserDataType>(self_: &mut B2body<D>, flag: bool) {
784
785		if self_.m_type == B2bodyType::B2StaticBody
786		{
787			return;
788	
789		}
790
791		self_.m_flags.set(BodyFlags::E_AWAKE_FLAG, flag);
792		if flag {
793			self_.m_sleep_time = 0.0;
794		} else {
795			self_.m_sleep_time = 0.0;
796			self_.m_linear_velocity.set_zero();
797			self_.m_angular_velocity = 0.0;
798			self_.m_force.set_zero();
799			self_.m_torque = 0.0;
800		}
801	}
802
803	pub fn is_awake<D: UserDataType>(self_: &B2body<D>) -> bool {
804		return self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG);
805	}
806
807	pub fn is_enabled<D: UserDataType>(self_: &B2body<D>) -> bool {
808		return self_.m_flags.contains(BodyFlags::E_ENABLED_FLAG);
809	}
810
811	pub fn is_fixed_rotation<D: UserDataType>(self_: &B2body<D>) -> bool {
812		return self_.m_flags.contains(BodyFlags::E_FIXED_ROTATION_FLAG);
813	}
814
815	pub fn set_sleeping_allowed<D: UserDataType>(self_: &mut B2body<D>, flag: bool) {
816		self_.m_flags.set(BodyFlags::E_AUTO_SLEEP_FLAG, flag);
817		if flag {
818		} else {
819			self_.set_awake(true);
820		}
821	}
822
823	pub fn is_sleeping_allowed<D: UserDataType>(self_: &B2body<D>) -> bool {
824		return self_.m_flags.contains(BodyFlags::E_AUTO_SLEEP_FLAG);
825	}
826
827	// pub fn get_fixture_list_mut<D: UserDataType>(
828	// 	self_: &mut B2body<D>,
829	// ) -> &mut Option<FixturePtr<D>> {
830	// 	return &mut self_.m_fixture_list;
831	// }
832
833	pub fn get_fixture_list<D: UserDataType>(self_: &B2body<D>) -> &LinkedList<B2fixture<D>> {
834		return &self_.m_fixture_list;
835	}
836
837	pub fn get_joint_list_mut<D: UserDataType>(
838		self_: &mut B2body<D>,
839	) -> &mut DoubleLinkedList<B2jointEdge<D>> {
840		return &mut self_.m_joint_list;
841	}
842
843	pub fn get_joint_list<D: UserDataType>(self_: &B2body<D>) -> &DoubleLinkedList<B2jointEdge<D>> {
844		return &self_.m_joint_list;
845	}
846
847	// pub fn get_contact_list_mut<D: UserDataType>(
848	// 	self_: &mut B2body<D>,
849	// ) -> &mut Option<ContactEdgePtr<D>> {
850	// 	return &mut self_.m_contact_list.head;
851	// }
852
853	pub fn get_contact_list<D: UserDataType>(self_: &B2body<D>) -> &DoubleLinkedList<B2contactEdge<D>> {
854		return &self_.m_contact_list;
855	}
856
857	pub fn get_next<D: UserDataType>(self_: &B2body<D>) -> Option<BodyPtr<D>> {
858		return self_.m_next.clone();
859	}
860
861	pub fn set_user_data<D: UserDataType>(self_: &mut B2body<D>, data: &D::Body) {
862		self_.m_user_data = Some(data.clone());
863	}
864
865	pub fn get_user_data<D: UserDataType>(self_: &B2body<D>) -> Option<D::Body> {
866		return self_.m_user_data.clone();
867	}
868
869	pub fn apply_force<D: UserDataType>(
870		self_: &mut B2body<D>,
871		force: B2vec2,
872		point: B2vec2,
873		wake: bool,
874	) {
875		if self_.m_type != B2bodyType::B2DynamicBody {
876			return;
877		}
878
879		if wake && !self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
880			self_.set_awake(true);
881		}
882
883		// Don't accumulate a force if the body is sleeping.
884		if self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
885			self_.m_force += force;
886			self_.m_torque += b2_cross(point - self_.m_sweep.c, force);
887		}
888	}
889
890	pub fn apply_force_to_center<D: UserDataType>(self_: &mut B2body<D>, force: B2vec2, wake: bool) {
891		if self_.m_type != B2bodyType::B2DynamicBody {
892			return;
893		}
894
895		if wake && !self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
896			self_.set_awake(true);
897		}
898
899		// Don't accumulate a force if the body is sleeping
900		if self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
901			self_.m_force += force;
902		}
903	}
904
905	pub fn apply_torque<D: UserDataType>(self_: &mut B2body<D>, torque: f32, wake: bool) {
906		if self_.m_type != B2bodyType::B2DynamicBody {
907			return;
908		}
909
910		if wake && !self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
911			self_.set_awake(true);
912		}
913
914		// Don't accumulate a force if the body is sleeping
915		if self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
916			self_.m_torque += torque;
917		}
918	}
919
920	pub fn apply_linear_impulse<D: UserDataType>(
921		self_: &mut B2body<D>,
922		impulse: B2vec2,
923		point: B2vec2,
924		wake: bool,
925	) {
926		if self_.m_type != B2bodyType::B2DynamicBody {
927			return;
928		}
929
930		if wake && !self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
931			self_.set_awake(true);
932		}
933
934		// Don't accumulate velocity if the body is sleeping
935		if self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
936			self_.m_linear_velocity += self_.m_inv_mass * impulse;
937			self_.m_angular_velocity += self_.m_inv_i * b2_cross(point - self_.m_sweep.c, impulse);
938		}
939	}
940
941	pub fn apply_linear_impulse_to_center<D: UserDataType>(
942		self_: &mut B2body<D>,
943		impulse: B2vec2,
944		wake: bool,
945	) {
946		if self_.m_type != B2bodyType::B2DynamicBody {
947			return;
948		}
949		if wake && !self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
950			self_.set_awake(true);
951		}
952
953		// Don't accumulate velocity if the body is sleeping
954		if self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
955			self_.m_linear_velocity += self_.m_inv_mass * impulse;
956		}
957	}
958
959	pub fn apply_angular_impulse<D: UserDataType>(self_: &mut B2body<D>, impulse: f32, wake: bool) {
960		if self_.m_type != B2bodyType::B2DynamicBody {
961			return;
962		}
963
964		if wake && !self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
965			self_.set_awake(true);
966		}
967
968		// Don't accumulate velocity if the body is sleeping
969		if self_.m_flags.contains(BodyFlags::E_AWAKE_FLAG) {
970			self_.m_angular_velocity += self_.m_inv_i * impulse;
971		}
972	}
973
974	pub fn synchronize_transform<D: UserDataType>(self_: &mut B2body<D>) {
975		self_.m_xf.q.set(self_.m_sweep.a);
976		self_.m_xf.p = self_.m_sweep.c - b2_mul_rot_by_vec2(self_.m_xf.q, self_.m_sweep.local_center);
977	}
978
979	pub fn advance<D: UserDataType>(self_: &mut B2body<D>, alpha: f32) {
980		// advance to the new safe time. This doesn't sync the broad-phase.
981		self_.m_sweep.advance(alpha);
982		self_.m_sweep.c = self_.m_sweep.c0;
983		self_.m_sweep.a = self_.m_sweep.a0;
984		self_.m_xf.q.set(self_.m_sweep.a);
985		self_.m_xf.p = self_.m_sweep.c - b2_mul_rot_by_vec2(self_.m_xf.q, self_.m_sweep.local_center);
986	}
987
988	pub fn get_world<D: UserDataType>(self_: &B2body<D>) -> B2worldPtr<D> {
989		return self_.m_world.upgrade().unwrap();
990	}
991}