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.
- data/ext/chipmunk/chipmunk.c +199 -28
- data/ext/chipmunk/chipmunk.h +123 -68
- data/ext/chipmunk/chipmunk_ffi.h +129 -11
- data/ext/chipmunk/chipmunk_private.h +232 -16
- data/ext/chipmunk/chipmunk_types.h +94 -30
- data/ext/chipmunk/chipmunk_unsafe.h +12 -3
- data/ext/chipmunk/constraints/cpConstraint.h +90 -34
- data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
- data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
- data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
- data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
- data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
- data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
- data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
- data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
- data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
- data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
- data/ext/chipmunk/constraints/util.h +36 -44
- data/ext/chipmunk/cpArbiter.c +159 -94
- data/ext/chipmunk/cpArbiter.h +135 -129
- data/ext/chipmunk/cpArray.c +37 -56
- data/ext/chipmunk/cpBB.c +1 -12
- data/ext/chipmunk/cpBB.h +80 -18
- data/ext/chipmunk/cpBBTree.c +891 -0
- data/ext/chipmunk/cpBody.c +185 -47
- data/ext/chipmunk/cpBody.h +156 -124
- data/ext/chipmunk/cpCollision.c +126 -115
- data/ext/chipmunk/cpConstraint.c +10 -6
- data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
- data/ext/chipmunk/cpDampedSpring.c +25 -18
- data/ext/chipmunk/cpGearJoint.c +23 -17
- data/ext/chipmunk/cpGrooveJoint.c +26 -22
- data/ext/chipmunk/cpHashSet.c +51 -51
- data/ext/chipmunk/cpPinJoint.c +26 -19
- data/ext/chipmunk/cpPivotJoint.c +23 -19
- data/ext/chipmunk/cpPolyShape.c +93 -69
- data/ext/chipmunk/cpPolyShape.h +33 -69
- data/ext/chipmunk/cpRatchetJoint.c +26 -21
- data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
- data/ext/chipmunk/cpShape.c +122 -133
- data/ext/chipmunk/cpShape.h +146 -95
- data/ext/chipmunk/cpSimpleMotor.c +24 -17
- data/ext/chipmunk/cpSlideJoint.c +28 -26
- data/ext/chipmunk/cpSpace.c +251 -196
- data/ext/chipmunk/cpSpace.h +173 -103
- data/ext/chipmunk/cpSpaceComponent.c +236 -159
- data/ext/chipmunk/cpSpaceHash.c +259 -159
- data/ext/chipmunk/cpSpaceQuery.c +127 -59
- data/ext/chipmunk/cpSpaceStep.c +235 -197
- data/ext/chipmunk/cpSpatialIndex.c +69 -0
- data/ext/chipmunk/cpSpatialIndex.h +227 -0
- data/ext/chipmunk/cpSweep1D.c +254 -0
- data/ext/chipmunk/cpVect.c +11 -26
- data/ext/chipmunk/cpVect.h +76 -71
- data/ext/chipmunk/extconf.rb +4 -31
- data/ext/chipmunk/prime.h +1 -1
- data/ext/chipmunk/rb_chipmunk.c +36 -45
- data/ext/chipmunk/rb_chipmunk.h +6 -3
- data/ext/chipmunk/rb_cpArbiter.c +2 -2
- data/ext/chipmunk/rb_cpBB.c +116 -35
- data/ext/chipmunk/rb_cpBody.c +5 -12
- data/ext/chipmunk/rb_cpConstraint.c +144 -9
- data/ext/chipmunk/rb_cpShape.c +69 -78
- data/ext/chipmunk/rb_cpSpace.c +81 -76
- metadata +61 -61
- data/LICENSE +0 -22
- data/README +0 -110
- data/Rakefile +0 -102
- data/ext/chipmunk/cpArray.h +0 -49
- data/ext/chipmunk/cpCollision.h +0 -28
- data/ext/chipmunk/cpHashSet.h +0 -82
- data/ext/chipmunk/cpSpaceHash.h +0 -110
- data/lib/chipmunk.rb +0 -194
@@ -19,8 +19,12 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
22
|
+
/// @defgroup cpRatchetJoint cpRatchetJoint
|
23
|
+
/// @{
|
23
24
|
|
25
|
+
const cpConstraintClass *cpRatchetJointGetClass(void);
|
26
|
+
|
27
|
+
/// @private
|
24
28
|
typedef struct cpRatchetJoint {
|
25
29
|
cpConstraint constraint;
|
26
30
|
cpFloat angle, phase, ratchet;
|
@@ -28,13 +32,18 @@ typedef struct cpRatchetJoint {
|
|
28
32
|
cpFloat iSum;
|
29
33
|
|
30
34
|
cpFloat bias;
|
31
|
-
cpFloat jAcc
|
35
|
+
cpFloat jAcc;
|
32
36
|
} cpRatchetJoint;
|
33
37
|
|
34
|
-
|
35
|
-
cpRatchetJoint
|
36
|
-
|
38
|
+
/// Allocate a ratchet joint.
|
39
|
+
cpRatchetJoint* cpRatchetJointAlloc(void);
|
40
|
+
/// Initialize a ratched joint.
|
41
|
+
cpRatchetJoint* cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
42
|
+
/// Allocate and initialize a ratchet joint.
|
43
|
+
cpConstraint* cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
44
|
+
|
45
|
+
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle)
|
46
|
+
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase)
|
47
|
+
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet)
|
37
48
|
|
38
|
-
|
39
|
-
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase);
|
40
|
-
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet);
|
49
|
+
/// @}
|
@@ -19,8 +19,12 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
22
|
+
/// @defgroup cpRotaryLimitJoint cpRotaryLimitJoint
|
23
|
+
/// @{
|
23
24
|
|
25
|
+
const cpConstraintClass *cpRotaryLimitJointGetClass(void);
|
26
|
+
|
27
|
+
/// @private
|
24
28
|
typedef struct cpRotaryLimitJoint {
|
25
29
|
cpConstraint constraint;
|
26
30
|
cpFloat min, max;
|
@@ -28,12 +32,17 @@ typedef struct cpRotaryLimitJoint {
|
|
28
32
|
cpFloat iSum;
|
29
33
|
|
30
34
|
cpFloat bias;
|
31
|
-
cpFloat jAcc
|
35
|
+
cpFloat jAcc;
|
32
36
|
} cpRotaryLimitJoint;
|
33
37
|
|
34
|
-
|
35
|
-
cpRotaryLimitJoint
|
36
|
-
|
38
|
+
/// Allocate a damped rotary limit joint.
|
39
|
+
cpRotaryLimitJoint* cpRotaryLimitJointAlloc(void);
|
40
|
+
/// Initialize a damped rotary limit joint.
|
41
|
+
cpRotaryLimitJoint* cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
42
|
+
/// Allocate and initialize a damped rotary limit joint.
|
43
|
+
cpConstraint* cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
44
|
+
|
45
|
+
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min)
|
46
|
+
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max)
|
37
47
|
|
38
|
-
|
39
|
-
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max);
|
48
|
+
/// @}
|
@@ -19,19 +19,28 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
22
|
+
/// @defgroup cpSimpleMotor cpSimpleMotor
|
23
|
+
/// @{
|
23
24
|
|
25
|
+
const cpConstraintClass *cpSimpleMotorGetClass(void);
|
26
|
+
|
27
|
+
/// @private
|
24
28
|
typedef struct cpSimpleMotor {
|
25
29
|
cpConstraint constraint;
|
26
30
|
cpFloat rate;
|
27
31
|
|
28
32
|
cpFloat iSum;
|
29
33
|
|
30
|
-
cpFloat jAcc
|
34
|
+
cpFloat jAcc;
|
31
35
|
} cpSimpleMotor;
|
32
36
|
|
33
|
-
|
34
|
-
cpSimpleMotor
|
35
|
-
|
37
|
+
/// Allocate a simple motor.
|
38
|
+
cpSimpleMotor* cpSimpleMotorAlloc(void);
|
39
|
+
/// initialize a simple motor.
|
40
|
+
cpSimpleMotor* cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
|
41
|
+
/// Allocate and initialize a simple motor.
|
42
|
+
cpConstraint* cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);
|
43
|
+
|
44
|
+
CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate)
|
36
45
|
|
37
|
-
|
46
|
+
/// @}
|
@@ -19,8 +19,12 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
22
|
+
/// @defgroup cpSlideJoint cpSlideJoint
|
23
|
+
/// @{
|
23
24
|
|
25
|
+
const cpConstraintClass *cpSlideJointGetClass(void);
|
26
|
+
|
27
|
+
/// @private
|
24
28
|
typedef struct cpSlideJoint {
|
25
29
|
cpConstraint constraint;
|
26
30
|
cpVect anchr1, anchr2;
|
@@ -30,15 +34,20 @@ typedef struct cpSlideJoint {
|
|
30
34
|
cpVect n;
|
31
35
|
cpFloat nMass;
|
32
36
|
|
33
|
-
cpFloat jnAcc
|
37
|
+
cpFloat jnAcc;
|
34
38
|
cpFloat bias;
|
35
39
|
} cpSlideJoint;
|
36
40
|
|
37
|
-
|
38
|
-
cpSlideJoint
|
39
|
-
|
41
|
+
/// Allocate a slide joint.
|
42
|
+
cpSlideJoint* cpSlideJointAlloc(void);
|
43
|
+
/// Initialize a slide joint.
|
44
|
+
cpSlideJoint* cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
45
|
+
/// Allocate and initialize a slide joint.
|
46
|
+
cpConstraint* cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
47
|
+
|
48
|
+
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1)
|
49
|
+
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2)
|
50
|
+
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min)
|
51
|
+
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max)
|
40
52
|
|
41
|
-
|
42
|
-
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2);
|
43
|
-
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min);
|
44
|
-
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max);
|
53
|
+
/// @}
|
@@ -19,22 +19,13 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
22
|
+
// These are utility routines to use when creating custom constraints.
|
23
|
+
// I'm not sure if this should be part of the private API or not.
|
24
|
+
// I should probably clean up the naming conventions if it is...
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
-
#define J_MAX(constraint, dt) (((cpConstraint *)constraint)->maxForce*(dt))
|
26
|
+
#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(void){return (cpConstraintClass *)&klass;}
|
27
27
|
|
28
|
-
|
29
|
-
#define CONSTRAINT_BEGIN(constraint, a_var, b_var) \
|
30
|
-
cpBody *a_var, *b_var; { \
|
31
|
-
a_var = ((cpConstraint *)constraint)->a; \
|
32
|
-
b_var = ((cpConstraint *)constraint)->b; \
|
33
|
-
if( \
|
34
|
-
(cpBodyIsSleeping(a_var) || cpBodyIsStatic(a_var)) && \
|
35
|
-
(cpBodyIsSleeping(b_var) || cpBodyIsStatic(b_var)) \
|
36
|
-
) return; \
|
37
|
-
}
|
28
|
+
void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);
|
38
29
|
|
39
30
|
static inline cpVect
|
40
31
|
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
@@ -49,18 +40,24 @@ normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
|
49
40
|
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
50
41
|
}
|
51
42
|
|
43
|
+
static inline void
|
44
|
+
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
45
|
+
body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
|
46
|
+
body->w += body->i_inv*cpvcross(r, j);
|
47
|
+
}
|
48
|
+
|
52
49
|
static inline void
|
53
50
|
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
54
51
|
{
|
55
|
-
|
56
|
-
|
52
|
+
apply_impulse(a, cpvneg(j), r1);
|
53
|
+
apply_impulse(b, j, r2);
|
57
54
|
}
|
58
55
|
|
59
56
|
static inline void
|
60
57
|
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
61
58
|
{
|
62
|
-
body->v_bias = cpvadd(body->v_bias, cpvmult(j, body->m_inv));
|
63
|
-
body->w_bias += body->i_inv*cpvcross(r, j);
|
59
|
+
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
|
60
|
+
body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
|
64
61
|
}
|
65
62
|
|
66
63
|
static inline void
|
@@ -70,37 +67,30 @@ apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
|
70
67
|
apply_bias_impulse(b, j, r2);
|
71
68
|
}
|
72
69
|
|
73
|
-
static inline
|
74
|
-
|
70
|
+
static inline cpFloat
|
71
|
+
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
75
72
|
{
|
76
|
-
|
77
|
-
|
73
|
+
cpFloat rcn = cpvcross(r, n);
|
74
|
+
return body->m_inv + body->i_inv*rcn*rcn;
|
78
75
|
}
|
79
76
|
|
80
77
|
static inline cpFloat
|
81
78
|
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
82
79
|
{
|
83
|
-
cpFloat
|
84
|
-
|
85
|
-
cpFloat r2cn = cpvcross(r2, n);
|
86
|
-
|
87
|
-
cpFloat value = mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;
|
88
|
-
cpAssert(value != 0.0, "Unsolvable collision or constraint.");
|
80
|
+
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
81
|
+
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
89
82
|
|
90
83
|
return value;
|
91
84
|
}
|
92
85
|
|
93
|
-
static inline
|
94
|
-
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2
|
86
|
+
static inline cpMat2x2
|
87
|
+
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
95
88
|
{
|
96
|
-
// calculate mass matrix
|
97
|
-
// If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...
|
98
|
-
cpFloat k11, k12, k21, k22;
|
99
89
|
cpFloat m_sum = a->m_inv + b->m_inv;
|
100
90
|
|
101
|
-
// start with
|
102
|
-
k11 = m_sum
|
103
|
-
k21 = 0.0f
|
91
|
+
// start with Identity*m_sum
|
92
|
+
cpFloat k11 = m_sum, k12 = 0.0f;
|
93
|
+
cpFloat k21 = 0.0f, k22 = m_sum;
|
104
94
|
|
105
95
|
// add the influence from r1
|
106
96
|
cpFloat a_i_inv = a->i_inv;
|
@@ -119,16 +109,18 @@ k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect *k1, cpVect *k2)
|
|
119
109
|
k21 += r2nxy; k22 += r2xsq;
|
120
110
|
|
121
111
|
// invert
|
122
|
-
cpFloat
|
123
|
-
|
112
|
+
cpFloat det = k11*k22 - k12*k21;
|
113
|
+
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
124
114
|
|
125
|
-
cpFloat det_inv = 1.0f/
|
126
|
-
|
127
|
-
|
115
|
+
cpFloat det_inv = 1.0f/det;
|
116
|
+
return cpMat2x2New(
|
117
|
+
k22*det_inv, -k12*det_inv,
|
118
|
+
-k21*det_inv, k11*det_inv
|
119
|
+
);
|
128
120
|
}
|
129
121
|
|
130
|
-
static inline
|
131
|
-
|
122
|
+
static inline cpFloat
|
123
|
+
bias_coef(cpFloat errorBias, cpFloat dt)
|
132
124
|
{
|
133
|
-
return
|
125
|
+
return 1.0f - cpfpow(errorBias, dt);
|
134
126
|
}
|
data/ext/chipmunk/cpArbiter.c
CHANGED
@@ -18,15 +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
|
-
#include <stdlib.h>
|
23
21
|
|
24
22
|
#include "chipmunk_private.h"
|
25
23
|
#include "constraints/util.h"
|
26
24
|
|
27
|
-
cpFloat cp_bias_coef = 0.1f;
|
28
|
-
cpFloat cp_collision_slop = 0.1f;
|
29
|
-
|
30
25
|
cpContact*
|
31
26
|
cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash)
|
32
27
|
{
|
@@ -43,62 +38,157 @@ cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash
|
|
43
38
|
return con;
|
44
39
|
}
|
45
40
|
|
41
|
+
// TODO make this generic so I can reuse it for constraints also.
|
42
|
+
static inline void
|
43
|
+
unthreadHelper(cpArbiter *arb, cpBody *body)
|
44
|
+
{
|
45
|
+
struct cpArbiterThread *thread = cpArbiterThreadForBody(arb, body);
|
46
|
+
cpArbiter *prev = thread->prev;
|
47
|
+
cpArbiter *next = thread->next;
|
48
|
+
|
49
|
+
if(prev){
|
50
|
+
cpArbiterThreadForBody(prev, body)->next = next;
|
51
|
+
} else if(body->arbiterList == arb) {
|
52
|
+
// IFF prev is NULL and body->arbiterList == arb, is arb at the head of the list.
|
53
|
+
// This function may be called for an arbiter that was never in a list.
|
54
|
+
// In that case, we need to protect it from wiping out the body->arbiterList pointer.
|
55
|
+
body->arbiterList = next;
|
56
|
+
}
|
57
|
+
|
58
|
+
if(next) cpArbiterThreadForBody(next, body)->prev = prev;
|
59
|
+
|
60
|
+
thread->prev = NULL;
|
61
|
+
thread->next = NULL;
|
62
|
+
}
|
63
|
+
|
64
|
+
void
|
65
|
+
cpArbiterUnthread(cpArbiter *arb)
|
66
|
+
{
|
67
|
+
unthreadHelper(arb, arb->body_a);
|
68
|
+
unthreadHelper(arb, arb->body_b);
|
69
|
+
}
|
70
|
+
|
71
|
+
cpBool cpArbiterIsFirstContact(const cpArbiter *arb)
|
72
|
+
{
|
73
|
+
return arb->CP_PRIVATE(state) == cpArbiterStateFirstColl;
|
74
|
+
}
|
75
|
+
|
76
|
+
int cpArbiterGetCount(const cpArbiter *arb)
|
77
|
+
{
|
78
|
+
// Return 0 contacts if we are in a separate callback.
|
79
|
+
return (arb->CP_PRIVATE(state) != cpArbiterStateCached ? arb->CP_PRIVATE(numContacts) : 0);
|
80
|
+
}
|
81
|
+
|
82
|
+
cpVect
|
83
|
+
cpArbiterGetNormal(const cpArbiter *arb, int i)
|
84
|
+
{
|
85
|
+
cpAssertHard(0 <= i && i < cpArbiterGetCount(arb), "Index error: The specified contact index is invalid for this arbiter");
|
86
|
+
|
87
|
+
cpVect n = arb->contacts[i].n;
|
88
|
+
return arb->swappedColl ? cpvneg(n) : n;
|
89
|
+
}
|
90
|
+
|
91
|
+
cpVect
|
92
|
+
cpArbiterGetPoint(const cpArbiter *arb, int i)
|
93
|
+
{
|
94
|
+
cpAssertHard(0 <= i && i < cpArbiterGetCount(arb), "Index error: The specified contact index is invalid for this arbiter");
|
95
|
+
|
96
|
+
return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);
|
97
|
+
}
|
98
|
+
|
99
|
+
cpFloat
|
100
|
+
cpArbiterGetDepth(const cpArbiter *arb, int i)
|
101
|
+
{
|
102
|
+
cpAssertHard(0 <= i && i < cpArbiterGetCount(arb), "Index error: The specified contact index is invalid for this arbiter");
|
103
|
+
|
104
|
+
return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);
|
105
|
+
}
|
106
|
+
|
107
|
+
cpContactPointSet
|
108
|
+
cpArbiterGetContactPointSet(const cpArbiter *arb)
|
109
|
+
{
|
110
|
+
cpContactPointSet set;
|
111
|
+
set.count = cpArbiterGetCount(arb);
|
112
|
+
|
113
|
+
int i;
|
114
|
+
for(i=0; i<set.count; i++){
|
115
|
+
set.points[i].point = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);
|
116
|
+
set.points[i].normal = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);
|
117
|
+
set.points[i].dist = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);
|
118
|
+
}
|
119
|
+
|
120
|
+
return set;
|
121
|
+
}
|
122
|
+
|
123
|
+
|
46
124
|
cpVect
|
47
|
-
cpArbiterTotalImpulse(cpArbiter *arb)
|
125
|
+
cpArbiterTotalImpulse(const cpArbiter *arb)
|
48
126
|
{
|
49
127
|
cpContact *contacts = arb->contacts;
|
50
128
|
cpVect sum = cpvzero;
|
51
129
|
|
52
|
-
for(int i=0, count=arb
|
130
|
+
for(int i=0, count=cpArbiterGetCount(arb); i<count; i++){
|
53
131
|
cpContact *con = &contacts[i];
|
54
132
|
sum = cpvadd(sum, cpvmult(con->n, con->jnAcc));
|
55
133
|
}
|
56
|
-
|
57
|
-
return sum;
|
134
|
+
|
135
|
+
return (arb->swappedColl ? sum : cpvneg(sum));
|
58
136
|
}
|
59
137
|
|
60
138
|
cpVect
|
61
|
-
cpArbiterTotalImpulseWithFriction(cpArbiter *arb)
|
139
|
+
cpArbiterTotalImpulseWithFriction(const cpArbiter *arb)
|
62
140
|
{
|
63
141
|
cpContact *contacts = arb->contacts;
|
64
142
|
cpVect sum = cpvzero;
|
65
143
|
|
66
|
-
for(int i=0, count=arb
|
144
|
+
for(int i=0, count=cpArbiterGetCount(arb); i<count; i++){
|
67
145
|
cpContact *con = &contacts[i];
|
68
146
|
sum = cpvadd(sum, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));
|
69
147
|
}
|
70
148
|
|
71
|
-
return sum;
|
149
|
+
return (arb->swappedColl ? sum : cpvneg(sum));
|
72
150
|
}
|
73
151
|
|
74
152
|
cpFloat
|
75
|
-
|
153
|
+
cpArbiterTotalKE(const cpArbiter *arb)
|
76
154
|
{
|
77
|
-
cpFloat
|
78
|
-
|
155
|
+
cpFloat eCoef = (1 - arb->e)/(1 + arb->e);
|
156
|
+
cpFloat sum = 0.0;
|
79
157
|
|
80
|
-
|
158
|
+
cpContact *contacts = arb->contacts;
|
159
|
+
for(int i=0, count=cpArbiterGetCount(arb); i<count; i++){
|
81
160
|
cpContact *con = &contacts[i];
|
82
|
-
|
161
|
+
cpFloat jnAcc = con->jnAcc;
|
162
|
+
cpFloat jtAcc = con->jtAcc;
|
83
163
|
|
84
|
-
|
85
|
-
vsum = cpvadd(vsum, j);
|
164
|
+
sum += eCoef*jnAcc*jnAcc/con->nMass + jtAcc*jtAcc/con->tMass;
|
86
165
|
}
|
87
166
|
|
88
|
-
|
89
|
-
return (1.0f - vmag/fsum);
|
167
|
+
return sum;
|
90
168
|
}
|
91
169
|
|
170
|
+
//cpFloat
|
171
|
+
//cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts)
|
172
|
+
//{
|
173
|
+
// cpFloat fsum = 0.0f;
|
174
|
+
// cpVect vsum = cpvzero;
|
175
|
+
//
|
176
|
+
// for(int i=0; i<numContacts; i++){
|
177
|
+
// cpContact *con = &contacts[i];
|
178
|
+
// cpVect j = cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc));
|
179
|
+
//
|
180
|
+
// fsum += cpvlength(j);
|
181
|
+
// vsum = cpvadd(vsum, j);
|
182
|
+
// }
|
183
|
+
//
|
184
|
+
// cpFloat vmag = cpvlength(vsum);
|
185
|
+
// return (1.0f - vmag/fsum);
|
186
|
+
//}
|
187
|
+
|
92
188
|
void
|
93
189
|
cpArbiterIgnore(cpArbiter *arb)
|
94
190
|
{
|
95
|
-
arb->state = cpArbiterStateIgnore
|
96
|
-
}
|
97
|
-
|
98
|
-
cpArbiter*
|
99
|
-
cpArbiterAlloc(void)
|
100
|
-
{
|
101
|
-
return (cpArbiter *)cpcalloc(1, sizeof(cpArbiter));
|
191
|
+
arb->state = cpArbiterStateIgnore;
|
102
192
|
}
|
103
193
|
|
104
194
|
cpArbiter*
|
@@ -114,41 +204,27 @@ cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b)
|
|
114
204
|
arb->numContacts = 0;
|
115
205
|
arb->contacts = NULL;
|
116
206
|
|
117
|
-
arb->a = a;
|
118
|
-
arb->b = b;
|
207
|
+
arb->a = a; arb->body_a = a->body;
|
208
|
+
arb->b = b; arb->body_b = b->body;
|
209
|
+
|
210
|
+
arb->thread_a.next = NULL;
|
211
|
+
arb->thread_b.next = NULL;
|
212
|
+
arb->thread_a.prev = NULL;
|
213
|
+
arb->thread_b.prev = NULL;
|
119
214
|
|
120
215
|
arb->stamp = 0;
|
121
216
|
arb->state = cpArbiterStateFirstColl;
|
122
217
|
|
218
|
+
arb->data = NULL;
|
219
|
+
|
123
220
|
return arb;
|
124
221
|
}
|
125
222
|
|
126
|
-
cpArbiter*
|
127
|
-
cpArbiterNew(cpShape *a, cpShape *b)
|
128
|
-
{
|
129
|
-
return cpArbiterInit(cpArbiterAlloc(), a, b);
|
130
|
-
}
|
131
|
-
|
132
|
-
void
|
133
|
-
cpArbiterDestroy(cpArbiter *arb)
|
134
|
-
{
|
135
|
-
// if(arb->contacts) cpfree(arb->contacts);
|
136
|
-
}
|
137
|
-
|
138
|
-
void
|
139
|
-
cpArbiterFree(cpArbiter *arb)
|
140
|
-
{
|
141
|
-
if(arb){
|
142
|
-
cpArbiterDestroy(arb);
|
143
|
-
cpfree(arb);
|
144
|
-
}
|
145
|
-
}
|
146
|
-
|
147
223
|
void
|
148
224
|
cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)
|
149
225
|
{
|
150
226
|
// Arbiters without contact data may exist if a collision function rejected the collision.
|
151
|
-
if(arb->
|
227
|
+
if(arb->numContacts > 0){
|
152
228
|
// Iterate over the possible pairs to look for hash value matches.
|
153
229
|
for(int i=0; i<arb->numContacts; i++){
|
154
230
|
cpContact *old = &arb->contacts[i];
|
@@ -177,18 +253,18 @@ cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisio
|
|
177
253
|
arb->surface_vr = cpvsub(a->surface_v, b->surface_v);
|
178
254
|
|
179
255
|
// For collisions between two similar primitive types, the order could have been swapped.
|
180
|
-
arb->a = a;
|
181
|
-
arb->b = b;
|
256
|
+
arb->a = a; arb->body_a = a->body;
|
257
|
+
arb->b = b; arb->body_b = b->body;
|
182
258
|
|
183
259
|
// mark it as new if it's been cached
|
184
260
|
if(arb->state == cpArbiterStateCached) arb->state = cpArbiterStateFirstColl;
|
185
261
|
}
|
186
262
|
|
187
263
|
void
|
188
|
-
cpArbiterPreStep(cpArbiter *arb, cpFloat
|
264
|
+
cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat slop, cpFloat bias)
|
189
265
|
{
|
190
|
-
cpBody *a = arb->
|
191
|
-
cpBody *b = arb->
|
266
|
+
cpBody *a = arb->body_a;
|
267
|
+
cpBody *b = arb->body_b;
|
192
268
|
|
193
269
|
for(int i=0; i<arb->numContacts; i++){
|
194
270
|
cpContact *con = &arb->contacts[i];
|
@@ -202,79 +278,68 @@ cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)
|
|
202
278
|
con->tMass = 1.0f/k_scalar(a, b, con->r1, con->r2, cpvperp(con->n));
|
203
279
|
|
204
280
|
// Calculate the target bias velocity.
|
205
|
-
con->bias = -
|
281
|
+
con->bias = -bias*cpfmin(0.0f, con->dist + slop)/dt;
|
206
282
|
con->jBias = 0.0f;
|
207
283
|
|
208
284
|
// Calculate the target bounce velocity.
|
209
|
-
con->bounce = normal_relative_velocity(a, b, con->r1, con->r2, con->n)*arb->e
|
285
|
+
con->bounce = normal_relative_velocity(a, b, con->r1, con->r2, con->n)*arb->e;
|
210
286
|
}
|
211
287
|
}
|
212
288
|
|
213
289
|
void
|
214
|
-
cpArbiterApplyCachedImpulse(cpArbiter *arb)
|
290
|
+
cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef)
|
215
291
|
{
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
arb->surface_vr = cpvsub(shapeb->surface_v, shapea->surface_v);
|
221
|
-
|
222
|
-
cpBody *a = shapea->body;
|
223
|
-
cpBody *b = shapeb->body;
|
292
|
+
if(cpArbiterIsFirstContact(arb)) return;
|
293
|
+
|
294
|
+
cpBody *a = arb->body_a;
|
295
|
+
cpBody *b = arb->body_b;
|
224
296
|
|
225
297
|
for(int i=0; i<arb->numContacts; i++){
|
226
298
|
cpContact *con = &arb->contacts[i];
|
227
|
-
|
299
|
+
cpVect j = cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc));
|
300
|
+
apply_impulses(a, b, con->r1, con->r2, cpvmult(j, dt_coef));
|
228
301
|
}
|
229
302
|
}
|
230
303
|
|
304
|
+
// TODO is it worth splitting velocity/position correction?
|
305
|
+
|
231
306
|
void
|
232
|
-
cpArbiterApplyImpulse(cpArbiter *arb
|
307
|
+
cpArbiterApplyImpulse(cpArbiter *arb)
|
233
308
|
{
|
234
|
-
cpBody *a = arb->
|
235
|
-
cpBody *b = arb->
|
309
|
+
cpBody *a = arb->body_a;
|
310
|
+
cpBody *b = arb->body_b;
|
311
|
+
cpVect surface_vr = arb->surface_vr;
|
312
|
+
cpFloat friction = arb->u;
|
236
313
|
|
237
314
|
for(int i=0; i<arb->numContacts; i++){
|
238
315
|
cpContact *con = &arb->contacts[i];
|
316
|
+
cpFloat nMass = con->nMass;
|
239
317
|
cpVect n = con->n;
|
240
318
|
cpVect r1 = con->r1;
|
241
319
|
cpVect r2 = con->r2;
|
242
320
|
|
243
|
-
// Calculate the relative bias velocities.
|
244
321
|
cpVect vb1 = cpvadd(a->v_bias, cpvmult(cpvperp(r1), a->w_bias));
|
245
322
|
cpVect vb2 = cpvadd(b->v_bias, cpvmult(cpvperp(r2), b->w_bias));
|
323
|
+
cpVect vr = relative_velocity(a, b, r1, r2);
|
324
|
+
|
246
325
|
cpFloat vbn = cpvdot(cpvsub(vb2, vb1), n);
|
326
|
+
cpFloat vrn = cpvdot(vr, n);
|
327
|
+
cpFloat vrt = cpvdot(cpvadd(vr, surface_vr), cpvperp(n));
|
247
328
|
|
248
|
-
|
249
|
-
cpFloat jbn = (con->bias - vbn)*con->nMass;
|
329
|
+
cpFloat jbn = (con->bias - vbn)*nMass;
|
250
330
|
cpFloat jbnOld = con->jBias;
|
251
331
|
con->jBias = cpfmax(jbnOld + jbn, 0.0f);
|
252
|
-
jbn = con->jBias - jbnOld;
|
253
332
|
|
254
|
-
|
255
|
-
apply_bias_impulses(a, b, r1, r2, cpvmult(n, jbn));
|
256
|
-
|
257
|
-
// Calculate the relative velocity.
|
258
|
-
cpVect vr = relative_velocity(a, b, r1, r2);
|
259
|
-
cpFloat vrn = cpvdot(vr, n);
|
260
|
-
|
261
|
-
// Calculate and clamp the normal impulse.
|
262
|
-
cpFloat jn = -(con->bounce*eCoef + vrn)*con->nMass;
|
333
|
+
cpFloat jn = -(con->bounce + vrn)*nMass;
|
263
334
|
cpFloat jnOld = con->jnAcc;
|
264
335
|
con->jnAcc = cpfmax(jnOld + jn, 0.0f);
|
265
|
-
jn = con->jnAcc - jnOld;
|
266
|
-
|
267
|
-
// Calculate the relative tangent velocity.
|
268
|
-
cpFloat vrt = cpvdot(cpvadd(vr, arb->surface_vr), cpvperp(n));
|
269
336
|
|
270
|
-
|
271
|
-
cpFloat jtMax = arb->u*con->jnAcc;
|
337
|
+
cpFloat jtMax = friction*con->jnAcc;
|
272
338
|
cpFloat jt = -vrt*con->tMass;
|
273
339
|
cpFloat jtOld = con->jtAcc;
|
274
340
|
con->jtAcc = cpfclamp(jtOld + jt, -jtMax, jtMax);
|
275
|
-
jt = con->jtAcc - jtOld;
|
276
341
|
|
277
|
-
|
278
|
-
apply_impulses(a, b, r1, r2, cpvrotate(n, cpv(
|
342
|
+
apply_bias_impulses(a, b, r1, r2, cpvmult(n, con->jBias - jbnOld));
|
343
|
+
apply_impulses(a, b, r1, r2, cpvrotate(n, cpv(con->jnAcc - jnOld, con->jtAcc - jtOld)));
|
279
344
|
}
|
280
345
|
}
|