chipmunk 4.1.0 → 5.2.0

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