Body.cs 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. /*
  2. * Box2D.XNA port of Box2D:
  3. * Copyright (c) 2009 Brandon Furtwangler, Nathan Furtwangler
  4. *
  5. * Original source Box2D:
  6. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  7. *
  8. * This software is provided 'as-is', without any express or implied
  9. * warranty. In no event will the authors be held liable for any damages
  10. * arising from the use of this software.
  11. * Permission is granted to anyone to use this software for any purpose,
  12. * including commercial applications, and to alter it and redistribute it
  13. * freely, subject to the following restrictions:
  14. * 1. The origin of this software must not be misrepresented; you must not
  15. * claim that you wrote the original software. If you use this software
  16. * in a product, an acknowledgment in the product documentation would be
  17. * appreciated but is not required.
  18. * 2. Altered source versions must be plainly marked as such, and must not be
  19. * misrepresented as being the original software.
  20. * 3. This notice may not be removed or altered from any source distribution.
  21. */
  22. using System;
  23. using System.Diagnostics;
  24. using Microsoft.Xna.Framework;
  25. namespace Box2D.XNA
  26. {
  27. /// The body type.
  28. /// static: zero mass, zero velocity, may be manually moved
  29. /// kinematic: zero mass, non-zero velocity set by user, moved by solver
  30. /// dynamic: positive mass, non-zero velocity determined by forces, moved by solver
  31. public enum BodyType
  32. {
  33. Static,
  34. Kinematic,
  35. Dynamic,
  36. }
  37. /// A body definition holds all the data needed to construct a rigid body.
  38. /// You can safely re-use body definitions. Shapes are added to a body after construction.
  39. public class BodyDef
  40. {
  41. /// This constructor sets the body definition default values.
  42. public BodyDef()
  43. {
  44. userData = null;
  45. position = new Vector2(0.0f, 0.0f);
  46. angle = 0.0f;
  47. linearVelocity = new Vector2(0.0f, 0.0f);
  48. angularVelocity = 0.0f;
  49. linearDamping = 0.0f;
  50. angularDamping = 0.0f;
  51. allowSleep = true;
  52. awake = true;
  53. fixedRotation = false;
  54. bullet = false;
  55. type = BodyType.Static;
  56. active = true;
  57. inertiaScale = 1.0f;
  58. }
  59. /// The body type: static, kinematic, or dynamic.
  60. /// Note: if a dynamic body would have zero mass, the mass is set to one.
  61. public BodyType type;
  62. /// The world position of the body. Avoid creating bodies at the origin
  63. /// since this can lead to many overlapping shapes.
  64. public Vector2 position;
  65. /// The world angle of the body in radians.
  66. public float angle;
  67. /// The linear velocity of the body's origin in world co-ordinates.
  68. public Vector2 linearVelocity;
  69. /// The angular velocity of the body.
  70. public float angularVelocity;
  71. /// Linear damping is use to reduce the linear velocity. The damping parameter
  72. /// can be larger than 1.0f but the damping effect becomes sensitive to the
  73. /// time step when the damping parameter is large.
  74. public float linearDamping;
  75. /// Angular damping is use to reduce the angular velocity. The damping parameter
  76. /// can be larger than 1.0f but the damping effect becomes sensitive to the
  77. /// time step when the damping parameter is large.
  78. public float angularDamping;
  79. /// Set this flag to false if this body should never fall asleep. Note that
  80. /// this increases CPU usage.
  81. public bool allowSleep;
  82. /// Is this body awake or sleeping?
  83. public bool awake;
  84. /// Should this body be prevented from rotating? Useful for characters.
  85. public bool fixedRotation;
  86. /// Is this a fast moving body that should be prevented from tunneling through
  87. /// other moving bodies? Note that all bodies are prevented from tunneling through
  88. /// kinematic and static bodies. This setting is only considered on dynamic bodies.
  89. /// @warning You should use this flag sparingly since it increases processing time.
  90. public bool bullet;
  91. /// Does this body start out active?
  92. public bool active;
  93. /// Use this to store application specific body data.
  94. public object userData;
  95. /// Experimental: scales the inertia tensor.
  96. public float inertiaScale;
  97. };
  98. [Flags]
  99. public enum BodyFlags
  100. {
  101. None = 0,
  102. Island = (1 << 0),
  103. Awake = (1 << 1),
  104. AutoSleep = (1 << 2),
  105. Bullet = (1 << 3),
  106. FixedRotation = (1 << 4),
  107. Active = (1 << 5),
  108. Toi = (1 << 6),
  109. }
  110. public class Body
  111. {
  112. /// Set the type of this body. This may alter the mass and velocity.
  113. public void SetType(BodyType type)
  114. {
  115. if (_type == type)
  116. {
  117. return;
  118. }
  119. _type = type;
  120. ResetMassData();
  121. if (_type == BodyType.Static)
  122. {
  123. _linearVelocity = Vector2.Zero;
  124. _angularVelocity = 0.0f;
  125. }
  126. SetAwake(true);
  127. _force = Vector2.Zero;
  128. _torque = 0.0f;
  129. // Since the body type changed, we need to flag contacts for filtering.
  130. for (ContactEdge ce = _contactList; ce != null; ce = ce.Next)
  131. {
  132. ce.Contact.FlagForFiltering();
  133. }
  134. }
  135. /// Get the type of this body.
  136. public new BodyType GetType()
  137. {
  138. return _type;
  139. }
  140. /// Creates a fixture and attach it to this body. Use this function if you need
  141. /// to set some fixture parameters, like friction. Otherwise you can create the
  142. /// fixture directly from a shape.
  143. /// If the density is non-zero, this function automatically updates the mass of the body.
  144. /// Contacts are not created until the next time step.
  145. /// @param def the fixture definition.
  146. /// @warning This function is locked during callbacks.
  147. public Fixture CreateFixture(FixtureDef def)
  148. {
  149. Debug.Assert(_world.IsLocked == false);
  150. if (_world.IsLocked == true)
  151. {
  152. return null;
  153. }
  154. Fixture fixture = new Fixture();
  155. fixture.Create(this, def);
  156. if ((_flags & BodyFlags.Active) == BodyFlags.Active)
  157. {
  158. BroadPhase broadPhase = _world._contactManager._broadPhase;
  159. fixture.CreateProxies(broadPhase, ref _xf);
  160. }
  161. fixture._next = _fixtureList;
  162. _fixtureList = fixture;
  163. ++_fixtureCount;
  164. fixture._body = this;
  165. // Adjust mass properties if needed.
  166. if (fixture._density > 0.0f)
  167. {
  168. ResetMassData();
  169. }
  170. // Let the world know we have a new fixture. This will cause new contacts
  171. // to be created at the beginning of the next time step.
  172. _world._flags |= WorldFlags.NewFixture;
  173. return fixture;
  174. }
  175. /// Creates a fixture from a shape and attach it to this body.
  176. /// This is a convenience function. Use FixtureDef if you need to set parameters
  177. /// like friction, restitution, user data, or filtering.
  178. /// If the density is non-zero, this function automatically updates the mass of the body.
  179. /// @param shape the shape to be cloned.
  180. /// @param density the shape density (set to zero for static bodies).
  181. /// @warning This function is locked during callbacks.
  182. public Fixture CreateFixture(Shape shape, float density)
  183. {
  184. FixtureDef def = new FixtureDef();
  185. def.shape = shape;
  186. def.density = density;
  187. return CreateFixture(def);
  188. }
  189. /// Destroy a fixture. This removes the fixture from the broad-phase and
  190. /// destroys all contacts associated with this fixture. This will
  191. /// automatically adjust the mass of the body if the body is dynamic and the
  192. /// fixture has positive density.
  193. /// All fixtures attached to a body are implicitly destroyed when the body is destroyed.
  194. /// @param fixture the fixture to be removed.
  195. /// @warning This function is locked during callbacks.
  196. public void DestroyFixture(Fixture fixture)
  197. {
  198. Debug.Assert(_world.IsLocked == false);
  199. if (_world.IsLocked == true)
  200. {
  201. return;
  202. }
  203. Debug.Assert(fixture._body == this);
  204. // Remove the fixture from this body's singly linked list.
  205. Debug.Assert(_fixtureCount > 0);
  206. Fixture node = _fixtureList;
  207. bool found = false;
  208. while (node != null)
  209. {
  210. if (node == fixture)
  211. {
  212. _fixtureList = fixture._next;
  213. found = true;
  214. break;
  215. }
  216. node = node._next;
  217. }
  218. // You tried to remove a shape that is not attached to this body.
  219. Debug.Assert(found);
  220. // Destroy any contacts associated with the fixture.
  221. ContactEdge edge = _contactList;
  222. while (edge != null)
  223. {
  224. Contact c = edge.Contact;
  225. edge = edge.Next;
  226. Fixture fixtureA = c.GetFixtureA();
  227. Fixture fixtureB = c.GetFixtureB();
  228. if (fixture == fixtureA || fixture == fixtureB)
  229. {
  230. // This destroys the contact and removes it from
  231. // this body's contact list.
  232. _world._contactManager.Destroy(c);
  233. }
  234. }
  235. if ((_flags & BodyFlags.Active) == BodyFlags.Active)
  236. {
  237. Debug.Assert(fixture._proxyId != BroadPhase.NullProxy);
  238. BroadPhase broadPhase = _world._contactManager._broadPhase;
  239. fixture.DestroyProxies(broadPhase);
  240. }
  241. fixture.Destroy();
  242. fixture._body = null;
  243. fixture._next = null;
  244. --_fixtureCount;
  245. ResetMassData();
  246. }
  247. /// Set the position of the body's origin and rotation.
  248. /// This breaks any contacts and wakes the other bodies.
  249. /// Manipulating a body's transform may cause non-physical behavior.
  250. /// @param position the world position of the body's local origin.
  251. /// @param angle the world rotation in radians.
  252. public void SetTransform(Vector2 position, float angle)
  253. {
  254. Debug.Assert(_world.IsLocked == false);
  255. if (_world.IsLocked == true)
  256. {
  257. return;
  258. }
  259. _xf.R.Set(angle);
  260. _xf.Position = position;
  261. _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter);
  262. _sweep.a0 = _sweep.a = angle;
  263. BroadPhase broadPhase = _world._contactManager._broadPhase;
  264. for (Fixture f = _fixtureList; f != null; f = f._next)
  265. {
  266. f.Synchronize(broadPhase, ref _xf, ref _xf);
  267. }
  268. _world._contactManager.FindNewContacts();
  269. }
  270. // For teleporting a body without considering new contacts immediately.
  271. public void SetTransformIgnoreContacts(Vector2 position, float angle)
  272. {
  273. Debug.Assert(_world.IsLocked == false);
  274. if (_world.IsLocked == true)
  275. {
  276. return;
  277. }
  278. _xf.R.Set(angle);
  279. _xf.Position = position;
  280. _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter);
  281. _sweep.a0 = _sweep.a = angle;
  282. BroadPhase broadPhase = _world._contactManager._broadPhase;
  283. for (Fixture f = _fixtureList; f != null; f = f._next)
  284. {
  285. f.Synchronize(broadPhase, ref _xf, ref _xf);
  286. }
  287. }
  288. /// Get the body transform for the body's origin.
  289. /// @return the world transform of the body's origin.
  290. public void GetTransform(out Transform xf)
  291. {
  292. xf = _xf;
  293. }
  294. /// Get the world body origin position.
  295. /// @return the world position of the body's origin.
  296. public Vector2 GetPosition()
  297. {
  298. return _xf.Position;
  299. }
  300. /// Get the angle in radians.
  301. /// @return the current world rotation angle in radians.
  302. public float GetAngle()
  303. {
  304. return _sweep.a;
  305. }
  306. /// Get the world position of the center of mass.
  307. public Vector2 GetWorldCenter()
  308. {
  309. return _sweep.c;
  310. }
  311. /// Get the local position of the center of mass.
  312. public Vector2 GetLocalCenter()
  313. {
  314. return _sweep.localCenter;
  315. }
  316. /// Set the linear velocity of the center of mass.
  317. /// @param v the new linear velocity of the center of mass.
  318. public void SetLinearVelocity(Vector2 v)
  319. {
  320. if (_type == BodyType.Static)
  321. {
  322. return;
  323. }
  324. if (Vector2.Dot(v,v) > 0.0f)
  325. {
  326. SetAwake(true);
  327. }
  328. _linearVelocity = v;
  329. }
  330. /// Get the linear velocity of the center of mass.
  331. /// @return the linear velocity of the center of mass.
  332. public Vector2 GetLinearVelocity()
  333. {
  334. return _linearVelocity;
  335. }
  336. /// Set the angular velocity.
  337. /// @param omega the new angular velocity in radians/second.
  338. public void SetAngularVelocity(float w)
  339. {
  340. if (_type == BodyType.Static)
  341. {
  342. return;
  343. }
  344. if (w*w > 0.0f)
  345. {
  346. SetAwake(true);
  347. }
  348. _angularVelocity = w;
  349. }
  350. /// Get the angular velocity.
  351. /// @return the angular velocity in radians/second.
  352. public float GetAngularVelocity()
  353. {
  354. return _angularVelocity;
  355. }
  356. /// Apply a force at a world point. If the force is not
  357. /// applied at the center of mass, it will generate a torque and
  358. /// affect the angular velocity. This wakes up the body.
  359. /// @param force the world force vector, usually in Newtons (N).
  360. /// @param point the world position of the point of application.
  361. public void ApplyForce(Vector2 force, Vector2 point)
  362. {
  363. if (_type == BodyType.Dynamic)
  364. {
  365. if (IsAwake() == false)
  366. {
  367. SetAwake(true);
  368. }
  369. _force += force;
  370. _torque += MathUtils.Cross(point - _sweep.c, force);
  371. }
  372. }
  373. /// Apply a torque. This affects the angular velocity
  374. /// without affecting the linear velocity of the center of mass.
  375. /// This wakes up the body.
  376. /// @param torque about the z-axis (out of the screen), usually in N-m.
  377. public void ApplyTorque(float torque)
  378. {
  379. if (_type == BodyType.Dynamic)
  380. {
  381. if (IsAwake() == false)
  382. {
  383. SetAwake(true);
  384. }
  385. _torque += torque;
  386. }
  387. }
  388. /// Apply an impulse at a point. This immediately modifies the velocity.
  389. /// It also modifies the angular velocity if the point of application
  390. /// is not at the center of mass. This wakes up the body.
  391. /// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
  392. /// @param point the world position of the point of application.
  393. public void ApplyLinearImpulse(Vector2 impulse, Vector2 point)
  394. {
  395. if (_type != BodyType.Dynamic)
  396. {
  397. return;
  398. }
  399. if (IsAwake() == false)
  400. {
  401. SetAwake(true);
  402. }
  403. _linearVelocity += _invMass * impulse;
  404. _angularVelocity += _invI * MathUtils.Cross(point - _sweep.c, impulse);
  405. }
  406. /// Apply an angular impulse.
  407. /// @param impulse the angular impulse in units of kg*m*m/s
  408. public void ApplyAngularImpulse(float impulse)
  409. {
  410. if (_type != BodyType.Dynamic)
  411. {
  412. return;
  413. }
  414. if (IsAwake() == false)
  415. {
  416. SetAwake(true);
  417. }
  418. _angularVelocity += _invI * impulse;
  419. }
  420. /// Get the total mass of the body.
  421. /// @return the mass, usually in kilograms (kg).
  422. public float GetMass()
  423. {
  424. return _mass;
  425. }
  426. /// Get the rotational inertia of the body about the local origin.
  427. /// @return the rotational inertia, usually in kg-m^2.
  428. public float GetInertia()
  429. {
  430. return _I + _mass * Vector2.Dot(_sweep.localCenter, _sweep.localCenter);
  431. }
  432. /// Get the mass data of the body.
  433. /// @return a struct containing the mass, inertia and center of the body.
  434. public void GetMassData(out MassData massData)
  435. {
  436. massData = new MassData();
  437. massData.mass = _mass;
  438. massData.I = _I + _mass * Vector2.Dot(_sweep.localCenter, _sweep.localCenter);
  439. massData.center = _sweep.localCenter;
  440. }
  441. /// Set the mass properties to override the mass properties of the fixtures.
  442. /// Note that this changes the center of mass position.
  443. /// Note that creating or destroying fixtures can also alter the mass.
  444. /// This function has no effect if the body isn't dynamic.
  445. /// @param massData the mass properties.
  446. public void SetMassData(ref MassData massData)
  447. {
  448. Debug.Assert(_world.IsLocked == false);
  449. if (_world.IsLocked == true)
  450. {
  451. return;
  452. }
  453. if (_type != BodyType.Dynamic)
  454. {
  455. return;
  456. }
  457. _invMass = 0.0f;
  458. _I = 0.0f;
  459. _invI = 0.0f;
  460. _mass = massData.mass;
  461. if (_mass <= 0.0f)
  462. {
  463. _mass = 1.0f;
  464. }
  465. _invMass = 1.0f / _mass;
  466. if (massData.I > 0.0f && (_flags & BodyFlags.FixedRotation) == 0)
  467. {
  468. _I = massData.I - _mass * Vector2.Dot(massData.center, massData.center);
  469. Debug.Assert(_I > 0.0f);
  470. _invI = 1.0f / _I;
  471. }
  472. // Move center of mass.
  473. Vector2 oldCenter = _sweep.c;
  474. _sweep.localCenter = massData.center;
  475. _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter);
  476. // Update center of mass velocity.
  477. _linearVelocity += MathUtils.Cross(_angularVelocity, _sweep.c - oldCenter);
  478. }
  479. /// This resets the mass properties to the sum of the mass properties of the fixtures.
  480. /// This normally does not need to be called unless you called SetMassData to override
  481. /// the mass and you later want to reset the mass.
  482. public void ResetMassData()
  483. {
  484. // Compute mass data from shapes. Each shape has its own density.
  485. _mass = 0.0f;
  486. _invMass = 0.0f;
  487. _I = 0.0f;
  488. _invI = 0.0f;
  489. _sweep.localCenter = Vector2.Zero;
  490. // Static and kinematic bodies have zero mass.
  491. if (_type == BodyType.Static || _type == BodyType.Kinematic)
  492. {
  493. _sweep.c0 = _sweep.c = _xf.Position;
  494. return;
  495. }
  496. Debug.Assert(_type == BodyType.Dynamic);
  497. // Accumulate mass over all fixtures.
  498. Vector2 center = Vector2.Zero;
  499. for (Fixture f = _fixtureList; f != null; f = f._next)
  500. {
  501. if (f._density == 0.0f)
  502. {
  503. continue;
  504. }
  505. MassData massData;
  506. f.GetMassData(out massData);
  507. _mass += massData.mass;
  508. center += massData.mass * massData.center;
  509. _I += massData.I;
  510. }
  511. // Compute center of mass.
  512. if (_mass > 0.0f)
  513. {
  514. _invMass = 1.0f / _mass;
  515. center *= _invMass;
  516. }
  517. else
  518. {
  519. // Force all dynamic bodies to have a positive mass.
  520. _mass = 1.0f;
  521. _invMass = 1.0f;
  522. }
  523. if (_I > 0.0f && (_flags & BodyFlags.FixedRotation) == 0)
  524. {
  525. // Center the inertia about the center of mass.
  526. _I -= _mass * Vector2.Dot(center, center);
  527. Debug.Assert(_I > 0.0f);
  528. _invI = 1.0f / _I;
  529. }
  530. else
  531. {
  532. _I = 0.0f;
  533. _invI = 0.0f;
  534. }
  535. // Move center of mass.
  536. Vector2 oldCenter = _sweep.c;
  537. _sweep.localCenter = center;
  538. _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter);
  539. // Update center of mass velocity.
  540. _linearVelocity += MathUtils.Cross(_angularVelocity, _sweep.c - oldCenter);
  541. }
  542. /// Get the world coordinates of a point given the local coordinates.
  543. /// @param localPoint a point on the body measured relative the the body's origin.
  544. /// @return the same point expressed in world coordinates.
  545. public Vector2 GetWorldPoint(Vector2 localPoint)
  546. {
  547. return MathUtils.Multiply(ref _xf, localPoint);
  548. }
  549. /// Get the world coordinates of a vector given the local coordinates.
  550. /// @param localVector a vector fixed in the body.
  551. /// @return the same vector expressed in world coordinates.
  552. public Vector2 GetWorldVector(Vector2 localVector)
  553. {
  554. return MathUtils.Multiply(ref _xf.R, localVector);
  555. }
  556. /// Gets a local point relative to the body's origin given a world point.
  557. /// @param a point in world coordinates.
  558. /// @return the corresponding local point relative to the body's origin.
  559. public Vector2 GetLocalPoint(Vector2 worldPoint)
  560. {
  561. return MathUtils.MultiplyT(ref _xf, worldPoint);
  562. }
  563. /// Gets a local vector given a world vector.
  564. /// @param a vector in world coordinates.
  565. /// @return the corresponding local vector.
  566. public Vector2 GetLocalVector(Vector2 worldVector)
  567. {
  568. return MathUtils.MultiplyT(ref _xf.R, worldVector);
  569. }
  570. /// Get the world linear velocity of a world point attached to this body.
  571. /// @param a point in world coordinates.
  572. /// @return the world velocity of a point.
  573. public Vector2 GetLinearVelocityFromWorldPoint(Vector2 worldPoint)
  574. {
  575. return _linearVelocity + MathUtils.Cross(_angularVelocity, worldPoint - _sweep.c);
  576. }
  577. /// Get the world velocity of a local point.
  578. /// @param a point in local coordinates.
  579. /// @return the world velocity of a point.
  580. public Vector2 GetLinearVelocityFromLocalPoint(Vector2 localPoint)
  581. {
  582. return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
  583. }
  584. /// Get the linear damping of the body.
  585. public float GetLinearDamping()
  586. {
  587. return _linearDamping;
  588. }
  589. /// Set the linear damping of the body.
  590. public void SetLinearDamping(float linearDamping)
  591. {
  592. _linearDamping = linearDamping;
  593. }
  594. /// Get the angular damping of the body.
  595. public float GetAngularDamping()
  596. {
  597. return _angularDamping;
  598. }
  599. /// Set the angular damping of the body.
  600. public void SetAngularDamping(float angularDamping)
  601. {
  602. _angularDamping = angularDamping;
  603. }
  604. /// Is this body treated like a bullet for continuous collision detection?
  605. public bool IsBullet
  606. {
  607. get
  608. {
  609. return (_flags & BodyFlags.Bullet) == BodyFlags.Bullet;
  610. }
  611. }
  612. /// Should this body be treated like a bullet for continuous collision detection?
  613. public void SetBullet(bool flag)
  614. {
  615. if (flag)
  616. {
  617. _flags |= BodyFlags.Bullet;
  618. }
  619. else
  620. {
  621. _flags &= ~BodyFlags.Bullet;
  622. }
  623. }
  624. /// You can disable sleeping on this body. If you disable sleeping, the
  625. /// body will be woken.
  626. void SetSleepingAllowed(bool flag)
  627. {
  628. if (flag)
  629. {
  630. _flags |= BodyFlags.AutoSleep;
  631. }
  632. else
  633. {
  634. _flags &= ~BodyFlags.AutoSleep;
  635. SetAwake(true);
  636. }
  637. }
  638. /// Is this body allowed to sleep
  639. public bool IsSleepingAllowed
  640. {
  641. get
  642. {
  643. return (_flags & BodyFlags.AutoSleep) == BodyFlags.AutoSleep;
  644. }
  645. }
  646. /// You can disable sleeping on this body.
  647. public void AllowSleeping(bool flag)
  648. {
  649. if (flag)
  650. {
  651. _flags |= BodyFlags.AutoSleep;
  652. }
  653. else
  654. {
  655. _flags &= ~BodyFlags.AutoSleep;
  656. SetAwake(true);
  657. }
  658. }
  659. /// Set the sleep state of the body. A sleeping body has very
  660. /// low CPU cost.
  661. /// @param flag set to true to put body to sleep, false to wake it.
  662. public void SetAwake(bool flag)
  663. {
  664. if (flag)
  665. {
  666. if ((_flags & BodyFlags.Awake) == 0)
  667. {
  668. _flags |= BodyFlags.Awake;
  669. _sleepTime = 0.0f;
  670. }
  671. }
  672. else
  673. {
  674. _flags &= ~BodyFlags.Awake;
  675. _sleepTime = 0.0f;
  676. _linearVelocity = Vector2.Zero;
  677. _angularVelocity = 0.0f;
  678. _force = Vector2.Zero;
  679. _torque = 0.0f;
  680. }
  681. }
  682. /// Get the sleeping state of this body.
  683. /// @return true if the body is sleeping.
  684. public bool IsAwake()
  685. {
  686. return (_flags & BodyFlags.Awake) == BodyFlags.Awake;
  687. }
  688. /// Set the active state of the body. An inactive body is not
  689. /// simulated and cannot be collided with or woken up.
  690. /// If you pass a flag of true, all fixtures will be added to the
  691. /// broad-phase.
  692. /// If you pass a flag of false, all fixtures will be removed from
  693. /// the broad-phase and all contacts will be destroyed.
  694. /// Fixtures and joints are otherwise unaffected. You may continue
  695. /// to create/destroy fixtures and joints on inactive bodies.
  696. /// Fixtures on an inactive body are implicitly inactive and will
  697. /// not participate in collisions, ray-casts, or queries.
  698. /// Joints connected to an inactive body are implicitly inactive.
  699. /// An inactive body is still owned by a b2World object and remains
  700. /// in the body list.
  701. public void SetActive(bool flag)
  702. {
  703. if (flag == IsActive())
  704. {
  705. return;
  706. }
  707. if (flag)
  708. {
  709. _flags |= BodyFlags.Active;
  710. // Create all proxies.
  711. BroadPhase broadPhase = _world._contactManager._broadPhase;
  712. for (Fixture f = _fixtureList; f != null; f = f._next)
  713. {
  714. f.CreateProxies(broadPhase, ref _xf);
  715. }
  716. // Contacts are created the next time step.
  717. }
  718. else
  719. {
  720. _flags &= ~BodyFlags.Active;
  721. // Destroy all proxies.
  722. BroadPhase broadPhase = _world._contactManager._broadPhase;
  723. for (Fixture f = _fixtureList; f != null; f = f._next)
  724. {
  725. f.DestroyProxies(broadPhase);
  726. }
  727. // Destroy the attached contacts.
  728. ContactEdge ce = _contactList;
  729. while (ce != null)
  730. {
  731. ContactEdge ce0 = ce;
  732. ce = ce.Next;
  733. _world._contactManager.Destroy(ce0.Contact);
  734. }
  735. _contactList = null;
  736. }
  737. }
  738. /// Get the active state of the body.
  739. public bool IsActive()
  740. {
  741. return (_flags & BodyFlags.Active) == BodyFlags.Active;
  742. }
  743. /// Set this body to have fixed rotation. This causes the mass
  744. /// to be reset.
  745. public void SetFixedRotation(bool flag)
  746. {
  747. if (flag)
  748. {
  749. _flags |= BodyFlags.FixedRotation;
  750. }
  751. else
  752. {
  753. _flags &= ~BodyFlags.FixedRotation;
  754. }
  755. ResetMassData();
  756. }
  757. /// Does this body have fixed rotation?
  758. public bool IsFixedRotation()
  759. {
  760. return (_flags & BodyFlags.FixedRotation) == BodyFlags.FixedRotation;
  761. }
  762. public Fixture GetFixtureList()
  763. {
  764. return _fixtureList;
  765. }
  766. /// Get the list of all joints attached to this body.
  767. public JointEdge GetJointList()
  768. {
  769. return _jointList;
  770. }
  771. /// Get the list of all contacts attached to this body.
  772. /// @warning this list changes during the time step and you may
  773. /// miss some collisions if you don't use ContactListener.
  774. public ContactEdge GetContactList()
  775. {
  776. return _contactList;
  777. }
  778. /// Get the next body in the world's body list.
  779. public Body GetNext()
  780. {
  781. return _next;
  782. }
  783. /// Get the user data pointer that was provided in the body definition.
  784. public object GetUserData()
  785. {
  786. return _userData;
  787. }
  788. /// Set the user data. Use this to store your application specific data.
  789. public void SetUserData(object data)
  790. {
  791. _userData = data;
  792. }
  793. /// Get the parent world of this body.
  794. public World GetWorld()
  795. {
  796. return _world;
  797. }
  798. internal Body(BodyDef bd, World world)
  799. {
  800. Debug.Assert(bd.position.IsValid());
  801. Debug.Assert(bd.linearVelocity.IsValid());
  802. Debug.Assert(MathUtils.IsValid(bd.angle));
  803. Debug.Assert(MathUtils.IsValid(bd.angularVelocity));
  804. Debug.Assert(MathUtils.IsValid(bd.inertiaScale) && bd.inertiaScale >= 0.0f);
  805. Debug.Assert(MathUtils.IsValid(bd.angularDamping) && bd.angularDamping >= 0.0f);
  806. Debug.Assert(MathUtils.IsValid(bd.linearDamping) && bd.linearDamping >= 0.0f);
  807. if (bd.bullet)
  808. {
  809. _flags |= BodyFlags.Bullet;
  810. }
  811. if (bd.fixedRotation)
  812. {
  813. _flags |= BodyFlags.FixedRotation;
  814. }
  815. if (bd.allowSleep)
  816. {
  817. _flags |= BodyFlags.AutoSleep;
  818. }
  819. if (bd.awake)
  820. {
  821. _flags |= BodyFlags.Awake;
  822. }
  823. if (bd.active)
  824. {
  825. _flags |= BodyFlags.Active;
  826. }
  827. _world = world;
  828. _xf.Position = bd.position;
  829. _xf.R.Set(bd.angle);
  830. _sweep.a0 = _sweep.a = bd.angle;
  831. _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter);
  832. _linearVelocity = bd.linearVelocity;
  833. _angularVelocity = bd.angularVelocity;
  834. _linearDamping = bd.linearDamping;
  835. _angularDamping = bd.angularDamping;
  836. _type = bd.type;
  837. if (_type == BodyType.Dynamic)
  838. {
  839. _mass = 1.0f;
  840. _invMass = 1.0f;
  841. }
  842. _userData = bd.userData;
  843. }
  844. internal void SynchronizeFixtures()
  845. {
  846. Transform xf1 = new Transform();
  847. xf1.R.Set(_sweep.a0);
  848. xf1.Position = _sweep.c0 - MathUtils.Multiply(ref xf1.R, _sweep.localCenter);
  849. BroadPhase broadPhase = _world._contactManager._broadPhase;
  850. for (Fixture f = _fixtureList; f != null; f = f._next)
  851. {
  852. f.Synchronize(broadPhase, ref xf1, ref _xf);
  853. }
  854. }
  855. internal void SynchronizeTransform()
  856. {
  857. _xf.R.Set(_sweep.a);
  858. _xf.Position = _sweep.c - MathUtils.Multiply(ref _xf.R, _sweep.localCenter);
  859. }
  860. // This is used to prevent connected bodies from colliding.
  861. // It may lie, depending on the collideConnected flag.
  862. internal bool ShouldCollide(Body other)
  863. {
  864. // At least one body should be dynamic.
  865. if (_type != BodyType.Dynamic && other._type != BodyType.Dynamic)
  866. {
  867. return false;
  868. }
  869. // Does a joint prevent collision?
  870. for (JointEdge jn = _jointList; jn != null; jn = jn.Next)
  871. {
  872. if (jn.Other == other)
  873. {
  874. if (jn.Joint._collideConnected == false)
  875. {
  876. return false;
  877. }
  878. }
  879. }
  880. return true;
  881. }
  882. internal void Advance(float t)
  883. {
  884. // Advance to the new safe time.
  885. _sweep.Advance(t);
  886. _sweep.c = _sweep.c0;
  887. _sweep.a = _sweep.a0;
  888. SynchronizeTransform();
  889. }
  890. /// <summary>
  891. /// Get the world body origin position.
  892. /// </summary>
  893. /// <returns>Return the world position of the body's origin.</returns>
  894. public Vector2 Position
  895. {
  896. get
  897. {
  898. return _xf.Position;
  899. }
  900. set
  901. {
  902. SetTransform(value, Rotation);
  903. }
  904. }
  905. /// <summary>
  906. /// Get the angle in radians.
  907. /// </summary>
  908. /// <returns>Return the current world rotation angle in radians.</returns>
  909. public float Rotation
  910. {
  911. get
  912. {
  913. return _sweep.a;
  914. }
  915. set
  916. {
  917. SetTransform(Position, value);
  918. }
  919. }
  920. internal BodyFlags _flags;
  921. internal BodyType _type;
  922. internal int _islandIndex;
  923. internal Transform _xf; // the body origin transform
  924. internal Sweep _sweep; // the swept motion for CCD
  925. internal Vector2 _linearVelocity;
  926. internal float _angularVelocity;
  927. internal Vector2 _force;
  928. internal float _torque;
  929. internal World _world;
  930. internal Body _prev;
  931. internal Body _next;
  932. internal Fixture _fixtureList;
  933. internal int _fixtureCount;
  934. internal JointEdge _jointList;
  935. internal ContactEdge _contactList;
  936. internal float _mass, _invMass;
  937. // Rotational inertia about the center of mass.
  938. internal float _I, _invI;
  939. internal float _linearDamping;
  940. internal float _angularDamping;
  941. internal float _sleepTime;
  942. internal object _userData;
  943. internal float _intertiaScale;
  944. }
  945. }