cpSpaceDebug.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. * SOFTWARE.
  20. */
  21. #include "chipmunk/chipmunk_private.h"
  22. #ifndef CP_SPACE_DISABLE_DEBUG_API
  23. static void
  24. cpSpaceDebugDrawShape(cpShape *shape, cpSpaceDebugDrawOptions *options)
  25. {
  26. cpBody *body = shape->body;
  27. cpDataPointer data = options->data;
  28. cpSpaceDebugColor outline_color = options->shapeOutlineColor;
  29. cpSpaceDebugColor fill_color = options->colorForShape(shape, data);
  30. switch(shape->klass->type){
  31. case CP_CIRCLE_SHAPE: {
  32. cpCircleShape *circle = (cpCircleShape *)shape;
  33. options->drawCircle(circle->tc, body->a, circle->r, outline_color, fill_color, data);
  34. break;
  35. }
  36. case CP_SEGMENT_SHAPE: {
  37. cpSegmentShape *seg = (cpSegmentShape *)shape;
  38. options->drawFatSegment(seg->ta, seg->tb, seg->r, outline_color, fill_color, data);
  39. break;
  40. }
  41. case CP_POLY_SHAPE: {
  42. cpPolyShape *poly = (cpPolyShape *)shape;
  43. int count = poly->count;
  44. struct cpSplittingPlane *planes = poly->planes;
  45. cpVect *verts = (cpVect *)alloca(count*sizeof(cpVect));
  46. for(int i=0; i<count; i++) verts[i] = planes[i].v0;
  47. options->drawPolygon(count, verts, poly->r, outline_color, fill_color, data);
  48. break;
  49. }
  50. default: break;
  51. }
  52. }
  53. static const cpVect spring_verts[] = {
  54. {0.00f, 0.0f},
  55. {0.20f, 0.0f},
  56. {0.25f, 3.0f},
  57. {0.30f,-6.0f},
  58. {0.35f, 6.0f},
  59. {0.40f,-6.0f},
  60. {0.45f, 6.0f},
  61. {0.50f,-6.0f},
  62. {0.55f, 6.0f},
  63. {0.60f,-6.0f},
  64. {0.65f, 6.0f},
  65. {0.70f,-3.0f},
  66. {0.75f, 6.0f},
  67. {0.80f, 0.0f},
  68. {1.00f, 0.0f},
  69. };
  70. static const int spring_count = sizeof(spring_verts)/sizeof(cpVect);
  71. static void
  72. cpSpaceDebugDrawConstraint(cpConstraint *constraint, cpSpaceDebugDrawOptions *options)
  73. {
  74. cpDataPointer data = options->data;
  75. cpSpaceDebugColor color = options->constraintColor;
  76. cpBody *body_a = constraint->a;
  77. cpBody *body_b = constraint->b;
  78. if(cpConstraintIsPinJoint(constraint)){
  79. cpPinJoint *joint = (cpPinJoint *)constraint;
  80. cpVect a = cpTransformPoint(body_a->transform, joint->anchorA);
  81. cpVect b = cpTransformPoint(body_b->transform, joint->anchorB);
  82. options->drawDot(5, a, color, data);
  83. options->drawDot(5, b, color, data);
  84. options->drawSegment(a, b, color, data);
  85. } else if(cpConstraintIsSlideJoint(constraint)){
  86. cpSlideJoint *joint = (cpSlideJoint *)constraint;
  87. cpVect a = cpTransformPoint(body_a->transform, joint->anchorA);
  88. cpVect b = cpTransformPoint(body_b->transform, joint->anchorB);
  89. options->drawDot(5, a, color, data);
  90. options->drawDot(5, b, color, data);
  91. options->drawSegment(a, b, color, data);
  92. } else if(cpConstraintIsPivotJoint(constraint)){
  93. cpPivotJoint *joint = (cpPivotJoint *)constraint;
  94. cpVect a = cpTransformPoint(body_a->transform, joint->anchorA);
  95. cpVect b = cpTransformPoint(body_b->transform, joint->anchorB);
  96. options->drawDot(5, a, color, data);
  97. options->drawDot(5, b, color, data);
  98. } else if(cpConstraintIsGrooveJoint(constraint)){
  99. cpGrooveJoint *joint = (cpGrooveJoint *)constraint;
  100. cpVect a = cpTransformPoint(body_a->transform, joint->grv_a);
  101. cpVect b = cpTransformPoint(body_a->transform, joint->grv_b);
  102. cpVect c = cpTransformPoint(body_b->transform, joint->anchorB);
  103. options->drawDot(5, c, color, data);
  104. options->drawSegment(a, b, color, data);
  105. } else if(cpConstraintIsDampedSpring(constraint)){
  106. cpDampedSpring *spring = (cpDampedSpring *)constraint;
  107. cpDataPointer data = options->data;
  108. cpSpaceDebugColor color = options->constraintColor;
  109. cpVect a = cpTransformPoint(body_a->transform, spring->anchorA);
  110. cpVect b = cpTransformPoint(body_b->transform, spring->anchorB);
  111. options->drawDot(5, a, color, data);
  112. options->drawDot(5, b, color, data);
  113. cpVect delta = cpvsub(b, a);
  114. cpFloat cos = delta.x;
  115. cpFloat sin = delta.y;
  116. cpFloat s = 1.0f/cpvlength(delta);
  117. cpVect r1 = cpv(cos, -sin*s);
  118. cpVect r2 = cpv(sin, cos*s);
  119. cpVect *verts = (cpVect *)alloca(spring_count*sizeof(cpVect));
  120. for(int i=0; i<spring_count; i++){
  121. cpVect v = spring_verts[i];
  122. verts[i] = cpv(cpvdot(v, r1) + a.x, cpvdot(v, r2) + a.y);
  123. }
  124. for(int i=0; i<spring_count-1; i++){
  125. options->drawSegment(verts[i], verts[i + 1], color, data);
  126. }
  127. }
  128. }
  129. void
  130. cpSpaceDebugDraw(cpSpace *space, cpSpaceDebugDrawOptions *options)
  131. {
  132. if(options->flags & CP_SPACE_DEBUG_DRAW_SHAPES){
  133. cpSpaceEachShape(space, (cpSpaceShapeIteratorFunc)cpSpaceDebugDrawShape, options);
  134. }
  135. if(options->flags & CP_SPACE_DEBUG_DRAW_CONSTRAINTS){
  136. cpSpaceEachConstraint(space, (cpSpaceConstraintIteratorFunc)cpSpaceDebugDrawConstraint, options);
  137. }
  138. if(options->flags & CP_SPACE_DEBUG_DRAW_COLLISION_POINTS){
  139. cpArray *arbiters = space->arbiters;
  140. cpSpaceDebugColor color = options->collisionPointColor;
  141. cpSpaceDebugDrawSegmentImpl draw_seg = options->drawSegment;
  142. cpDataPointer data = options->data;
  143. for(int i=0; i<arbiters->num; i++){
  144. cpArbiter *arb = (cpArbiter*)arbiters->arr[i];
  145. cpVect n = arb->n;
  146. for(int j=0; j<arb->count; j++){
  147. cpVect p1 = cpvadd(arb->body_a->p, arb->contacts[j].r1);
  148. cpVect p2 = cpvadd(arb->body_b->p, arb->contacts[j].r2);
  149. cpFloat d = 2.0f;
  150. cpVect a = cpvadd(p1, cpvmult(n, -d));
  151. cpVect b = cpvadd(p2, cpvmult(n, d));
  152. draw_seg(a, b, color, data);
  153. }
  154. }
  155. }
  156. }
  157. #endif