chipmunk 4.1.0 → 5.2.0

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 (71) hide show
  1. data/LICENSE +20 -0
  2. data/README +60 -0
  3. data/Rakefile +47 -40
  4. data/ext/chipmunk/chipmunk.c +39 -3
  5. data/ext/chipmunk/cpArbiter.c +91 -80
  6. data/ext/chipmunk/cpArray.c +24 -10
  7. data/ext/chipmunk/cpBB.c +5 -4
  8. data/ext/chipmunk/cpBody.c +30 -22
  9. data/ext/chipmunk/cpCollision.c +54 -53
  10. data/ext/chipmunk/cpConstraint.c +54 -0
  11. data/ext/chipmunk/cpDampedRotarySpring.c +106 -0
  12. data/ext/chipmunk/cpDampedSpring.c +117 -0
  13. data/ext/chipmunk/cpGearJoint.c +114 -0
  14. data/ext/chipmunk/cpGrooveJoint.c +138 -0
  15. data/ext/chipmunk/cpHashSet.c +74 -40
  16. data/ext/chipmunk/cpPinJoint.c +117 -0
  17. data/ext/chipmunk/cpPivotJoint.c +114 -0
  18. data/ext/chipmunk/cpPolyShape.c +117 -15
  19. data/ext/chipmunk/cpRatchetJoint.c +128 -0
  20. data/ext/chipmunk/cpRotaryLimitJoint.c +122 -0
  21. data/ext/chipmunk/cpShape.c +174 -18
  22. data/ext/chipmunk/cpSimpleMotor.c +99 -0
  23. data/ext/chipmunk/cpSlideJoint.c +131 -0
  24. data/ext/chipmunk/cpSpace.c +584 -215
  25. data/ext/chipmunk/cpSpaceHash.c +191 -105
  26. data/ext/chipmunk/cpVect.c +18 -10
  27. data/ext/chipmunk/extconf.rb +34 -4
  28. data/ext/chipmunk/{chipmunk.h → include/chipmunk/chipmunk.h} +63 -6
  29. data/ext/chipmunk/include/chipmunk/chipmunk_ffi.h +42 -0
  30. data/ext/chipmunk/include/chipmunk/chipmunk_types.h +80 -0
  31. data/ext/chipmunk/include/chipmunk/chipmunk_unsafe.h +54 -0
  32. data/ext/chipmunk/include/chipmunk/constraints/cpConstraint.h +92 -0
  33. data/ext/chipmunk/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
  34. data/ext/chipmunk/include/chipmunk/constraints/cpDampedSpring.h +53 -0
  35. data/ext/chipmunk/include/chipmunk/constraints/cpGearJoint.h +41 -0
  36. data/ext/chipmunk/include/chipmunk/constraints/cpGrooveJoint.h +44 -0
  37. data/ext/chipmunk/include/chipmunk/constraints/cpPinJoint.h +43 -0
  38. data/ext/chipmunk/include/chipmunk/constraints/cpPivotJoint.h +42 -0
  39. data/ext/chipmunk/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
  40. data/ext/chipmunk/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
  41. data/ext/chipmunk/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
  42. data/ext/chipmunk/include/chipmunk/constraints/cpSlideJoint.h +44 -0
  43. data/ext/chipmunk/include/chipmunk/constraints/util.h +116 -0
  44. data/ext/chipmunk/{cpArbiter.h → include/chipmunk/cpArbiter.h} +66 -15
  45. data/ext/chipmunk/{cpArray.h → include/chipmunk/cpArray.h} +2 -1
  46. data/ext/chipmunk/{cpBB.h → include/chipmunk/cpBB.h} +21 -0
  47. data/ext/chipmunk/{cpBody.h → include/chipmunk/cpBody.h} +37 -9
  48. data/ext/chipmunk/{cpCollision.h → include/chipmunk/cpCollision.h} +1 -1
  49. data/ext/chipmunk/{cpHashSet.h → include/chipmunk/cpHashSet.h} +12 -9
  50. data/ext/chipmunk/{cpPolyShape.h → include/chipmunk/cpPolyShape.h} +13 -2
  51. data/ext/chipmunk/{cpShape.h → include/chipmunk/cpShape.h} +51 -18
  52. data/ext/chipmunk/include/chipmunk/cpSpace.h +180 -0
  53. data/ext/chipmunk/{cpSpaceHash.h → include/chipmunk/cpSpaceHash.h} +18 -9
  54. data/ext/chipmunk/{cpVect.h → include/chipmunk/cpVect.h} +61 -10
  55. data/ext/chipmunk/prime.h +32 -32
  56. data/ext/chipmunk/rb_chipmunk.c +125 -109
  57. data/ext/chipmunk/rb_chipmunk.h +96 -77
  58. data/ext/chipmunk/rb_cpArbiter.c +225 -0
  59. data/ext/chipmunk/rb_cpBB.c +174 -154
  60. data/ext/chipmunk/rb_cpBody.c +347 -239
  61. data/ext/chipmunk/rb_cpConstraint.c +346 -0
  62. data/ext/chipmunk/rb_cpShape.c +455 -292
  63. data/ext/chipmunk/rb_cpSpace.c +544 -330
  64. data/ext/chipmunk/rb_cpVect.c +321 -250
  65. data/lib/chipmunk.rb +28 -15
  66. data/lib/chipmunk/version.rb +3 -0
  67. metadata +74 -34
  68. data/ext/chipmunk/cpJoint.c +0 -553
  69. data/ext/chipmunk/cpJoint.h +0 -122
  70. data/ext/chipmunk/cpSpace.h +0 -120
  71. data/ext/chipmunk/rb_cpJoint.c +0 -136
@@ -18,6 +18,10 @@
18
18
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
19
  * SOFTWARE.
20
20
  */
21
+
22
+ struct cpArbiter;
23
+ struct cpSpace;
24
+ struct cpCollisionHandler;
21
25
 
22
26
  // Determines how fast penetrations resolve themselves.
23
27
  extern cpFloat cp_bias_coef;
@@ -25,7 +29,7 @@ extern cpFloat cp_bias_coef;
25
29
  extern cpFloat cp_collision_slop;
26
30
 
27
31
  // Data structure for contact points.
28
- typedef struct cpContact{
32
+ typedef struct cpContact {
29
33
  // Contact point and normal.
30
34
  cpVect p, n;
31
35
  // Penetration distance.
@@ -40,46 +44,93 @@ typedef struct cpContact{
40
44
  cpFloat bias;
41
45
 
42
46
  // Hash value used to (mostly) uniquely identify a contact.
43
- unsigned int hash;
47
+ cpHashValue hash;
44
48
  } cpContact;
45
49
 
46
50
  // Contacts are always allocated in groups.
47
- cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, unsigned int hash);
51
+ cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
48
52
 
49
53
  // Sum the contact impulses. (Can be used after cpSpaceStep() returns)
50
54
  cpVect cpContactsSumImpulses(cpContact *contacts, int numContacts);
51
55
  cpVect cpContactsSumImpulsesWithFriction(cpContact *contacts, int numContacts);
52
56
 
57
+ typedef enum cpArbiterState {
58
+ cpArbiterStateNormal,
59
+ cpArbiterStateFirstColl,
60
+ cpArbiterStateIgnore,
61
+ } cpArbiterState;
62
+
53
63
  // Data structure for tracking collisions between shapes.
54
- typedef struct cpArbiter{
64
+ typedef struct cpArbiter {
55
65
  // Information on the contact points between the objects.
56
66
  int numContacts;
57
67
  cpContact *contacts;
58
68
 
59
69
  // The two shapes involved in the collision.
60
- cpShape *a, *b;
70
+ // These variables are NOT in the order defined by the collision handler.
71
+ cpShape *private_a, *private_b;
61
72
 
62
- // Calculated by cpArbiterPreStep().
73
+ // Calculated before calling the pre-solve collision handler
74
+ // Override them with custom values if you want specialized behavior
75
+ cpFloat e;
63
76
  cpFloat u;
64
- cpVect target_v;
77
+ // Used for surface_v calculations, implementation may change
78
+ cpVect surface_vr;
65
79
 
66
80
  // Time stamp of the arbiter. (from cpSpace)
67
81
  int stamp;
82
+
83
+ struct cpCollisionHandler *handler;
84
+
85
+ // Are the shapes swapped in relation to the collision handler?
86
+ char swappedColl;
87
+ char state;
68
88
  } cpArbiter;
69
89
 
70
- // Basic allocation/destruction functions.
71
- cpArbiter* cpArbiterAlloc(void);
72
- cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b, int stamp);
73
- cpArbiter* cpArbiterNew(cpShape *a, cpShape *b, int stamp);
74
-
75
- void cpArbiterDestroy(cpArbiter *arb);
76
- void cpArbiterFree(cpArbiter *arb);
90
+ // Arbiters are allocated in large buffers by the space and don't require a destroy function
91
+ cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
77
92
 
78
93
  // These functions are all intended to be used internally.
79
94
  // Inject new contact points into the arbiter while preserving contact history.
80
- void cpArbiterInject(cpArbiter *arb, cpContact *contacts, int numContacts);
95
+ void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
81
96
  // Precalculate values used by the solver.
82
97
  void cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv);
83
98
  void cpArbiterApplyCachedImpulse(cpArbiter *arb);
84
99
  // Run an iteration of the solver on the arbiter.
85
100
  void cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef);
101
+
102
+ // Arbiter Helper Functions
103
+ cpVect cpArbiterTotalImpulse(cpArbiter *arb);
104
+ cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);
105
+ void cpArbiterIgnore(cpArbiter *arb);
106
+
107
+
108
+ static inline void
109
+ cpArbiterGetShapes(cpArbiter *arb, cpShape **a, cpShape **b)
110
+ {
111
+ if(arb->swappedColl){
112
+ (*a) = arb->private_b, (*b) = arb->private_a;
113
+ } else {
114
+ (*a) = arb->private_a, (*b) = arb->private_b;
115
+ }
116
+ }
117
+ #define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
118
+
119
+ static inline int
120
+ cpArbiterIsFirstContact(cpArbiter *arb)
121
+ {
122
+ return arb->state == cpArbiterStateFirstColl;
123
+ }
124
+
125
+ static inline cpVect
126
+ cpArbiterGetNormal(cpArbiter *arb, int i)
127
+ {
128
+ cpVect n = arb->contacts[i].n;
129
+ return arb->swappedColl ? cpvneg(n) : n;
130
+ }
131
+
132
+ static inline cpVect
133
+ cpArbiterGetPoint(cpArbiter *arb, int i)
134
+ {
135
+ return arb->contacts[i].p;
136
+ }
@@ -38,7 +38,8 @@ void cpArrayFree(cpArray *arr);
38
38
  void cpArrayClear(cpArray *arr);
39
39
 
40
40
  void cpArrayPush(cpArray *arr, void *object);
41
- void cpArrayDeleteIndex(cpArray *arr, int index);
41
+ void *cpArrayPop(cpArray *arr);
42
+ void cpArrayDeleteIndex(cpArray *arr, int idx);
42
43
  void cpArrayDeleteObj(cpArray *arr, void *obj);
43
44
 
44
45
  void cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data);
@@ -49,5 +49,26 @@ cpBBcontainsVect(const cpBB bb, const cpVect v)
49
49
  return (bb.l < v.x && bb.r > v.x && bb.b < v.y && bb.t > v.y);
50
50
  }
51
51
 
52
+ static inline cpBB
53
+ cpBBmerge(const cpBB a, const cpBB b){
54
+ return cpBBNew(
55
+ cpfmin(a.l, b.l),
56
+ cpfmin(a.b, b.b),
57
+ cpfmax(a.r, b.r),
58
+ cpfmax(a.t, b.t)
59
+ );
60
+ }
61
+
62
+ static inline cpBB
63
+ cpBBexpand(const cpBB bb, const cpVect v){
64
+ return cpBBNew(
65
+ cpfmin(bb.l, v.x),
66
+ cpfmin(bb.b, v.y),
67
+ cpfmax(bb.r, v.x),
68
+ cpfmax(bb.t, v.y)
69
+ );
70
+ }
71
+
52
72
  cpVect cpBBClampVect(const cpBB bb, const cpVect v); // clamps the vector to lie within the bbox
73
+ // TODO edge case issue
53
74
  cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
@@ -23,9 +23,11 @@ struct cpBody;
23
23
  typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
24
24
  typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);
25
25
 
26
+ extern cpBodyVelocityFunc cpBodyUpdateVelocityDefault;
27
+ extern cpBodyPositionFunc cpBodyUpdatePositionDefault;
26
28
 
27
29
  typedef struct cpBody{
28
- // *** Integration Functions.
30
+ // *** Integration Functions.ntoehu
29
31
 
30
32
  // Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
31
33
  cpBodyVelocityFunc velocity_func;
@@ -40,7 +42,7 @@ typedef struct cpBody{
40
42
  cpFloat m, m_inv;
41
43
 
42
44
  // Moment of inertia and it's inverse.
43
- // Always use cpBodySetMass() whenever changing the mass as these values must agree.
45
+ // Always use cpBodySetMoment() whenever changing the moment as these values must agree.
44
46
  cpFloat i, i_inv;
45
47
 
46
48
  // *** Positional Properties
@@ -59,11 +61,14 @@ typedef struct cpBody{
59
61
  // *** User Definable Fields
60
62
 
61
63
  // User defined data pointer.
62
- void *data;
64
+ cpDataPointer data;
65
+
66
+ // Maximum velocities this body can move at after integrating velocity
67
+ cpFloat v_limit, w_limit;
63
68
 
64
69
  // *** Internally Used Fields
65
70
 
66
- // Velocity bias values used when solving penetrations and correcting joints.
71
+ // Velocity bias values used when solving penetrations and correcting constraints.
67
72
  cpVect v_bias;
68
73
  cpFloat w_bias;
69
74
 
@@ -78,10 +83,32 @@ cpBody *cpBodyNew(cpFloat m, cpFloat i);
78
83
  void cpBodyDestroy(cpBody *body);
79
84
  void cpBodyFree(cpBody *body);
80
85
 
81
- // Setters for some of the special properties (mandatory!)
86
+ #define CP_DefineBodyGetter(type, member, name) static inline type cpBodyGet##name(cpBody *body){return body->member;}
87
+ #define CP_DefineBodySetter(type, member, name) static inline void cpBodySet##name(cpBody *body, type value){body->member = value;}
88
+
89
+ #define CP_DefineBodyProperty(type, member, name) \
90
+ CP_DefineBodyGetter(type, member, name) \
91
+ CP_DefineBodySetter(type, member, name)
92
+
93
+
94
+ // Accessors for cpBody struct members
95
+ CP_DefineBodyGetter(cpFloat, m, Mass);
82
96
  void cpBodySetMass(cpBody *body, cpFloat m);
97
+
98
+ CP_DefineBodyGetter(cpFloat, i, Moment);
83
99
  void cpBodySetMoment(cpBody *body, cpFloat i);
100
+
101
+
102
+ CP_DefineBodyProperty(cpVect, p, Pos);
103
+ CP_DefineBodyProperty(cpVect, v, Vel);
104
+ CP_DefineBodyProperty(cpVect, f, Force);
105
+ CP_DefineBodyGetter(cpFloat, a, Angle);
84
106
  void cpBodySetAngle(cpBody *body, cpFloat a);
107
+ CP_DefineBodyProperty(cpFloat, w, AngVel);
108
+ CP_DefineBodyProperty(cpFloat, t, Torque);
109
+ CP_DefineBodyGetter(cpVect, rot, Rot);
110
+ CP_DefineBodyProperty(cpFloat, v_limit, VelLimit);
111
+ CP_DefineBodyProperty(cpFloat, w_limit, AngVelLimit);
85
112
 
86
113
  // Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.
87
114
  // Intended for objects that are moved manually with a custom velocity integration function.
@@ -105,7 +132,7 @@ cpBodyWorld2Local(cpBody *body, cpVect v)
105
132
  return cpvunrotate(cpvsub(v, body->p), body->rot);
106
133
  }
107
134
 
108
- // Apply an impulse (in world coordinates) to the body.
135
+ // Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
109
136
  static inline void
110
137
  cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)
111
138
  {
@@ -113,7 +140,7 @@ cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)
113
140
  body->w += body->i_inv*cpvcross(r, j);
114
141
  }
115
142
 
116
- // Not intended for external use. Used by cpArbiter.c and cpJoint.c.
143
+ // Not intended for external use. Used by cpArbiter.c and cpConstraint.c.
117
144
  static inline void
118
145
  cpBodyApplyBiasImpulse(cpBody *body, cpVect j, cpVect r)
119
146
  {
@@ -123,10 +150,11 @@ cpBodyApplyBiasImpulse(cpBody *body, cpVect j, cpVect r)
123
150
 
124
151
  // Zero the forces on a body.
125
152
  void cpBodyResetForces(cpBody *body);
126
- // Apply a force (in world coordinates) to a body.
153
+ // Apply a force (in world coordinates) to a body at a point relative to the center of gravity (also in world coordinates).
127
154
  void cpBodyApplyForce(cpBody *body, cpVect f, cpVect r);
128
155
 
129
156
  // Apply a damped spring force between two bodies.
130
- void cpDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);
157
+ // Warning: Large damping values can be unstable. Use a cpDampedSpring constraint for this instead.
158
+ void cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);
131
159
 
132
160
  //int cpBodyMarkLowEnergy(cpBody *body, cpFloat dvsq, int max);
@@ -20,4 +20,4 @@
20
20
  */
21
21
 
22
22
  // Collides two cpShape structures. (this function is lonely :( )
23
- int cpCollideShapes(cpShape *a, cpShape *b, cpContact **arr);
23
+ int cpCollideShapes(cpShape *a, cpShape *b, cpContact *arr);
@@ -27,7 +27,7 @@ typedef struct cpHashSetBin {
27
27
  // Pointer to the element.
28
28
  void *elt;
29
29
  // Hash value of the element.
30
- unsigned int hash;
30
+ cpHashValue hash;
31
31
  // Next element in the chain.
32
32
  struct cpHashSetBin *next;
33
33
  } cpHashSetBin;
@@ -38,8 +38,8 @@ typedef int (*cpHashSetEqlFunc)(void *ptr, void *elt);
38
38
  typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
39
39
  // Iterator function for a hashset.
40
40
  typedef void (*cpHashSetIterFunc)(void *elt, void *data);
41
- // Reject function. Returns true if elt should be dropped.
42
- typedef int (*cpHashSetRejectFunc)(void *elt, void *data);
41
+ // Filter function. Returns false if elt should be dropped.
42
+ typedef int (*cpHashSetFilterFunc)(void *elt, void *data);
43
43
 
44
44
  typedef struct cpHashSet {
45
45
  // Number of elements stored in the table.
@@ -54,7 +54,10 @@ typedef struct cpHashSet {
54
54
  // Defaults to NULL.
55
55
  void *default_value;
56
56
 
57
- cpHashSetBin **table;
57
+ // The table and recycled bins
58
+ cpHashSetBin **table, *pooledBins;
59
+
60
+ cpArray *allocatedBuffers;
58
61
  } cpHashSet;
59
62
 
60
63
  // Basic allocation/destruction functions.
@@ -67,13 +70,13 @@ cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc t
67
70
 
68
71
  // Insert an element into the set, returns the element.
69
72
  // If it doesn't already exist, the transformation function is applied.
70
- void *cpHashSetInsert(cpHashSet *set, unsigned int hash, void *ptr, void *data);
73
+ void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data);
71
74
  // Remove and return an element from the set.
72
- void *cpHashSetRemove(cpHashSet *set, unsigned int hash, void *ptr);
75
+ void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
73
76
  // Find an element in the set. Returns the default value if the element isn't found.
74
- void *cpHashSetFind(cpHashSet *set, unsigned int hash, void *ptr);
77
+ void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
75
78
 
76
79
  // Iterate over a hashset.
77
80
  void cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data);
78
- // Iterate over a hashset while rejecting certain elements.
79
- void cpHashSetReject(cpHashSet *set, cpHashSetRejectFunc func, void *data);
81
+ // Iterate over a hashset, retain .
82
+ void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
@@ -46,6 +46,17 @@ cpPolyShape *cpPolyShapeAlloc(void);
46
46
  cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset);
47
47
  cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset);
48
48
 
49
+ cpPolyShape *cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);
50
+ cpShape *cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);
51
+
52
+ // Check that a set of vertexes has a correct winding and that they are convex
53
+ int cpPolyValidate(cpVect *verts, int numVerts);
54
+
55
+ int cpPolyShapeGetNumVerts(cpShape *shape);
56
+ cpVect cpPolyShapeGetVert(cpShape *shape, int idx);
57
+
58
+ // *** inlined utility functions
59
+
49
60
  // Returns the minimum distance of the polygon to the axis.
50
61
  static inline cpFloat
51
62
  cpPolyShapeValueOnAxis(const cpPolyShape *poly, const cpVect n, const cpFloat d)
@@ -69,7 +80,7 @@ cpPolyShapeContainsVert(cpPolyShape *poly, cpVect v)
69
80
  int i;
70
81
  for(i=0; i<poly->numVerts; i++){
71
82
  cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
72
- if(dist > 0.0) return 0;
83
+ if(dist > 0.0f) return 0;
73
84
  }
74
85
 
75
86
  return 1;
@@ -85,7 +96,7 @@ cpPolyShapeContainsVertPartial(cpPolyShape *poly, cpVect v, cpVect n)
85
96
  for(i=0; i<poly->numVerts; i++){
86
97
  if(cpvdot(axes[i].n, n) < 0.0f) continue;
87
98
  cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
88
- if(dist > 0.0) return 0;
99
+ if(dist > 0.0f) return 0;
89
100
  }
90
101
 
91
102
  return 1;
@@ -18,9 +18,16 @@
18
18
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
19
  * SOFTWARE.
20
20
  */
21
+
22
+ // Forward declarations required for defining other structs.
23
+ struct cpShape;
24
+ struct cpShapeClass;
21
25
 
22
- // For determinism, you can reset the shape id counter.
23
- void cpResetShapeIdCounter(void);
26
+ typedef struct cpSegmentQueryInfo {
27
+ struct cpShape *shape; // shape that was hit, NULL if no collision
28
+ cpFloat t; // Distance along query segment, will always be in the range [0, 1].
29
+ cpVect n; // normal of hit surface
30
+ } cpSegmentQueryInfo;
24
31
 
25
32
  // Enumeration of shape types.
26
33
  typedef enum cpShapeType{
@@ -30,10 +37,6 @@ typedef enum cpShapeType{
30
37
  CP_NUM_SHAPES
31
38
  } cpShapeType;
32
39
 
33
- // Forward declarations required for defining the cpShape and cpShapeClass structs.
34
- struct cpShape;
35
- struct cpShapeClass;
36
-
37
40
  // Shape class. Holds function pointers and type data.
38
41
  typedef struct cpShapeClass {
39
42
  cpShapeType type;
@@ -43,8 +46,11 @@ typedef struct cpShapeClass {
43
46
  // Called to by cpShapeDestroy().
44
47
  void (*destroy)(struct cpShape *shape);
45
48
 
46
- // called by cpShapeQueryPointQuery().
49
+ // called by cpShapePointQuery().
47
50
  int (*pointQuery)(struct cpShape *shape, cpVect p);
51
+
52
+ // called by cpShapeSegmentQuery()
53
+ void (*segmentQuery)(struct cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
48
54
  } cpShapeClass;
49
55
 
50
56
  // Basic shape struct that the others inherit from.
@@ -58,6 +64,9 @@ typedef struct cpShape{
58
64
  // Cached BBox for the shape.
59
65
  cpBB bb;
60
66
 
67
+ // Sensors invoke callbacks, but do not generate collisions
68
+ int sensor;
69
+
61
70
  // *** Surface properties.
62
71
 
63
72
  // Coefficient of restitution. (elasticity)
@@ -70,19 +79,19 @@ typedef struct cpShape{
70
79
  // *** User Definable Fields
71
80
 
72
81
  // User defined data pointer for the shape.
73
- void *data;
82
+ cpDataPointer data;
74
83
 
75
84
  // User defined collision type for the shape.
76
- unsigned int collision_type;
85
+ cpCollisionType collision_type;
77
86
  // User defined collision group for the shape.
78
- unsigned int group;
87
+ cpGroup group;
79
88
  // User defined layer bitmask for the shape.
80
- unsigned int layers;
89
+ cpLayers layers;
81
90
 
82
91
  // *** Internally Used Fields
83
92
 
84
93
  // Unique id used as the hash value.
85
- unsigned int id;
94
+ cpHashValue hashid;
86
95
  } cpShape;
87
96
 
88
97
  // Low level shape initialization func.
@@ -98,17 +107,13 @@ cpBB cpShapeCacheBB(cpShape *shape);
98
107
  // Test if a point lies within a shape.
99
108
  int cpShapePointQuery(cpShape *shape, cpVect p);
100
109
 
101
- // Test if a segment collides with a shape.
102
- // Returns [0-1] if the segment collides and -1 otherwise.
103
- // 0 would be a collision at point a, 1 would be a collision at point b.
104
- //cpFloat cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b);
105
-
110
+ #define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(cpShape *shape)
106
111
 
107
112
  // Circle shape structure.
108
113
  typedef struct cpCircleShape{
109
114
  cpShape shape;
110
115
 
111
- // Center. (body space coordinates)
116
+ // Center in body space coordinates
112
117
  cpVect c;
113
118
  // Radius.
114
119
  cpFloat r;
@@ -122,6 +127,9 @@ cpCircleShape *cpCircleShapeAlloc(void);
122
127
  cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
123
128
  cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
124
129
 
130
+ CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
131
+ CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
132
+
125
133
  // Segment shape structure.
126
134
  typedef struct cpSegmentShape{
127
135
  cpShape shape;
@@ -139,3 +147,28 @@ typedef struct cpSegmentShape{
139
147
  cpSegmentShape* cpSegmentShapeAlloc(void);
140
148
  cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
141
149
  cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
150
+
151
+ CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
152
+ CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
153
+ CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
154
+ CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
155
+
156
+ // For determinism, you can reset the shape id counter.
157
+ void cpResetShapeIdCounter(void);
158
+
159
+ // Directed segment queries against individual shapes.
160
+ void cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info);
161
+
162
+ int cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
163
+
164
+ static inline cpVect
165
+ cpSegmentQueryHitPoint(cpVect start, cpVect end, cpSegmentQueryInfo info)
166
+ {
167
+ return cpvlerp(start, end, info.t);
168
+ }
169
+
170
+ static inline cpFloat
171
+ cpSegmentQueryHitDist(cpVect start, cpVect end, cpSegmentQueryInfo info)
172
+ {
173
+ return cpvdist(start, end)*info.t;
174
+ }