chipmunk 5.3.4.5 → 6.1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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
  }