box2ddebugdraw.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Box2D QML plugin
  3. * Copyright (C) 2010 Nokia Corporation
  4. *
  5. * This file is part of the Box2D QML plugin.
  6. *
  7. * This library is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation; either version 2.1 of the License, or (at
  10. * your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  14. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  15. * License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this library; If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #include "box2ddebugdraw.h"
  21. #include "box2dworld.h"
  22. #include <Box2D.h>
  23. #include <QPainter>
  24. class DebugDraw : public b2DebugDraw
  25. {
  26. public:
  27. DebugDraw(QPainter *painter, Box2DWorld *world);
  28. void draw();
  29. void DrawPolygon(const b2Vec2 *vertices, int32 vertexCount,
  30. const b2Color &color);
  31. void DrawSolidPolygon(const b2Vec2 *vertices, int32 vertexCount,
  32. const b2Color &color);
  33. void DrawCircle(const b2Vec2 &center, float32 radius,
  34. const b2Color &color);
  35. void DrawSolidCircle(const b2Vec2 &center, float32 radius,
  36. const b2Vec2 &axis, const b2Color &color);
  37. void DrawSegment(const b2Vec2 &p1, const b2Vec2 &p2,
  38. const b2Color &color);
  39. void DrawTransform(const b2Transform &xf);
  40. private:
  41. QPainter *mP;
  42. b2World *mWorld;
  43. };
  44. DebugDraw::DebugDraw(QPainter *painter, Box2DWorld *world)
  45. : mP(painter)
  46. , mWorld(world->world())
  47. {
  48. SetFlags(e_shapeBit |
  49. e_jointBit |
  50. e_aabbBit |
  51. e_pairBit |
  52. e_centerOfMassBit);
  53. }
  54. void DebugDraw::draw()
  55. {
  56. mWorld->SetDebugDraw(this);
  57. mWorld->DrawDebugData();
  58. mWorld->SetDebugDraw(0);
  59. }
  60. static QPointF toQPointF(const b2Vec2 &vec)
  61. {
  62. return QPointF(vec.x * scaleRatio,
  63. -vec.y * scaleRatio);
  64. }
  65. static QColor toQColor(const b2Color &color)
  66. {
  67. return QColor(color.r * 255,
  68. color.g * 255,
  69. color.b * 255);
  70. }
  71. static QPolygonF toQPolygonF(const b2Vec2 *vertices, int32 vertexCount)
  72. {
  73. QPolygonF polygon;
  74. polygon.reserve(vertexCount);
  75. for (int i = 0; i < vertexCount; ++i)
  76. polygon.append(toQPointF(vertices[i]));
  77. return polygon;
  78. }
  79. void DebugDraw::DrawPolygon(const b2Vec2 *vertices, int32 vertexCount,
  80. const b2Color &color)
  81. {
  82. mP->setPen(toQColor(color));
  83. mP->setBrush(Qt::NoBrush);
  84. mP->drawPolygon(toQPolygonF(vertices, vertexCount));
  85. }
  86. void DebugDraw::DrawSolidPolygon(const b2Vec2 *vertices, int32 vertexCount,
  87. const b2Color &color)
  88. {
  89. mP->setPen(Qt::NoPen);
  90. mP->setBrush(toQColor(color));
  91. mP->drawPolygon(toQPolygonF(vertices, vertexCount));
  92. }
  93. void DebugDraw::DrawCircle(const b2Vec2 &center, float32 radius,
  94. const b2Color &color)
  95. {
  96. mP->setPen(toQColor(color));
  97. mP->setBrush(Qt::NoBrush);
  98. mP->drawEllipse(toQPointF(center),
  99. radius * scaleRatio,
  100. radius * scaleRatio);
  101. }
  102. void DebugDraw::DrawSolidCircle(const b2Vec2 &center, float32 radius,
  103. const b2Vec2 &axis, const b2Color &color)
  104. {
  105. Q_UNUSED(axis)
  106. mP->setPen(Qt::NoPen);
  107. mP->setBrush(toQColor(color));
  108. mP->drawEllipse(toQPointF(center),
  109. radius * scaleRatio,
  110. radius * scaleRatio);
  111. }
  112. void DebugDraw::DrawSegment(const b2Vec2 &p1, const b2Vec2 &p2,
  113. const b2Color &color)
  114. {
  115. mP->setPen(toQColor(color));
  116. mP->drawLine(toQPointF(p1), toQPointF(p2));
  117. }
  118. void DebugDraw::DrawTransform(const b2Transform &xf)
  119. {
  120. Q_UNUSED(xf)
  121. // TODO: Not sure how to draw transforms
  122. }
  123. Box2DDebugDraw::Box2DDebugDraw(QDeclarativeItem *parent) :
  124. QDeclarativeItem(parent),
  125. mWorld(0)
  126. {
  127. setFlag(QGraphicsItem::ItemHasNoContents, false);
  128. }
  129. void Box2DDebugDraw::setWorld(Box2DWorld *world)
  130. {
  131. if (mWorld == world)
  132. return;
  133. if (mWorld)
  134. mWorld->disconnect(this);
  135. mWorld = world;
  136. if (mWorld)
  137. connect(mWorld, SIGNAL(stepped()), SLOT(onWorldStepped()));
  138. }
  139. void Box2DDebugDraw::paint(QPainter *p, const QStyleOptionGraphicsItem *,
  140. QWidget *)
  141. {
  142. if (!mWorld)
  143. return;
  144. // Darken the view to make the debug draw stand out more
  145. p->fillRect(0, 0, width(), height(), QColor(0, 0, 0, 128));
  146. DebugDraw debugDraw(p, mWorld);
  147. debugDraw.draw();
  148. }
  149. void Box2DDebugDraw::onWorldStepped()
  150. {
  151. if (isVisible() && opacity() > 0)
  152. update();
  153. }