Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2016
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.56 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using System.Text;
  6. using FarseerPhysics.Collision;
  7. using FarseerPhysics.Collision.Shapes;
  8. using FarseerPhysics.Common;
  9. using FarseerPhysics.Controllers;
  10. using FarseerPhysics.Dynamics;
  11. using FarseerPhysics.Dynamics.Contacts;
  12. using FarseerPhysics.Dynamics.Joints;
  13. using SFML.Graphics;
  14. using FarseerPhysics;
  15.  
  16. using Transform = FarseerPhysics.Common.Transform;
  17. using CircleShape = FarseerPhysics.Collision.Shapes.CircleShape;
  18.  
  19. namespace Voodoo
  20. {
  21. public class DebugPhysics : DebugViewBase
  22. {
  23. private struct ContactPoint
  24. {
  25. public Vector2 Normal;
  26. public Vector2 Position;
  27. public PointState State;
  28. }
  29.  
  30. public Color DefaultShapeColor = Color.Cyan;
  31. public Color InactiveShapeColor = Color.Yellow;
  32. public Color KinematicShapeColor = Color.Magenta;
  33. public Color SleepingShapeColor = new Color(50, 50 ,50);
  34. public Color StaticShapeColor = Color.Blue;
  35.  
  36. private RenderStates m_renderStates;
  37.  
  38. private const int CircleSegments = 32;
  39. private VertexArray m_TrianglesArray = new VertexArray(PrimitiveType.Triangles);
  40. private VertexArray m_LinesArray = new VertexArray(PrimitiveType.Lines);
  41.  
  42. private Vector2[] _tempVertices = new Vector2[Settings.MaxPolygonVertices];
  43.  
  44. private int _pointCount;
  45. private const int MaxContactPoints = 2048;
  46. private ContactPoint[] _points = new ContactPoint[MaxContactPoints];
  47.  
  48. private bool m_visible;
  49.  
  50. public DebugPhysics(World world)
  51. : base(world)
  52. {
  53.  
  54.  
  55. AppendFlags(DebugViewFlags.AABB |
  56. DebugViewFlags.CenterOfMass |
  57. DebugViewFlags.ContactNormals |
  58. DebugViewFlags.Controllers |
  59. DebugViewFlags.DebugPanel | DebugViewFlags.Joint | DebugViewFlags.PerformanceGraph | DebugViewFlags.PolygonPoints | DebugViewFlags.Shape);
  60.  
  61.  
  62. }
  63.  
  64.  
  65. public override void DrawCircle(Vector2 center, float radius, float red, float blue, float green)
  66. {
  67. DrawCircle(center, radius, new Color((byte)(red * 255), (byte)(green * 255),(byte)(blue * 255)));
  68. }
  69.  
  70. public override void DrawPolygon(Vector2[] vertices, int count, float red, float blue, float green, bool closed = true)
  71. {
  72. DrawPolygon(vertices, count, new Color((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255)), closed);
  73. }
  74.  
  75. public override void DrawSegment(Vector2 start, Vector2 end, float red, float blue, float green)
  76. {
  77. DrawSegment(start, end, new Color((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255)));
  78. }
  79.  
  80. public override void DrawSolidCircle(Vector2 center, float radius, Vector2 axis, float red, float blue, float green)
  81. {
  82. DrawSolidCircle(center, radius, axis, new Color((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255)));
  83. }
  84.  
  85. public override void DrawSolidPolygon(Vector2[] vertices, int count, float red, float blue, float green)
  86. {
  87. DrawSolidPolygon(vertices, count, new Color((byte)(red * 255), (byte)(green * 255), (byte)(blue * 255)));
  88. }
  89.  
  90. public override void DrawTransform(ref FarseerPhysics.Common.Transform transform)
  91. {
  92. /*const float axisScale = 0.4f;
  93. Vector2 p1 = transform.p;
  94.  
  95. Vector2 p2 = p1 + axisScale * transform.q.GetXAxis();
  96. DrawSegment(p1, p2, Color.Red);
  97.  
  98. p2 = p1 + axisScale * transform.q.GetYAxis();
  99. DrawSegment(p1, p2, Color.Green);*/
  100. }
  101.  
  102.  
  103. public void DrawSolidPolygon(Vector2[] vertices, int count, Color color, bool outline = true)
  104. {
  105. if (count == 2)
  106. {
  107. DrawPolygon(vertices, count, color);
  108. return;
  109. }
  110.  
  111. Color colorFill = new Color();
  112. if (outline)
  113. {
  114. byte r = (byte)(color.R / 2);
  115. byte g = (byte)(color.G / 2);
  116. byte b = (byte)(color.B / 2);
  117. colorFill = new Color(r,g,b);
  118. }
  119. else
  120. colorFill = color;
  121.  
  122. for (int i = 1; i < count - 1; i++)
  123. {
  124. m_TrianglesArray.Append(new Vertex(vertices[0].ToSf(), colorFill));
  125. m_TrianglesArray.Append(new Vertex(vertices[i].ToSf(), colorFill));
  126. m_TrianglesArray.Append(new Vertex(vertices[i + 1].ToSf(), colorFill));
  127. }
  128.  
  129. if (outline)
  130. DrawPolygon(vertices, count, color);
  131. }
  132.  
  133. public void DrawPolygon(Vector2[] vertices, int count, Color color, bool closed = true)
  134. {
  135. for (int i = 0; i < count - 1; i++)
  136. {
  137. m_LinesArray.Append(new Vertex(vertices[i].ToSf(), color));
  138. m_LinesArray.Append(new Vertex(vertices[i + 1].ToSf(), color));
  139. }
  140. if (closed)
  141. {
  142. m_LinesArray.Append(new Vertex(vertices[count - 1].ToSf(), color));
  143. m_LinesArray.Append(new Vertex(vertices[0].ToSf(), color));
  144. }
  145.  
  146. }
  147.  
  148. public void DrawSolidCircle(Vector2 center, float radius, Vector2 axis, Color color)
  149. {
  150. const double increment = Math.PI * 2.0 / CircleSegments;
  151. double theta = 0.0;
  152.  
  153. Color colorFill = new Color((byte)(color.R / 2), (byte)(color.G / 2), (byte)(color.B / 2));
  154.  
  155. Vector2 v0 = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
  156. theta += increment;
  157.  
  158. for (int i = 1; i < CircleSegments - 1; i++)
  159. {
  160. Vector2 v1 = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
  161. Vector2 v2 = center + radius * new Vector2((float)Math.Cos(theta + increment), (float)Math.Sin(theta + increment));
  162.  
  163. m_TrianglesArray.Append(new Vertex(v0.ToSf(), colorFill));
  164. m_TrianglesArray.Append(new Vertex(v1.ToSf(), colorFill));
  165. m_TrianglesArray.Append(new Vertex(v2.ToSf(), colorFill));
  166. theta += increment;
  167. }
  168.  
  169. DrawCircle(center, radius, color);
  170. DrawSegment(center, center + axis * radius, color);
  171. }
  172.  
  173. public void DrawCircle(Vector2 center, float radius, Color color)
  174. {
  175. const double increment = Math.PI * 2.0 / CircleSegments;
  176. double theta = 0.0;
  177.  
  178. for (int i = 0; i < CircleSegments; i++)
  179. {
  180. Vector2 v1 = center + radius * new Vector2((float)Math.Cos(theta), (float)Math.Sin(theta));
  181. Vector2 v2 = center + radius * new Vector2((float)Math.Cos(theta + increment), (float)Math.Sin(theta + increment));
  182.  
  183. m_LinesArray.Append(new Vertex(v1.ToSf(), color));
  184. m_LinesArray.Append(new Vertex(v2.ToSf(), color));
  185. theta += increment;
  186. }
  187. }
  188.  
  189. private void DrawSegment(Vector2 start, Vector2 end, Color color)
  190. {
  191. m_LinesArray.Append(new Vertex(start.ToSf(), color));
  192. m_LinesArray.Append(new Vertex(end.ToSf(), color));
  193. }
  194.  
  195. public void DrawAABB(ref AABB aabb, Color color)
  196. {
  197. Vector2[] verts = new Vector2[4];
  198. verts[0] = new Vector2(aabb.LowerBound.X, aabb.LowerBound.Y);
  199. verts[1] = new Vector2(aabb.UpperBound.X, aabb.LowerBound.Y);
  200. verts[2] = new Vector2(aabb.UpperBound.X, aabb.UpperBound.Y);
  201. verts[3] = new Vector2(aabb.LowerBound.X, aabb.UpperBound.Y);
  202.  
  203. DrawPolygon(verts, 4, color.R, color.G, color.B);
  204. }
  205.  
  206. public void DrawPoint(Vector2 p, float size, Color color)
  207. {
  208. Vector2[] verts = new Vector2[4];
  209. float hs = size / 2.0f;
  210. verts[0] = p + new Vector2(-hs, -hs);
  211. verts[1] = p + new Vector2(hs, -hs);
  212. verts[2] = p + new Vector2(hs, hs);
  213. verts[3] = p + new Vector2(-hs, hs);
  214.  
  215. DrawSolidPolygon(verts, 4, color, true);
  216. }
  217.  
  218. private void DrawJoint(Joint joint)
  219. {
  220. if (!joint.Enabled)
  221. return;
  222.  
  223. Body b1 = joint.BodyA;
  224. Body b2 = joint.BodyB;
  225. Transform xf1;
  226. b1.GetTransform(out xf1);
  227.  
  228. Vector2 x2 = Vector2.Zero;
  229.  
  230. // WIP David
  231. if (!joint.IsFixedType())
  232. {
  233. Transform xf2;
  234. b2.GetTransform(out xf2);
  235. x2 = xf2.p;
  236. }
  237.  
  238. Vector2 p1 = joint.WorldAnchorA;
  239. Vector2 p2 = joint.WorldAnchorB;
  240. Vector2 x1 = xf1.p;
  241.  
  242. Color color = new Color(127, 200, 200);
  243.  
  244. switch (joint.JointType)
  245. {
  246. case JointType.Distance:
  247. DrawSegment(p1, p2, color);
  248. break;
  249. case JointType.Pulley:
  250. PulleyJoint pulley = (PulleyJoint)joint;
  251. Vector2 s1 = b1.GetWorldPoint(pulley.LocalAnchorA);
  252. Vector2 s2 = b2.GetWorldPoint(pulley.LocalAnchorB);
  253. DrawSegment(p1, p2, color);
  254. DrawSegment(p1, s1, color);
  255. DrawSegment(p2, s2, color);
  256. break;
  257. case JointType.FixedMouse:
  258. DrawPoint(p1, 0.5f, new Color(0, 255, 0));
  259. DrawSegment(p1, p2, new Color(200, 200, 200));
  260. break;
  261. case JointType.Revolute:
  262. DrawSegment(x1, p1, color);
  263. DrawSegment(p1, p2, color);
  264. DrawSegment(x2, p2, color);
  265.  
  266. DrawSolidCircle(p2, 0.1f, Vector2.Zero, Color.Red);
  267. DrawSolidCircle(p1, 0.1f, Vector2.Zero, Color.Blue);
  268. break;
  269. case JointType.FixedAngle:
  270. //Should not draw anything.
  271. break;
  272. case JointType.FixedRevolute:
  273. DrawSegment(x1, p1, color);
  274. DrawSolidCircle(p1, 0.1f, Vector2.Zero, Color.Magenta);
  275. break;
  276. case JointType.FixedLine:
  277. DrawSegment(x1, p1, color);
  278. DrawSegment(p1, p2, color);
  279. break;
  280. case JointType.FixedDistance:
  281. DrawSegment(x1, p1, color);
  282. DrawSegment(p1, p2, color);
  283. break;
  284. case JointType.FixedPrismatic:
  285. DrawSegment(x1, p1, color);
  286. DrawSegment(p1, p2, color);
  287. break;
  288. case JointType.Gear:
  289. DrawSegment(x1, x2, color);
  290. break;
  291. default:
  292. DrawSegment(x1, p1, color);
  293. DrawSegment(p1, p2, color);
  294. DrawSegment(x2, p2, color);
  295. break;
  296. }
  297. }
  298.  
  299. public void DrawShape(Fixture fixture, Transform xf, Color color)
  300. {
  301. switch (fixture.Shape.ShapeType)
  302. {
  303. case ShapeType.Circle:
  304. {
  305. CircleShape circle = (CircleShape)fixture.Shape;
  306.  
  307. Vector2 center = MathUtils.Mul(ref xf, circle.Position);
  308. float radius = circle.Radius;
  309. Vector2 axis = MathUtils.Mul(xf.q, new Vector2(1.0f, 0.0f));
  310.  
  311. DrawSolidCircle(center, radius, axis, color);
  312. }
  313. break;
  314.  
  315. case ShapeType.Polygon:
  316. {
  317. PolygonShape poly = (PolygonShape)fixture.Shape;
  318. int vertexCount = poly.Vertices.Count;
  319. Debug.Assert(vertexCount <= Settings.MaxPolygonVertices);
  320.  
  321. for (int i = 0; i < vertexCount; ++i)
  322. {
  323. _tempVertices[i] = MathUtils.Mul(ref xf, poly.Vertices[i]);
  324. }
  325.  
  326. DrawSolidPolygon(_tempVertices, vertexCount, color);
  327. }
  328. break;
  329.  
  330.  
  331. case ShapeType.Edge:
  332. {
  333. EdgeShape edge = (EdgeShape)fixture.Shape;
  334. Vector2 v1 = MathUtils.Mul(ref xf, edge.Vertex1);
  335. Vector2 v2 = MathUtils.Mul(ref xf, edge.Vertex2);
  336. DrawSegment(v1, v2, color);
  337. }
  338. break;
  339.  
  340. case ShapeType.Chain:
  341. {
  342. ChainShape chain = (ChainShape)fixture.Shape;
  343.  
  344. for (int i = 0; i < chain.Vertices.Count - 1; ++i)
  345. {
  346. Vector2 v1 = MathUtils.Mul(ref xf, chain.Vertices[i]);
  347. Vector2 v2 = MathUtils.Mul(ref xf, chain.Vertices[i + 1]);
  348. DrawSegment(v1, v2, color);
  349. }
  350. }
  351. break;
  352. }
  353. }
  354.  
  355. internal void DrawDebugData()
  356. {
  357. if (!m_visible)
  358. return;
  359.  
  360. if ((Flags & DebugViewFlags.Shape) == DebugViewFlags.Shape)
  361. {
  362. foreach (Body b in World.BodyList)
  363. {
  364. Transform xf;
  365. b.GetTransform(out xf);
  366. foreach (Fixture f in b.FixtureList)
  367. {
  368. if (b.Enabled == false)
  369. DrawShape(f, xf, InactiveShapeColor);
  370. else if (b.BodyType == BodyType.Static)
  371. DrawShape(f, xf, StaticShapeColor);
  372. else if (b.BodyType == BodyType.Kinematic)
  373. DrawShape(f, xf, KinematicShapeColor);
  374. else if (b.Awake == false)
  375. DrawShape(f, xf, SleepingShapeColor);
  376. else
  377. DrawShape(f, xf, DefaultShapeColor);
  378. }
  379. }
  380. }
  381.  
  382. if ((Flags & DebugViewFlags.ContactPoints) == DebugViewFlags.ContactPoints)
  383. {
  384. const float axisScale = 0.3f;
  385.  
  386. for (int i = 0; i < _pointCount; ++i)
  387. {
  388. ContactPoint point = _points[i];
  389.  
  390. if (point.State == PointState.Add)
  391. DrawPoint(point.Position, 0.1f, new Color(85, 240, 85));
  392. else if (point.State == PointState.Persist)
  393. DrawPoint(point.Position, 0.1f, new Color(85, 85, 240));
  394.  
  395. if ((Flags & DebugViewFlags.ContactNormals) == DebugViewFlags.ContactNormals)
  396. {
  397. Vector2 p1 = point.Position;
  398. Vector2 p2 = p1 + axisScale * point.Normal;
  399. DrawSegment(p1, p2, new Color(100, 230, 100));
  400. }
  401. }
  402.  
  403. _pointCount = 0;
  404. }
  405.  
  406. if ((Flags & DebugViewFlags.PolygonPoints) == DebugViewFlags.PolygonPoints)
  407. {
  408. foreach (Body body in World.BodyList)
  409. {
  410. foreach (Fixture f in body.FixtureList)
  411. {
  412. PolygonShape polygon = f.Shape as PolygonShape;
  413. if (polygon != null)
  414. {
  415. Transform xf;
  416. body.GetTransform(out xf);
  417.  
  418. for (int i = 0; i < polygon.Vertices.Count; i++)
  419. {
  420. Vector2 tmp = MathUtils.Mul(ref xf, polygon.Vertices[i]);
  421. DrawPoint(tmp, 0.1f, Color.Red);
  422. }
  423. }
  424. }
  425. }
  426. }
  427.  
  428. if ((Flags & DebugViewFlags.Joint) == DebugViewFlags.Joint)
  429. {
  430. foreach (Joint j in World.JointList)
  431. {
  432. DrawJoint(j);
  433. }
  434. }
  435.  
  436. if ((Flags & DebugViewFlags.AABB) == DebugViewFlags.AABB)
  437. {
  438. Color color = new Color(230, 85, 230);
  439. IBroadPhase bp = World.ContactManager.BroadPhase;
  440.  
  441. foreach (Body body in World.BodyList)
  442. {
  443. if (body.Enabled == false)
  444. continue;
  445.  
  446. foreach (Fixture f in body.FixtureList)
  447. {
  448. for (int t = 0; t < f.ProxyCount; ++t)
  449. {
  450. FixtureProxy proxy = f.Proxies[t];
  451. AABB aabb;
  452. bp.GetFatAABB(proxy.ProxyId, out aabb);
  453.  
  454. DrawAABB(ref aabb, color);
  455. }
  456. }
  457. }
  458. }
  459.  
  460. if ((Flags & DebugViewFlags.CenterOfMass) == DebugViewFlags.CenterOfMass)
  461. {
  462. foreach (Body b in World.BodyList)
  463. {
  464. Transform xf;
  465. b.GetTransform(out xf);
  466. xf.p = b.WorldCenter;
  467. DrawTransform(ref xf);
  468. }
  469. }
  470.  
  471. if ((Flags & DebugViewFlags.Controllers) == DebugViewFlags.Controllers)
  472. {
  473. for (int i = 0; i < World.ControllerList.Count; i++)
  474. {
  475. Controller controller = World.ControllerList[i];
  476.  
  477. BuoyancyController buoyancy = controller as BuoyancyController;
  478. if (buoyancy != null)
  479. {
  480. AABB container = buoyancy.Container;
  481. DrawAABB(ref container, Color.Cyan);
  482. }
  483. }
  484. }
  485.  
  486. m_game.m_Window.Draw(m_TrianglesArray, m_renderStates);
  487. m_game.m_Window.Draw(m_LinesArray, m_renderStates);
  488. m_TrianglesArray.Clear();
  489. m_LinesArray.Clear();
  490. }
  491. }
  492. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement