2
0

AdvancedDemo1.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System.Collections.Generic;
  2. using System.Text;
  3. using FarseerPhysics.Common;
  4. using FarseerPhysics.Common.Decomposition;
  5. using FarseerPhysics.Common.PolygonManipulation;
  6. using FarseerPhysics.Dynamics;
  7. using FarseerPhysics.Factories;
  8. using Microsoft.Xna.Framework;
  9. using Microsoft.Xna.Framework.Graphics;
  10. namespace FarseerPhysics.SamplesFramework
  11. {
  12. internal class AdvancedDemo1 : PhysicsGameScreen, IDemoScreen
  13. {
  14. private Border _border;
  15. private Body _compound;
  16. private Vector2 _origin;
  17. private Texture2D _polygonTexture;
  18. private float _scale;
  19. #region IDemoScreen Members
  20. public string GetTitle()
  21. {
  22. return "Texture to vertices";
  23. }
  24. public string GetDetails()
  25. {
  26. StringBuilder sb = new StringBuilder();
  27. sb.AppendLine("TODO: Add sample description!");
  28. sb.AppendLine(string.Empty);
  29. sb.AppendLine("GamePad:");
  30. sb.AppendLine(" - Move cursor: left thumbstick");
  31. sb.AppendLine(" - Grab object (beneath cursor): A button");
  32. sb.AppendLine(" - Drag grabbed object: left thumbstick");
  33. sb.AppendLine(" - Exit to menu: Back button");
  34. sb.AppendLine(string.Empty);
  35. sb.AppendLine("Keyboard:");
  36. sb.AppendLine(" - Exit to menu: Escape");
  37. sb.AppendLine(string.Empty);
  38. sb.AppendLine("Mouse / Touchscreen");
  39. sb.AppendLine(" - Grab object (beneath cursor): Left click");
  40. sb.AppendLine(" - Drag grabbed object: move mouse / finger");
  41. return sb.ToString();
  42. }
  43. #endregion
  44. public override void LoadContent()
  45. {
  46. base.LoadContent();
  47. World.Gravity = Vector2.Zero;
  48. _border = new Border(World, this, ScreenManager.GraphicsDevice.Viewport);
  49. //load texture that will represent the physics body
  50. _polygonTexture = ScreenManager.Content.Load<Texture2D>("Samples/object");
  51. //Create an array to hold the data from the texture
  52. uint[] data = new uint[_polygonTexture.Width * _polygonTexture.Height];
  53. //Transfer the texture data to the array
  54. _polygonTexture.GetData(data);
  55. //Find the vertices that makes up the outline of the shape in the texture
  56. Vertices textureVertices = PolygonTools.CreatePolygon(data, _polygonTexture.Width, false);
  57. //The tool return vertices as they were found in the texture.
  58. //We need to find the real center (centroid) of the vertices for 2 reasons:
  59. //1. To translate the vertices so the polygon is centered around the centroid.
  60. Vector2 centroid = -textureVertices.GetCentroid();
  61. textureVertices.Translate(ref centroid);
  62. //2. To draw the texture the correct place.
  63. _origin = -centroid;
  64. //We simplify the vertices found in the texture.
  65. textureVertices = SimplifyTools.ReduceByDistance(textureVertices, 4f);
  66. //Since it is a concave polygon, we need to partition it into several smaller convex polygons
  67. List<Vertices> list = BayazitDecomposer.ConvexPartition(textureVertices);
  68. //Adjust the scale of the object for WP7's lower resolution
  69. #if WINDOWS_PHONE
  70. _scale = 0.6f;
  71. #else
  72. _scale = 1f;
  73. #endif
  74. //scale the vertices from graphics space to sim space
  75. Vector2 vertScale = new Vector2(ConvertUnits.ToSimUnits(1)) * _scale;
  76. foreach (Vertices vertices in list)
  77. {
  78. vertices.Scale(ref vertScale);
  79. }
  80. //Create a single body with multiple fixtures
  81. _compound = BodyFactory.CreateCompoundPolygon(World, list, 1f, BodyType.Dynamic);
  82. _compound.BodyType = BodyType.Dynamic;
  83. }
  84. public override void Draw(GameTime gameTime)
  85. {
  86. ScreenManager.SpriteBatch.Begin(0, null, null, null, null, null, Camera.View);
  87. ScreenManager.SpriteBatch.Draw(_polygonTexture, ConvertUnits.ToDisplayUnits(_compound.Position),
  88. null, Color.Tomato, _compound.Rotation, _origin, _scale, SpriteEffects.None,
  89. 0f);
  90. ScreenManager.SpriteBatch.End();
  91. _border.Draw();
  92. base.Draw(gameTime);
  93. }
  94. }
  95. }