PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/PhysicsEngines/Jitter/JitterBody.cs

#
C# | 521 lines | 346 code | 47 blank | 128 comment | 4 complexity | dde6c5eeb4661de6c078fb8741b3a6df MD5 | raw file
Possible License(s): Apache-2.0
  1. using System.Collections.Generic;
  2. using Delta.PhysicsEngines.Enums;
  3. using Delta.Rendering.Models;
  4. using Delta.Utilities.Datatypes;
  5. using Delta.Utilities.Helpers;
  6. using Jitter.Collision.Shapes;
  7. using Jitter.Dynamics;
  8. using Jitter.LinearMath;
  9. namespace Delta.PhysicsEngines.Jitter
  10. {
  11. /// <summary>
  12. /// Jitter body implementation.
  13. /// </summary>
  14. internal class JitterBody : PhysicsBody
  15. {
  16. #region Body (Public)
  17. /// <summary>
  18. /// Gets the body.
  19. /// </summary>
  20. public RigidBody Body
  21. {
  22. get
  23. {
  24. return jitterBody;
  25. }
  26. }
  27. #endregion
  28. #region Position (Public)
  29. /// <summary>
  30. /// Position given in world space.
  31. /// </summary>
  32. public override Vector Position
  33. {
  34. get
  35. {
  36. JitterDatatypesMapping.Convert(jitterBody.Position, out position);
  37. return position;
  38. }
  39. set
  40. {
  41. jitterBody.Position = JitterDatatypesMapping.Convert(ref value);
  42. }
  43. }
  44. #endregion
  45. #region Position2D (Public)
  46. /// <summary>
  47. /// Position 2D given in world space (same as Position, just easier to
  48. /// access for 2D code not having to convert Position to a Point anymore).
  49. /// </summary>
  50. public override Point Position2D
  51. {
  52. get
  53. {
  54. position2D.X = jitterBody.Position.X;
  55. position2D.Y = jitterBody.Position.Y;
  56. return position2D;
  57. }
  58. set
  59. {
  60. // This is 3D physics engine, so do nothing by default.
  61. }
  62. }
  63. #endregion
  64. #region RotationMatrix (Public)
  65. /// <summary>
  66. /// Returns the rotation matrix from Jitter back for rendering.
  67. /// </summary>
  68. public override Matrix RotationMatrix
  69. {
  70. get
  71. {
  72. JitterDatatypesMapping.Convert(jitterBody.Orientation,
  73. ref rotationMatrix);
  74. return rotationMatrix;
  75. }
  76. set
  77. {
  78. if (jitterBody != null)
  79. {
  80. jitterBody.Orientation = JitterDatatypesMapping.Convert(ref value);
  81. }
  82. }
  83. }
  84. #endregion
  85. #region LinearVelocity (Public)
  86. /// <summary>
  87. /// The linear velocity of the body.
  88. /// </summary>
  89. public override Vector LinearVelocity
  90. {
  91. get
  92. {
  93. JitterDatatypesMapping.Convert(jitterBody.LinearVelocity,
  94. out linearVelocity);
  95. return linearVelocity;
  96. }
  97. set
  98. {
  99. jitterBody.LinearVelocity = JitterDatatypesMapping.Convert(ref value);
  100. }
  101. }
  102. #endregion
  103. #region AngularVelocity (Public)
  104. /// <summary>
  105. /// The angular velocity of the body.
  106. /// <remarks>
  107. /// For 2D physics simulation only X component is used.
  108. /// </remarks>
  109. /// </summary>
  110. public override Vector AngularVelocity
  111. {
  112. get
  113. {
  114. JitterDatatypesMapping.Convert(jitterBody.AngularVelocity,
  115. out angularVelocity);
  116. return angularVelocity;
  117. }
  118. set
  119. {
  120. jitterBody.AngularVelocity = JitterDatatypesMapping.Convert(ref value);
  121. }
  122. }
  123. #endregion
  124. #region AngularVelocity2D (Public)
  125. /// <summary>
  126. /// Angular velocity 2D as a float, for 2D only the .x component is used!
  127. /// </summary>
  128. public override float AngularVelocity2D
  129. {
  130. get
  131. {
  132. return jitterBody.AngularVelocity.X;
  133. }
  134. set
  135. {
  136. jitterBody.AngularVelocity = new JVector(value, 0f, 0f);
  137. }
  138. }
  139. #endregion
  140. #region Mass (Public)
  141. /// <summary>
  142. /// Gets or sets the mass. Usually in kilograms (kg).
  143. /// </summary>
  144. public override float Mass
  145. {
  146. get
  147. {
  148. return base.Mass;
  149. }
  150. set
  151. {
  152. jitterBody.Mass = value;
  153. }
  154. }
  155. #endregion
  156. #region Restitution (Public)
  157. /// <summary>
  158. /// Gets the restitution of the body.
  159. /// </summary>
  160. public override float Restitution
  161. {
  162. get
  163. {
  164. return base.Restitution;
  165. }
  166. set
  167. {
  168. jitterBody.Material.Restitution = value;
  169. base.Restitution = value;
  170. }
  171. }
  172. #endregion
  173. #region BoundingBox (Public)
  174. /// <summary>
  175. /// Gets the BoundingBox of the body.
  176. /// <remarks>
  177. /// Used during 3D simulation.
  178. /// </remarks>
  179. /// </summary>
  180. public override BoundingBox BoundingBox
  181. {
  182. get
  183. {
  184. JitterDatatypesMapping.Convert(jitterBody.BoundingBox.Min,
  185. out bounds.Min);
  186. JitterDatatypesMapping.Convert(jitterBody.BoundingBox.Max,
  187. out bounds.Max);
  188. return bounds;
  189. }
  190. }
  191. #endregion
  192. #region Private
  193. #region physicsManager (Private)
  194. private JitterPhysics physicsManager;
  195. #endregion
  196. #region jitterBody (Private)
  197. private readonly RigidBody jitterBody;
  198. #endregion
  199. #region jitterShape (Private)
  200. private Shape jitterShape;
  201. #endregion
  202. #region position (Private)
  203. private Vector position;
  204. #endregion
  205. #region position2D (Private)
  206. private Point position2D;
  207. #endregion
  208. #region rotationMatrix (Private)
  209. /// <summary>
  210. /// Create rotation matrix to be filled in by the Jitter matrix. It is
  211. /// very important that M44 is set to 1.0 to be rendered correctly!
  212. /// </summary>
  213. private Matrix rotationMatrix = Matrix.Identity;
  214. #endregion
  215. #region linearVelocity (Private)
  216. private Vector linearVelocity;
  217. #endregion
  218. #region angularVelocity (Private)
  219. private Vector angularVelocity;
  220. #endregion
  221. #region bounds (Private)
  222. private BoundingBox bounds;
  223. #endregion
  224. #endregion
  225. #region Constructors
  226. /// <summary>
  227. /// Constructor
  228. /// </summary>
  229. /// <param name="physicsManager">The physics manager.</param>
  230. /// <param name="shape">The shape.</param>
  231. /// <param name="setInitialPosition">Body initial position.</param>
  232. public JitterBody(JitterPhysics physicsManager, PhysicsShape shape,
  233. Vector setInitialPosition)
  234. : base(false, shape, setInitialPosition)
  235. {
  236. this.physicsManager = physicsManager;
  237. // First create shape
  238. CreateShape();
  239. // And set the rotation matrix again (needs created shape)
  240. RotationMatrix = Matrix.Identity;
  241. // Jitter needs the shape on body creation.
  242. jitterBody = new RigidBody(jitterShape);
  243. jitterBody.IsStatic = false;
  244. jitterBody.Mass = base.mass;
  245. jitterBody.Material.Restitution = base.restitution;
  246. jitterBody.Position =
  247. JitterDatatypesMapping.Convert(ref setInitialPosition);
  248. jitterBody.Tag = this;
  249. physicsManager.jitterWorld.AddBody(jitterBody);
  250. }
  251. /// <summary>
  252. /// Internal constructor for creating GroundBody.
  253. /// </summary>
  254. /// <param name="physicsManager">Jitter physics manager.</param>
  255. /// <param name="jitterBody">Initial jitter body created manually.</param>
  256. internal JitterBody(JitterPhysics physicsManager, RigidBody jitterBody)
  257. : base(false, null, Vector.Zero)
  258. {
  259. this.physicsManager = physicsManager;
  260. this.jitterBody = jitterBody;
  261. this.jitterBody.Tag = this;
  262. jitterShape = jitterBody.Shape;
  263. }
  264. #endregion
  265. #region ApplyForce (Public)
  266. /// <summary>
  267. /// Applies a force at the center of mass.
  268. /// </summary>
  269. /// <param name="force">The force.</param>
  270. public override void ApplyForce(Vector force)
  271. {
  272. jitterBody.AddForce(JitterDatatypesMapping.Convert(ref force));
  273. }
  274. /// <summary>
  275. /// Apply a force at a world point. If the force is not
  276. /// applied at the center of mass, it will generate a torque and
  277. /// affect the angular velocity. This wakes up the body.
  278. /// </summary>
  279. /// <param name="force">Force vector data.</param>
  280. /// <param name="position">Position in 3D where to apply force.</param>
  281. public override void ApplyForce(Vector force, Vector position)
  282. {
  283. jitterBody.AddForce(
  284. JitterDatatypesMapping.Convert(ref force),
  285. JitterDatatypesMapping.Convert(ref position)
  286. );
  287. }
  288. #endregion
  289. #region ApplyTorque (Public)
  290. /// <summary>
  291. /// Apply a torque. This affects the angular velocity without affecting the
  292. /// linear velocity of the center of mass.
  293. /// <remarks>
  294. /// This wakes up the body.
  295. /// </remarks>
  296. /// </summary>
  297. /// <param name="torque">
  298. /// Vector containing torque data for both 2D and 3D shapes.
  299. /// </param>
  300. public override void ApplyTorque(Vector torque)
  301. {
  302. jitterBody.AddTorque(JitterDatatypesMapping.Convert(ref torque));
  303. }
  304. #endregion
  305. #region ApplyLinearImpulse (Public)
  306. /// <summary>
  307. /// Apply an impulse at a point. This immediately modifies the velocity.
  308. /// <remarks>
  309. /// This wakes up the body.
  310. /// </remarks>
  311. /// </summary>
  312. /// <param name="impulse">Impulse vector data.</param>
  313. public override void ApplyLinearImpulse(Vector impulse)
  314. {
  315. jitterBody.ApplyImpulse(JitterDatatypesMapping.Convert(ref impulse));
  316. }
  317. /// <summary>
  318. /// Apply an impulse at a point. This immediately modifies the velocity.
  319. /// It also modifies the angular velocity if the point of application
  320. /// is not at the center of mass.
  321. /// <remarks>
  322. /// This wakes up the body.
  323. /// </remarks>
  324. /// </summary>
  325. /// <param name="impulse">Impulse vector data.</param>
  326. /// <param name="position">Position in 3D where to apply impulse.</param>
  327. public override void ApplyLinearImpulse(Vector impulse, Vector position)
  328. {
  329. jitterBody.ApplyImpulse(
  330. JitterDatatypesMapping.Convert(ref impulse),
  331. JitterDatatypesMapping.Convert(ref position));
  332. }
  333. #endregion
  334. #region ApplyAngularImpulse (Public)
  335. /// <summary>
  336. /// Apply an angular impulse.
  337. /// </summary>
  338. /// <param name="impulse">
  339. /// Vector containing impulse data for both 2D and 3D shapes.
  340. /// </param>
  341. public override void ApplyAngularImpulse(Vector impulse)
  342. {
  343. jitterBody.ApplyImpulse(JitterDatatypesMapping.Convert(ref impulse));
  344. }
  345. #endregion
  346. #region Methods (Private)
  347. #region CreateShape
  348. /// <summary>
  349. /// Creates Jitter shape from properties.
  350. /// </summary>
  351. private void CreateShape()
  352. {
  353. Dictionary<PhysicsShape.PropertyType, object> properties =
  354. base.Shape.Properties;
  355. switch (Shape.ShapeType)
  356. {
  357. case ShapeType.Sphere:
  358. jitterShape = new SphereShape(
  359. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  360. properties, PhysicsShape.PropertyType.Radius));
  361. break;
  362. case ShapeType.Box:
  363. Vector size =
  364. ArrayHelper.SafeGet<PhysicsShape.PropertyType, Vector>(
  365. properties, PhysicsShape.PropertyType.Size);
  366. jitterShape = new BoxShape(
  367. size.Y, size.Z, size.X
  368. );
  369. break;
  370. case ShapeType.Capsule:
  371. jitterShape = new CapsuleShape(
  372. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  373. properties, PhysicsShape.PropertyType.Depth),
  374. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  375. properties, PhysicsShape.PropertyType.Radius)
  376. );
  377. break;
  378. case ShapeType.Cone:
  379. jitterShape = new ConeShape(
  380. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  381. properties, PhysicsShape.PropertyType.Height),
  382. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  383. properties, PhysicsShape.PropertyType.Radius)
  384. );
  385. break;
  386. case ShapeType.Cylinder:
  387. jitterShape = new CylinderShape(
  388. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  389. properties, PhysicsShape.PropertyType.Height),
  390. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  391. properties, PhysicsShape.PropertyType.Radius)
  392. );
  393. break;
  394. case ShapeType.Triangle:
  395. jitterShape = Helpers.CreateFrom(
  396. ArrayHelper.SafeGet<PhysicsShape.PropertyType, Mesh>(
  397. properties, PhysicsShape.PropertyType.Mesh),
  398. ArrayHelper.SafeGet<PhysicsShape.PropertyType, Matrix>(
  399. properties, PhysicsShape.PropertyType.LocalSpaceMatrix),
  400. ArrayHelper.SafeGet<PhysicsShape.PropertyType, bool>(
  401. properties, PhysicsShape.PropertyType.InvertTriangles));
  402. break;
  403. case ShapeType.Terrain:
  404. jitterShape = new TerrainShape(
  405. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float[,]>(
  406. properties, PhysicsShape.PropertyType.Height),
  407. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  408. properties, PhysicsShape.PropertyType.ScaleX),
  409. ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
  410. properties, PhysicsShape.PropertyType.ScaleY)
  411. );
  412. break;
  413. }
  414. }
  415. #endregion
  416. #region FireCollisionBegin
  417. /// <summary>
  418. /// Method for access collision event from JitterPhysicsManager.
  419. /// </summary>
  420. /// <param name="other">Other body with which collision begin.</param>
  421. internal void FireCollisionBegin(PhysicsBody other)
  422. {
  423. base.OnCollisionBegin(other);
  424. }
  425. #endregion
  426. #region FireCollisionEnd
  427. /// <summary>
  428. /// Method for access collision event from JitterPhysicsManager.
  429. /// </summary>
  430. /// <param name="other">Other body with which collision end.</param>
  431. internal void FireCollisionEnd(PhysicsBody other)
  432. {
  433. base.OnCollisionEnd(other);
  434. }
  435. #endregion
  436. #region SetIsStatic
  437. /// <summary>
  438. /// Set if the body should be static or not.
  439. /// </summary>
  440. /// <param name="value">True if body should be static, otherwise False.
  441. /// </param>
  442. protected override void SetIsStatic(bool value)
  443. {
  444. jitterBody.IsStatic = value;
  445. }
  446. #endregion
  447. #region SetIsActive
  448. /// <summary>
  449. /// Set if the body should be active or not.
  450. /// </summary>
  451. /// <param name="value">True if body should be active, otherwise False.
  452. /// </param>
  453. protected override void SetIsActive(bool value)
  454. {
  455. jitterBody.IsActive = value;
  456. }
  457. #endregion
  458. #region SetFriction
  459. /// <summary>
  460. /// Set the friction of the body.
  461. /// </summary>
  462. /// <param name="value">Friction value to set.</param>
  463. protected override void SetFriction(float value)
  464. {
  465. Body.Material.DynamicFriction = value;
  466. if (IsStatic)
  467. {
  468. jitterBody.Material.StaticFriction = value;
  469. }
  470. }
  471. #endregion
  472. #endregion
  473. }
  474. }