chipmunk 5.3.4.5 → 6.1.3.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/ext/chipmunk/chipmunk.c +199 -28
  2. data/ext/chipmunk/chipmunk.h +123 -68
  3. data/ext/chipmunk/chipmunk_ffi.h +129 -11
  4. data/ext/chipmunk/chipmunk_private.h +232 -16
  5. data/ext/chipmunk/chipmunk_types.h +94 -30
  6. data/ext/chipmunk/chipmunk_unsafe.h +12 -3
  7. data/ext/chipmunk/constraints/cpConstraint.h +90 -34
  8. data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
  9. data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
  10. data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
  11. data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
  12. data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
  13. data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
  14. data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
  15. data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
  16. data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
  17. data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
  18. data/ext/chipmunk/constraints/util.h +36 -44
  19. data/ext/chipmunk/cpArbiter.c +159 -94
  20. data/ext/chipmunk/cpArbiter.h +135 -129
  21. data/ext/chipmunk/cpArray.c +37 -56
  22. data/ext/chipmunk/cpBB.c +1 -12
  23. data/ext/chipmunk/cpBB.h +80 -18
  24. data/ext/chipmunk/cpBBTree.c +891 -0
  25. data/ext/chipmunk/cpBody.c +185 -47
  26. data/ext/chipmunk/cpBody.h +156 -124
  27. data/ext/chipmunk/cpCollision.c +126 -115
  28. data/ext/chipmunk/cpConstraint.c +10 -6
  29. data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
  30. data/ext/chipmunk/cpDampedSpring.c +25 -18
  31. data/ext/chipmunk/cpGearJoint.c +23 -17
  32. data/ext/chipmunk/cpGrooveJoint.c +26 -22
  33. data/ext/chipmunk/cpHashSet.c +51 -51
  34. data/ext/chipmunk/cpPinJoint.c +26 -19
  35. data/ext/chipmunk/cpPivotJoint.c +23 -19
  36. data/ext/chipmunk/cpPolyShape.c +93 -69
  37. data/ext/chipmunk/cpPolyShape.h +33 -69
  38. data/ext/chipmunk/cpRatchetJoint.c +26 -21
  39. data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
  40. data/ext/chipmunk/cpShape.c +122 -133
  41. data/ext/chipmunk/cpShape.h +146 -95
  42. data/ext/chipmunk/cpSimpleMotor.c +24 -17
  43. data/ext/chipmunk/cpSlideJoint.c +28 -26
  44. data/ext/chipmunk/cpSpace.c +251 -196
  45. data/ext/chipmunk/cpSpace.h +173 -103
  46. data/ext/chipmunk/cpSpaceComponent.c +236 -159
  47. data/ext/chipmunk/cpSpaceHash.c +259 -159
  48. data/ext/chipmunk/cpSpaceQuery.c +127 -59
  49. data/ext/chipmunk/cpSpaceStep.c +235 -197
  50. data/ext/chipmunk/cpSpatialIndex.c +69 -0
  51. data/ext/chipmunk/cpSpatialIndex.h +227 -0
  52. data/ext/chipmunk/cpSweep1D.c +254 -0
  53. data/ext/chipmunk/cpVect.c +11 -26
  54. data/ext/chipmunk/cpVect.h +76 -71
  55. data/ext/chipmunk/extconf.rb +4 -31
  56. data/ext/chipmunk/prime.h +1 -1
  57. data/ext/chipmunk/rb_chipmunk.c +36 -45
  58. data/ext/chipmunk/rb_chipmunk.h +6 -3
  59. data/ext/chipmunk/rb_cpArbiter.c +2 -2
  60. data/ext/chipmunk/rb_cpBB.c +116 -35
  61. data/ext/chipmunk/rb_cpBody.c +5 -12
  62. data/ext/chipmunk/rb_cpConstraint.c +144 -9
  63. data/ext/chipmunk/rb_cpShape.c +69 -78
  64. data/ext/chipmunk/rb_cpSpace.c +81 -76
  65. metadata +61 -61
  66. data/LICENSE +0 -22
  67. data/README +0 -110
  68. data/Rakefile +0 -102
  69. data/ext/chipmunk/cpArray.h +0 -49
  70. data/ext/chipmunk/cpCollision.h +0 -28
  71. data/ext/chipmunk/cpHashSet.h +0 -82
  72. data/ext/chipmunk/cpSpaceHash.h +0 -110
  73. data/lib/chipmunk.rb +0 -194
@@ -19,16 +19,14 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include <stdlib.h>
23
- //#include <math.h>
24
-
25
22
  #include "chipmunk_private.h"
26
23
  #include "constraints/util.h"
27
24
 
28
25
  static void
29
- preStep(cpPinJoint *joint, cpFloat dt, cpFloat dt_inv)
26
+ preStep(cpPinJoint *joint, cpFloat dt)
30
27
  {
31
- CONSTRAINT_BEGIN(joint, a, b);
28
+ cpBody *a = joint->constraint.a;
29
+ cpBody *b = joint->constraint.b;
32
30
 
33
31
  joint->r1 = cpvrotate(joint->anchr1, a->rot);
34
32
  joint->r2 = cpvrotate(joint->anchr2, b->rot);
@@ -42,29 +40,35 @@ preStep(cpPinJoint *joint, cpFloat dt, cpFloat dt_inv)
42
40
 
43
41
  // calculate bias velocity
44
42
  cpFloat maxBias = joint->constraint.maxBias;
45
- joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(dist - joint->dist), -maxBias, maxBias);
46
-
47
- // compute max impulse
48
- joint->jnMax = J_MAX(joint, dt);
43
+ joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*(dist - joint->dist)/dt, -maxBias, maxBias);
44
+ }
45
+
46
+ static void
47
+ applyCachedImpulse(cpPinJoint *joint, cpFloat dt_coef)
48
+ {
49
+ cpBody *a = joint->constraint.a;
50
+ cpBody *b = joint->constraint.b;
49
51
 
50
- // apply accumulated impulse
51
- cpVect j = cpvmult(joint->n, joint->jnAcc);
52
+ cpVect j = cpvmult(joint->n, joint->jnAcc*dt_coef);
52
53
  apply_impulses(a, b, joint->r1, joint->r2, j);
53
54
  }
54
55
 
55
56
  static void
56
- applyImpulse(cpPinJoint *joint)
57
+ applyImpulse(cpPinJoint *joint, cpFloat dt)
57
58
  {
58
- CONSTRAINT_BEGIN(joint, a, b);
59
+ cpBody *a = joint->constraint.a;
60
+ cpBody *b = joint->constraint.b;
59
61
  cpVect n = joint->n;
60
62
 
61
63
  // compute relative velocity
62
64
  cpFloat vrn = normal_relative_velocity(a, b, joint->r1, joint->r2, n);
63
65
 
66
+ cpFloat jnMax = joint->constraint.maxForce*dt;
67
+
64
68
  // compute normal impulse
65
69
  cpFloat jn = (joint->bias - vrn)*joint->nMass;
66
70
  cpFloat jnOld = joint->jnAcc;
67
- joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, joint->jnMax);
71
+ joint->jnAcc = cpfclamp(jnOld + jn, -jnMax, jnMax);
68
72
  jn = joint->jnAcc - jnOld;
69
73
 
70
74
  // apply impulse
@@ -78,17 +82,18 @@ getImpulse(cpPinJoint *joint)
78
82
  }
79
83
 
80
84
  static const cpConstraintClass klass = {
81
- (cpConstraintPreStepFunction)preStep,
82
- (cpConstraintApplyImpulseFunction)applyImpulse,
83
- (cpConstraintGetImpulseFunction)getImpulse,
85
+ (cpConstraintPreStepImpl)preStep,
86
+ (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
87
+ (cpConstraintApplyImpulseImpl)applyImpulse,
88
+ (cpConstraintGetImpulseImpl)getImpulse,
84
89
  };
85
- CP_DefineClassGetter(cpPinJoint);
90
+ CP_DefineClassGetter(cpPinJoint)
86
91
 
87
92
 
88
93
  cpPinJoint *
89
94
  cpPinJointAlloc(void)
90
95
  {
91
- return (cpPinJoint *)cpmalloc(sizeof(cpPinJoint));
96
+ return (cpPinJoint *)cpcalloc(1, sizeof(cpPinJoint));
92
97
  }
93
98
 
94
99
  cpPinJoint *
@@ -103,6 +108,8 @@ cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect an
103
108
  cpVect p1 = (a ? cpvadd(a->p, cpvrotate(anchr1, a->rot)) : anchr1);
104
109
  cpVect p2 = (b ? cpvadd(b->p, cpvrotate(anchr2, b->rot)) : anchr2);
105
110
  joint->dist = cpvlength(cpvsub(p2, p1));
111
+
112
+ cpAssertWarn(joint->dist > 0.0, "You created a 0 length pin joint. A pivot joint will be much more stable.");
106
113
 
107
114
  joint->jnAcc = 0.0f;
108
115
 
@@ -19,37 +19,40 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include <stdlib.h>
23
-
24
22
  #include "chipmunk_private.h"
25
23
  #include "constraints/util.h"
26
24
 
27
25
  static void
28
- preStep(cpPivotJoint *joint, cpFloat dt, cpFloat dt_inv)
26
+ preStep(cpPivotJoint *joint, cpFloat dt)
29
27
  {
30
- CONSTRAINT_BEGIN(joint, a, b);
28
+ cpBody *a = joint->constraint.a;
29
+ cpBody *b = joint->constraint.b;
31
30
 
32
31
  joint->r1 = cpvrotate(joint->anchr1, a->rot);
33
32
  joint->r2 = cpvrotate(joint->anchr2, b->rot);
34
33
 
35
34
  // Calculate mass tensor
36
- k_tensor(a, b, joint->r1, joint->r2, &joint->k1, &joint->k2);
37
-
38
- // compute max impulse
39
- joint->jMaxLen = J_MAX(joint, dt);
35
+ joint-> k = k_tensor(a, b, joint->r1, joint->r2);
40
36
 
41
37
  // calculate bias velocity
42
38
  cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));
43
- joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.biasCoef*dt_inv), joint->constraint.maxBias);
39
+ joint->bias = cpvclamp(cpvmult(delta, -bias_coef(joint->constraint.errorBias, dt)/dt), joint->constraint.maxBias);
40
+ }
41
+
42
+ static void
43
+ applyCachedImpulse(cpPivotJoint *joint, cpFloat dt_coef)
44
+ {
45
+ cpBody *a = joint->constraint.a;
46
+ cpBody *b = joint->constraint.b;
44
47
 
45
- // apply accumulated impulse
46
- apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);
48
+ apply_impulses(a, b, joint->r1, joint->r2, cpvmult(joint->jAcc, dt_coef));
47
49
  }
48
50
 
49
51
  static void
50
- applyImpulse(cpPivotJoint *joint)
52
+ applyImpulse(cpPivotJoint *joint, cpFloat dt)
51
53
  {
52
- CONSTRAINT_BEGIN(joint, a, b);
54
+ cpBody *a = joint->constraint.a;
55
+ cpBody *b = joint->constraint.b;
53
56
 
54
57
  cpVect r1 = joint->r1;
55
58
  cpVect r2 = joint->r2;
@@ -58,9 +61,9 @@ applyImpulse(cpPivotJoint *joint)
58
61
  cpVect vr = relative_velocity(a, b, r1, r2);
59
62
 
60
63
  // compute normal impulse
61
- cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);
64
+ cpVect j = cpMat2x2Transform(joint->k, cpvsub(joint->bias, vr));
62
65
  cpVect jOld = joint->jAcc;
63
- joint->jAcc = cpvclamp(cpvadd(joint->jAcc, j), joint->jMaxLen);
66
+ joint->jAcc = cpvclamp(cpvadd(joint->jAcc, j), joint->constraint.maxForce*dt);
64
67
  j = cpvsub(joint->jAcc, jOld);
65
68
 
66
69
  // apply impulse
@@ -74,16 +77,17 @@ getImpulse(cpConstraint *joint)
74
77
  }
75
78
 
76
79
  static const cpConstraintClass klass = {
77
- (cpConstraintPreStepFunction)preStep,
78
- (cpConstraintApplyImpulseFunction)applyImpulse,
79
- (cpConstraintGetImpulseFunction)getImpulse,
80
+ (cpConstraintPreStepImpl)preStep,
81
+ (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
82
+ (cpConstraintApplyImpulseImpl)applyImpulse,
83
+ (cpConstraintGetImpulseImpl)getImpulse,
80
84
  };
81
85
  CP_DefineClassGetter(cpPivotJoint)
82
86
 
83
87
  cpPivotJoint *
84
88
  cpPivotJointAlloc(void)
85
89
  {
86
- return (cpPivotJoint *)cpmalloc(sizeof(cpPivotJoint));
90
+ return (cpPivotJoint *)cpcalloc(1, sizeof(cpPivotJoint));
87
91
  }
88
92
 
89
93
  cpPivotJoint *
@@ -19,8 +19,6 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include <stdlib.h>
23
-
24
22
  #include "chipmunk_private.h"
25
23
  #include "chipmunk_unsafe.h"
26
24
 
@@ -30,21 +28,33 @@ cpPolyShapeAlloc(void)
30
28
  return (cpPolyShape *)cpcalloc(1, sizeof(cpPolyShape));
31
29
  }
32
30
 
33
- static void
31
+ static cpBB
34
32
  cpPolyShapeTransformVerts(cpPolyShape *poly, cpVect p, cpVect rot)
35
33
  {
36
34
  cpVect *src = poly->verts;
37
35
  cpVect *dst = poly->tVerts;
38
36
 
39
- for(int i=0; i<poly->numVerts; i++)
40
- dst[i] = cpvadd(p, cpvrotate(src[i], rot));
37
+ cpFloat l = (cpFloat)INFINITY, r = -(cpFloat)INFINITY;
38
+ cpFloat b = (cpFloat)INFINITY, t = -(cpFloat)INFINITY;
39
+
40
+ for(int i=0; i<poly->numVerts; i++){
41
+ cpVect v = cpvadd(p, cpvrotate(src[i], rot));
42
+
43
+ dst[i] = v;
44
+ l = cpfmin(l, v.x);
45
+ r = cpfmax(r, v.x);
46
+ b = cpfmin(b, v.y);
47
+ t = cpfmax(t, v.y);
48
+ }
49
+
50
+ return cpBBNew(l, b, r, t);
41
51
  }
42
52
 
43
53
  static void
44
54
  cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)
45
55
  {
46
- cpPolyShapeAxis *src = poly->axes;
47
- cpPolyShapeAxis *dst = poly->tAxes;
56
+ cpSplittingPlane *src = poly->planes;
57
+ cpSplittingPlane *dst = poly->tPlanes;
48
58
 
49
59
  for(int i=0; i<poly->numVerts; i++){
50
60
  cpVect n = cpvrotate(src[i].n, rot);
@@ -54,55 +64,56 @@ cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)
54
64
  }
55
65
 
56
66
  static cpBB
57
- cpPolyShapeCacheData(cpShape *shape, cpVect p, cpVect rot)
67
+ cpPolyShapeCacheData(cpPolyShape *poly, cpVect p, cpVect rot)
58
68
  {
59
- cpPolyShape *poly = (cpPolyShape *)shape;
60
-
61
- cpFloat l, b, r, t;
62
-
63
69
  cpPolyShapeTransformAxes(poly, p, rot);
64
- cpPolyShapeTransformVerts(poly, p, rot);
65
-
66
- cpVect *verts = poly->tVerts;
67
- l = r = verts[0].x;
68
- b = t = verts[0].y;
70
+ cpBB bb = poly->shape.bb = cpPolyShapeTransformVerts(poly, p, rot);
69
71
 
70
- // TODO do as part of cpPolyShapeTransformVerts?
71
- for(int i=1; i<poly->numVerts; i++){
72
- cpVect v = verts[i];
73
-
74
- l = cpfmin(l, v.x);
75
- r = cpfmax(r, v.x);
76
-
77
- b = cpfmin(b, v.y);
78
- t = cpfmax(t, v.y);
79
- }
80
-
81
- return cpBBNew(l, b, r, t);
72
+ return bb;
82
73
  }
83
74
 
84
75
  static void
85
- cpPolyShapeDestroy(cpShape *shape)
76
+ cpPolyShapeDestroy(cpPolyShape *poly)
86
77
  {
87
- cpPolyShape *poly = (cpPolyShape *)shape;
88
-
89
78
  cpfree(poly->verts);
90
- cpfree(poly->tVerts);
91
-
92
- cpfree(poly->axes);
93
- cpfree(poly->tAxes);
79
+ cpfree(poly->planes);
94
80
  }
95
81
 
96
- static cpBool
97
- cpPolyShapePointQuery(cpShape *shape, cpVect p){
98
- return cpBBcontainsVect(shape->bb, p) && cpPolyShapeContainsVert((cpPolyShape *)shape, p);
82
+ static void
83
+ cpPolyShapeNearestPointQuery(cpPolyShape *poly, cpVect p, cpNearestPointQueryInfo *info){
84
+ int count = poly->numVerts;
85
+ cpSplittingPlane *planes = poly->tPlanes;
86
+ cpVect *verts = poly->tVerts;
87
+
88
+ cpVect v0 = verts[count - 1];
89
+ cpFloat minDist = INFINITY;
90
+ cpVect closestPoint = cpvzero;
91
+ cpBool outside = cpFalse;
92
+
93
+ for(int i=0; i<count; i++){
94
+ if(cpSplittingPlaneCompare(planes[i], p) > 0.0f) outside = cpTrue;
95
+
96
+ cpVect v1 = verts[i];
97
+ cpVect closest = cpClosetPointOnSegment(p, v0, v1);
98
+
99
+ cpFloat dist = cpvdist(p, closest);
100
+ if(dist < minDist){
101
+ minDist = dist;
102
+ closestPoint = closest;
103
+ }
104
+
105
+ v0 = v1;
106
+ }
107
+
108
+ info->shape = (cpShape *)poly;
109
+ info->p = closestPoint; // TODO div/0
110
+ info->d = (outside ? minDist : -minDist);
99
111
  }
100
112
 
101
113
  static void
102
- cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)
114
+ cpPolyShapeSegmentQuery(cpPolyShape *poly, cpVect a, cpVect b, cpSegmentQueryInfo *info)
103
115
  {
104
- cpPolyShape *poly = (cpPolyShape *)shape;
105
- cpPolyShapeAxis *axes = poly->tAxes;
116
+ cpSplittingPlane *axes = poly->tPlanes;
106
117
  cpVect *verts = poly->tVerts;
107
118
  int numVerts = poly->numVerts;
108
119
 
@@ -121,7 +132,7 @@ cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *
121
132
  cpFloat dtMax = -cpvcross(n, verts[(i+1)%numVerts]);
122
133
 
123
134
  if(dtMin <= dt && dt <= dtMax){
124
- info->shape = shape;
135
+ info->shape = (cpShape *)poly;
125
136
  info->t = t;
126
137
  info->n = n;
127
138
  }
@@ -130,10 +141,10 @@ cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *
130
141
 
131
142
  static const cpShapeClass polyClass = {
132
143
  CP_POLY_SHAPE,
133
- cpPolyShapeCacheData,
134
- cpPolyShapeDestroy,
135
- cpPolyShapePointQuery,
136
- cpPolyShapeSegmentQuery,
144
+ (cpShapeCacheDataImpl)cpPolyShapeCacheData,
145
+ (cpShapeDestroyImpl)cpPolyShapeDestroy,
146
+ (cpShapeNearestPointQueryImpl)cpPolyShapeNearestPointQuery,
147
+ (cpShapeSegmentQueryImpl)cpPolyShapeSegmentQuery,
137
148
  };
138
149
 
139
150
  cpBool
@@ -144,8 +155,9 @@ cpPolyValidate(const cpVect *verts, const int numVerts)
144
155
  cpVect b = verts[(i+1)%numVerts];
145
156
  cpVect c = verts[(i+2)%numVerts];
146
157
 
147
- if(cpvcross(cpvsub(b, a), cpvsub(c, b)) > 0.0f)
158
+ if(cpvcross(cpvsub(b, a), cpvsub(c, a)) > 0.0f){
148
159
  return cpFalse;
160
+ }
149
161
  }
150
162
 
151
163
  return cpTrue;
@@ -154,29 +166,31 @@ cpPolyValidate(const cpVect *verts, const int numVerts)
154
166
  int
155
167
  cpPolyShapeGetNumVerts(cpShape *shape)
156
168
  {
157
- cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
169
+ cpAssertHard(shape->klass == &polyClass, "Shape is not a poly shape.");
158
170
  return ((cpPolyShape *)shape)->numVerts;
159
171
  }
160
172
 
161
173
  cpVect
162
174
  cpPolyShapeGetVert(cpShape *shape, int idx)
163
175
  {
164
- cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
165
- cpAssert(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");
176
+ cpAssertHard(shape->klass == &polyClass, "Shape is not a poly shape.");
177
+ cpAssertHard(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");
166
178
 
167
179
  return ((cpPolyShape *)shape)->verts[idx];
168
180
  }
169
181
 
170
182
 
171
183
  static void
172
- setUpVerts(cpPolyShape *poly, int numVerts, cpVect *verts, cpVect offset)
184
+ setUpVerts(cpPolyShape *poly, int numVerts, const cpVect *verts, cpVect offset)
173
185
  {
186
+ // Fail if the user attempts to pass a concave poly, or a bad winding.
187
+ cpAssertHard(cpPolyValidate(verts, numVerts), "Polygon is concave or has a reversed winding. Consider using cpConvexHull() or CP_CONVEX_HULL().");
188
+
174
189
  poly->numVerts = numVerts;
175
-
176
- poly->verts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
177
- poly->tVerts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
178
- poly->axes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));
179
- poly->tAxes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));
190
+ poly->verts = (cpVect *)cpcalloc(2*numVerts, sizeof(cpVect));
191
+ poly->planes = (cpSplittingPlane *)cpcalloc(2*numVerts, sizeof(cpSplittingPlane));
192
+ poly->tVerts = poly->verts + numVerts;
193
+ poly->tPlanes = poly->planes + numVerts;
180
194
 
181
195
  for(int i=0; i<numVerts; i++){
182
196
  cpVect a = cpvadd(offset, verts[i]);
@@ -184,17 +198,15 @@ setUpVerts(cpPolyShape *poly, int numVerts, cpVect *verts, cpVect offset)
184
198
  cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
185
199
 
186
200
  poly->verts[i] = a;
187
- poly->axes[i].n = n;
188
- poly->axes[i].d = cpvdot(n, a);
201
+ poly->planes[i].n = n;
202
+ poly->planes[i].d = cpvdot(n, a);
189
203
  }
204
+
190
205
  }
191
206
 
192
207
  cpPolyShape *
193
- cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)
208
+ cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset)
194
209
  {
195
- // Fail if the user attempts to pass a concave poly, or a bad winding.
196
- cpAssert(cpPolyValidate(verts, numVerts), "Polygon is concave or has a reversed winding.");
197
-
198
210
  setUpVerts(poly, numVerts, verts, offset);
199
211
  cpShapeInit((cpShape *)poly, &polyClass, body);
200
212
 
@@ -213,11 +225,17 @@ cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height)
213
225
  cpFloat hw = width/2.0f;
214
226
  cpFloat hh = height/2.0f;
215
227
 
228
+ return cpBoxShapeInit2(poly, body, cpBBNew(-hw, -hh, hw, hh));
229
+ }
230
+
231
+ cpPolyShape *
232
+ cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box)
233
+ {
216
234
  cpVect verts[] = {
217
- cpv(-hw,-hh),
218
- cpv(-hw, hh),
219
- cpv( hw, hh),
220
- cpv( hw,-hh),
235
+ cpv(box.l, box.b),
236
+ cpv(box.l, box.t),
237
+ cpv(box.r, box.t),
238
+ cpv(box.r, box.b),
221
239
  };
222
240
 
223
241
  return cpPolyShapeInit(poly, body, 4, verts, cpvzero);
@@ -229,12 +247,18 @@ cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height)
229
247
  return (cpShape *)cpBoxShapeInit(cpPolyShapeAlloc(), body, width, height);
230
248
  }
231
249
 
250
+ cpShape *
251
+ cpBoxShapeNew2(cpBody *body, cpBB box)
252
+ {
253
+ return (cpShape *)cpBoxShapeInit2(cpPolyShapeAlloc(), body, box);
254
+ }
255
+
232
256
  // Unsafe API (chipmunk_unsafe.h)
233
257
 
234
258
  void
235
259
  cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset)
236
260
  {
237
- cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
238
- cpPolyShapeDestroy(shape);
261
+ cpAssertHard(shape->klass == &polyClass, "Shape is not a poly shape.");
262
+ cpPolyShapeDestroy((cpPolyShape *)shape);
239
263
  setUpVerts((cpPolyShape *)shape, numVerts, verts, offset);
240
264
  }