chipmunk 4.1.0 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +60 -0
- data/Rakefile +47 -40
- data/ext/chipmunk/chipmunk.c +39 -3
- data/ext/chipmunk/cpArbiter.c +91 -80
- data/ext/chipmunk/cpArray.c +24 -10
- data/ext/chipmunk/cpBB.c +5 -4
- data/ext/chipmunk/cpBody.c +30 -22
- data/ext/chipmunk/cpCollision.c +54 -53
- data/ext/chipmunk/cpConstraint.c +54 -0
- data/ext/chipmunk/cpDampedRotarySpring.c +106 -0
- data/ext/chipmunk/cpDampedSpring.c +117 -0
- data/ext/chipmunk/cpGearJoint.c +114 -0
- data/ext/chipmunk/cpGrooveJoint.c +138 -0
- data/ext/chipmunk/cpHashSet.c +74 -40
- data/ext/chipmunk/cpPinJoint.c +117 -0
- data/ext/chipmunk/cpPivotJoint.c +114 -0
- data/ext/chipmunk/cpPolyShape.c +117 -15
- data/ext/chipmunk/cpRatchetJoint.c +128 -0
- data/ext/chipmunk/cpRotaryLimitJoint.c +122 -0
- data/ext/chipmunk/cpShape.c +174 -18
- data/ext/chipmunk/cpSimpleMotor.c +99 -0
- data/ext/chipmunk/cpSlideJoint.c +131 -0
- data/ext/chipmunk/cpSpace.c +584 -215
- data/ext/chipmunk/cpSpaceHash.c +191 -105
- data/ext/chipmunk/cpVect.c +18 -10
- data/ext/chipmunk/extconf.rb +34 -4
- data/ext/chipmunk/{chipmunk.h → include/chipmunk/chipmunk.h} +63 -6
- data/ext/chipmunk/include/chipmunk/chipmunk_ffi.h +42 -0
- data/ext/chipmunk/include/chipmunk/chipmunk_types.h +80 -0
- data/ext/chipmunk/include/chipmunk/chipmunk_unsafe.h +54 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpConstraint.h +92 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpDampedSpring.h +53 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpGearJoint.h +41 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpGrooveJoint.h +44 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpPinJoint.h +43 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpPivotJoint.h +42 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpSlideJoint.h +44 -0
- data/ext/chipmunk/include/chipmunk/constraints/util.h +116 -0
- data/ext/chipmunk/{cpArbiter.h → include/chipmunk/cpArbiter.h} +66 -15
- data/ext/chipmunk/{cpArray.h → include/chipmunk/cpArray.h} +2 -1
- data/ext/chipmunk/{cpBB.h → include/chipmunk/cpBB.h} +21 -0
- data/ext/chipmunk/{cpBody.h → include/chipmunk/cpBody.h} +37 -9
- data/ext/chipmunk/{cpCollision.h → include/chipmunk/cpCollision.h} +1 -1
- data/ext/chipmunk/{cpHashSet.h → include/chipmunk/cpHashSet.h} +12 -9
- data/ext/chipmunk/{cpPolyShape.h → include/chipmunk/cpPolyShape.h} +13 -2
- data/ext/chipmunk/{cpShape.h → include/chipmunk/cpShape.h} +51 -18
- data/ext/chipmunk/include/chipmunk/cpSpace.h +180 -0
- data/ext/chipmunk/{cpSpaceHash.h → include/chipmunk/cpSpaceHash.h} +18 -9
- data/ext/chipmunk/{cpVect.h → include/chipmunk/cpVect.h} +61 -10
- data/ext/chipmunk/prime.h +32 -32
- data/ext/chipmunk/rb_chipmunk.c +125 -109
- data/ext/chipmunk/rb_chipmunk.h +96 -77
- data/ext/chipmunk/rb_cpArbiter.c +225 -0
- data/ext/chipmunk/rb_cpBB.c +174 -154
- data/ext/chipmunk/rb_cpBody.c +347 -239
- data/ext/chipmunk/rb_cpConstraint.c +346 -0
- data/ext/chipmunk/rb_cpShape.c +455 -292
- data/ext/chipmunk/rb_cpSpace.c +544 -330
- data/ext/chipmunk/rb_cpVect.c +321 -250
- data/lib/chipmunk.rb +28 -15
- data/lib/chipmunk/version.rb +3 -0
- metadata +74 -34
- data/ext/chipmunk/cpJoint.c +0 -553
- data/ext/chipmunk/cpJoint.h +0 -122
- data/ext/chipmunk/cpSpace.h +0 -120
- data/ext/chipmunk/rb_cpJoint.c +0 -136
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/* Copyright (c) 2007 Scott Lembcke
|
2
|
+
*
|
3
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
* of this software and associated documentation files (the "Software"), to deal
|
5
|
+
* in the Software without restriction, including without limitation the rights
|
6
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
* copies of the Software, and to permit persons to whom the Software is
|
8
|
+
* furnished to do so, subject to the following conditions:
|
9
|
+
*
|
10
|
+
* The above copyright notice and this permission notice shall be included in
|
11
|
+
* all copies or substantial portions of the Software.
|
12
|
+
*
|
13
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
* SOFTWARE.
|
20
|
+
*/
|
data/README
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
Ruby Bindings to Chipmunk Physics Version 5.2.0
|
2
|
+
|
3
|
+
(C) Scott Lembcke, Beoran and John Mair (banisterfiend)
|
4
|
+
|
5
|
+
IMPORTANT NOTICE:
|
6
|
+
These are bindings for MRI Ruby 1.8.x and 1.9.x to Chipmunk version 5.2.0
|
7
|
+
|
8
|
+
(1) 1/10/09 Cross-Platform Gem built by John Mair (banisterfiend)
|
9
|
+
* Just go: gem install chipmunk
|
10
|
+
|
11
|
+
(2) Patched for 1.9.1 by Beoran (beoran@rubyforge.org)
|
12
|
+
|
13
|
+
(3) How to build the gems? (maintainers only)
|
14
|
+
* Install rake-compiler (http://github.com/luislavena/rake-compiler)
|
15
|
+
* Install 1.9.1 and 1.8.6 mingw ruby versions (instructions above)
|
16
|
+
* Type: rake cross native gem RUBY_CC_VERSION=1.8.6:1.9.1
|
17
|
+
* Upload new gems to rubyforge and gemcutter.
|
18
|
+
|
19
|
+
FORUM:
|
20
|
+
|
21
|
+
http://www.slembcke.net/forums
|
22
|
+
|
23
|
+
CONTACT:
|
24
|
+
slembcke@gmail.com (also on Google Talk) for Chipmunk
|
25
|
+
beoran@rubyforge.org for these bindings
|
26
|
+
|
27
|
+
ABOUT:
|
28
|
+
Chipmunk is a simple, lightweight and fast 2D rigid body physics library
|
29
|
+
written in C. It's licensed under the unrestrictive, OSI approved MIT license. My aim is to give 2D developers access the same quality of physics you find in newer 3D games. I hope you enjoy using Chipmunk, and please consider donating to help make it worth our time to continue to support Chipmunk with great new features.
|
30
|
+
|
31
|
+
These bindings are intened to as an alternative for the chipmunk-ffi bindings when performance is of the utmost importance, as it may be for games. The intent is for it to be source code compatibe with the ffi bindings. If you have any problems with these bindings, please contact the maintainer at beoran@rubyforge.org.
|
32
|
+
|
33
|
+
CONTRACTING:
|
34
|
+
Howling Moon Software (Slembke's company) is available for contracting if you want to make the physics in your game really stand out. Feel free to contact them through their webpage: http://howlingmoonsoftware.com/contracting.php
|
35
|
+
|
36
|
+
CHANGES SINCE 4.x:
|
37
|
+
* Brand new Joint/Constraint API: New constraints can be added easily and are much more flexible than the old joint system.
|
38
|
+
* Efficient Segment Queries - Like raycasting, but with line segments.
|
39
|
+
* Brand new collision callback API: Collision begin/separate events, API for removal of objects within callbacks, more programable control over collision handling.
|
40
|
+
|
41
|
+
CHANGES SINCE RELEASE 3:
|
42
|
+
|
43
|
+
* Rational versioning scheme: (major.minor.build) Small changes
|
44
|
+
increment the build number. Significant changes that don't affect
|
45
|
+
backwards compatibility increment the minor number. Major changes
|
46
|
+
that will break backwards compatibility will increment the major
|
47
|
+
number.
|
48
|
+
|
49
|
+
* Optimizations: Speed increases of 5-10% should be common.
|
50
|
+
|
51
|
+
* Groove Joint: Similar to a pivot joint, but one of the anchors is
|
52
|
+
on a linear slide instead of being fixed.
|
53
|
+
|
54
|
+
* Comments/cleanup. The code should be much more readable now.
|
55
|
+
|
56
|
+
* Official build paths for working on Linux and MSVC.
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
data/Rakefile
CHANGED
@@ -1,40 +1,47 @@
|
|
1
|
-
# Rakefile added by John Mair (banisterfiend)
|
2
|
-
|
3
|
-
require 'rake/
|
4
|
-
require 'rake/
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
dlext
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
1
|
+
# Rakefile added by John Mair (banisterfiend)
|
2
|
+
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'rake/clean'
|
5
|
+
require 'lib/chipmunk/version.rb'
|
6
|
+
|
7
|
+
dlext = Config::CONFIG['DLEXT']
|
8
|
+
|
9
|
+
CLEAN.include("ext/**/*.#{dlext}", "ext/**/.log", "ext/**/.o", "ext/**/*~", "ext/**/*#*", "ext/**/.obj", "ext/**/.def", "ext/**/.pdb")
|
10
|
+
CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o", "doc/**")
|
11
|
+
|
12
|
+
|
13
|
+
def apply_spec_defaults(s)
|
14
|
+
s.name = "chipmunk"
|
15
|
+
s.summary = "ruby bindings for the chipmunk 5.1.0 physics engine"
|
16
|
+
s.description = s.summary
|
17
|
+
s.version = Chipmunk::VERSION
|
18
|
+
s.author = "Scott Lembcke, Beoran, John Mair (banisterfiend)"
|
19
|
+
s.email = 'beoran@rubyforge.com'
|
20
|
+
s.date = Time.now.strftime '%Y-%m-%d'
|
21
|
+
s.require_path = 'lib'
|
22
|
+
s.homepage = "http://code.google.com/p/chipmunk-physics/"
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# common tasks
|
27
|
+
task :compile => :clean
|
28
|
+
|
29
|
+
# spec = Gem::Specification.new do |s|
|
30
|
+
# apply_spec_defaults(s)
|
31
|
+
# s.platform = 'i386-mswin32'
|
32
|
+
# s.files = ["Rakefile", "README", "LICENSE", "lib/chipmunk.rb", "lib/1.8/chipmunk.#{dlext}", "lib/1.9/chipmunk.#{dlext}", "lib/chipmunk/version.rb"]
|
33
|
+
# end
|
34
|
+
|
35
|
+
|
36
|
+
spec = Gem::Specification.new do |s|
|
37
|
+
apply_spec_defaults(s)
|
38
|
+
s.platform = Gem::Platform::RUBY
|
39
|
+
s.extensions = FileList["ext/**/extconf.rb"]
|
40
|
+
s.files = ["Rakefile", "README", "LICENSE", "lib/chipmunk.rb", "lib/chipmunk/version.rb"] +
|
41
|
+
FileList["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c"].to_a
|
42
|
+
end
|
43
|
+
|
44
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
45
|
+
pkg.need_zip = false
|
46
|
+
pkg.need_tar = false
|
47
|
+
end
|
data/ext/chipmunk/chipmunk.c
CHANGED
@@ -19,7 +19,8 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
#include
|
22
|
+
#include <stdlib.h>
|
23
|
+
#include <stdio.h>
|
23
24
|
|
24
25
|
#include "chipmunk.h"
|
25
26
|
|
@@ -31,10 +32,27 @@ extern "C" {
|
|
31
32
|
}
|
32
33
|
#endif
|
33
34
|
|
35
|
+
void
|
36
|
+
cpMessage(char *message, char *condition, char *file, int line, int isError)
|
37
|
+
{
|
38
|
+
fprintf(stderr, (isError ? "Aborting due to Chipmunk error: %s\n" : "Chipmunk warning: %s\n"), message);
|
39
|
+
fprintf(stderr, "\tFailed condition: %s\n", condition);
|
40
|
+
fprintf(stderr, "\tSource:%s:%d\n", file, line);
|
41
|
+
|
42
|
+
if(isError) abort();
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
char *cpVersionString = "5.x.x";
|
34
47
|
|
35
48
|
void
|
36
49
|
cpInitChipmunk(void)
|
37
50
|
{
|
51
|
+
#ifndef NDEBUG
|
52
|
+
printf("Initializing Chipmunk v%s (Debug Enabled)\n", cpVersionString);
|
53
|
+
printf("Compile with -DNDEBUG defined to disable debug mode and runtime assertion checks\n");
|
54
|
+
#endif
|
55
|
+
|
38
56
|
cpInitCollisionFuncs();
|
39
57
|
}
|
40
58
|
|
@@ -44,10 +62,19 @@ cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)
|
|
44
62
|
return (1.0f/2.0f)*m*(r1*r1 + r2*r2) + m*cpvdot(offset, offset);
|
45
63
|
}
|
46
64
|
|
65
|
+
cpFloat
|
66
|
+
cpMomentForSegment(cpFloat m, cpVect a, cpVect b)
|
67
|
+
{
|
68
|
+
cpFloat length = cpvlength(cpvsub(b, a));
|
69
|
+
cpVect offset = cpvmult(cpvadd(a, b), 1.0f/2.0f);
|
70
|
+
|
71
|
+
return m*length*length/12.0f + m*cpvdot(offset, offset);
|
72
|
+
}
|
73
|
+
|
47
74
|
cpFloat
|
48
75
|
cpMomentForPoly(cpFloat m, const int numVerts, cpVect *verts, cpVect offset)
|
49
76
|
{
|
50
|
-
cpVect *tVerts = (cpVect *)
|
77
|
+
cpVect *tVerts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
|
51
78
|
for(int i=0; i<numVerts; i++)
|
52
79
|
tVerts[i] = cpvadd(verts[i], offset);
|
53
80
|
|
@@ -64,6 +91,15 @@ cpMomentForPoly(cpFloat m, const int numVerts, cpVect *verts, cpVect offset)
|
|
64
91
|
sum2 += a;
|
65
92
|
}
|
66
93
|
|
67
|
-
|
94
|
+
cpfree(tVerts);
|
68
95
|
return (m*sum1)/(6.0f*sum2);
|
69
96
|
}
|
97
|
+
|
98
|
+
cpFloat
|
99
|
+
cpMomentForBox(cpFloat m, cpFloat width, cpFloat height)
|
100
|
+
{
|
101
|
+
return m*(width*width + height*height)/12.0;
|
102
|
+
}
|
103
|
+
|
104
|
+
|
105
|
+
#include "chipmunk_ffi.h"
|
data/ext/chipmunk/cpArbiter.c
CHANGED
@@ -20,15 +20,15 @@
|
|
20
20
|
*/
|
21
21
|
|
22
22
|
#include <stdlib.h>
|
23
|
-
#include <math.h>
|
24
23
|
|
25
24
|
#include "chipmunk.h"
|
25
|
+
#include "constraints/util.h"
|
26
26
|
|
27
27
|
cpFloat cp_bias_coef = 0.1f;
|
28
28
|
cpFloat cp_collision_slop = 0.1f;
|
29
29
|
|
30
30
|
cpContact*
|
31
|
-
cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist,
|
31
|
+
cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash)
|
32
32
|
{
|
33
33
|
con->p = p;
|
34
34
|
con->n = n;
|
@@ -44,107 +44,142 @@ cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, unsigned int has
|
|
44
44
|
}
|
45
45
|
|
46
46
|
cpVect
|
47
|
-
|
47
|
+
cpArbiterTotalImpulse(cpArbiter *arb)
|
48
48
|
{
|
49
|
+
cpContact *contacts = arb->contacts;
|
49
50
|
cpVect sum = cpvzero;
|
50
51
|
|
51
|
-
for(int i=0; i<
|
52
|
+
for(int i=0, count=arb->numContacts; i<count; i++){
|
52
53
|
cpContact *con = &contacts[i];
|
53
|
-
|
54
|
-
sum = cpvadd(sum, j);
|
54
|
+
sum = cpvadd(sum, cpvmult(con->n, con->jnAcc));
|
55
55
|
}
|
56
56
|
|
57
57
|
return sum;
|
58
58
|
}
|
59
59
|
|
60
60
|
cpVect
|
61
|
-
|
61
|
+
cpArbiterTotalImpulseWithFriction(cpArbiter *arb)
|
62
62
|
{
|
63
|
+
cpContact *contacts = arb->contacts;
|
63
64
|
cpVect sum = cpvzero;
|
64
65
|
|
65
|
-
for(int i=0; i<
|
66
|
+
for(int i=0, count=arb->numContacts; i<count; i++){
|
66
67
|
cpContact *con = &contacts[i];
|
67
|
-
|
68
|
-
cpVect j = cpvadd(cpvmult(con->n, con->jnAcc), cpvmult(t, con->jtAcc));
|
69
|
-
sum = cpvadd(sum, j);
|
68
|
+
sum = cpvadd(sum, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));
|
70
69
|
}
|
71
70
|
|
72
71
|
return sum;
|
73
72
|
}
|
74
73
|
|
74
|
+
cpFloat
|
75
|
+
cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts)
|
76
|
+
{
|
77
|
+
cpFloat fsum = 0.0f;
|
78
|
+
cpVect vsum = cpvzero;
|
79
|
+
|
80
|
+
for(int i=0; i<numContacts; i++){
|
81
|
+
cpContact *con = &contacts[i];
|
82
|
+
cpVect j = cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc));
|
83
|
+
|
84
|
+
fsum += cpvlength(j);
|
85
|
+
vsum = cpvadd(vsum, j);
|
86
|
+
}
|
87
|
+
|
88
|
+
cpFloat vmag = cpvlength(vsum);
|
89
|
+
return (1.0f - vmag/fsum);
|
90
|
+
}
|
91
|
+
|
92
|
+
void
|
93
|
+
cpArbiterIgnore(cpArbiter *arb)
|
94
|
+
{
|
95
|
+
arb->state = cpArbiterStateIgnore;
|
96
|
+
}
|
97
|
+
|
75
98
|
cpArbiter*
|
76
99
|
cpArbiterAlloc(void)
|
77
100
|
{
|
78
|
-
return (cpArbiter *)
|
101
|
+
return (cpArbiter *)cpcalloc(1, sizeof(cpArbiter));
|
79
102
|
}
|
80
103
|
|
81
104
|
cpArbiter*
|
82
|
-
cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b
|
105
|
+
cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b)
|
83
106
|
{
|
84
107
|
arb->numContacts = 0;
|
85
108
|
arb->contacts = NULL;
|
86
109
|
|
87
|
-
arb->
|
88
|
-
arb->
|
110
|
+
arb->private_a = a;
|
111
|
+
arb->private_b = b;
|
112
|
+
|
113
|
+
arb->stamp = -1;
|
114
|
+
arb->state = cpArbiterStateFirstColl;
|
89
115
|
|
90
|
-
arb->stamp = stamp;
|
91
|
-
|
92
116
|
return arb;
|
93
117
|
}
|
94
118
|
|
95
119
|
cpArbiter*
|
96
|
-
cpArbiterNew(cpShape *a, cpShape *b
|
120
|
+
cpArbiterNew(cpShape *a, cpShape *b)
|
97
121
|
{
|
98
|
-
return cpArbiterInit(cpArbiterAlloc(), a, b
|
122
|
+
return cpArbiterInit(cpArbiterAlloc(), a, b);
|
99
123
|
}
|
100
124
|
|
101
125
|
void
|
102
126
|
cpArbiterDestroy(cpArbiter *arb)
|
103
127
|
{
|
104
|
-
|
128
|
+
// if(arb->contacts) cpfree(arb->contacts);
|
105
129
|
}
|
106
130
|
|
107
131
|
void
|
108
132
|
cpArbiterFree(cpArbiter *arb)
|
109
133
|
{
|
110
|
-
if(arb)
|
111
|
-
|
134
|
+
if(arb){
|
135
|
+
cpArbiterDestroy(arb);
|
136
|
+
cpfree(arb);
|
137
|
+
}
|
112
138
|
}
|
113
139
|
|
114
140
|
void
|
115
|
-
|
141
|
+
cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)
|
116
142
|
{
|
117
|
-
//
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
cpContact *new_contact = &contacts[j];
|
143
|
+
// Arbiters without contact data may exist if a collision function rejected the collision.
|
144
|
+
if(arb->contacts){
|
145
|
+
// Iterate over the possible pairs to look for hash value matches.
|
146
|
+
for(int i=0; i<arb->numContacts; i++){
|
147
|
+
cpContact *old = &arb->contacts[i];
|
123
148
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
new_contact->
|
149
|
+
for(int j=0; j<numContacts; j++){
|
150
|
+
cpContact *new_contact = &contacts[j];
|
151
|
+
|
152
|
+
// This could trigger false positives, but is fairly unlikely nor serious if it does.
|
153
|
+
if(new_contact->hash == old->hash){
|
154
|
+
// Copy the persistant contact information.
|
155
|
+
new_contact->jnAcc = old->jnAcc;
|
156
|
+
new_contact->jtAcc = old->jtAcc;
|
157
|
+
}
|
129
158
|
}
|
130
159
|
}
|
131
|
-
}
|
132
160
|
|
133
|
-
|
161
|
+
// cpfree(arb->contacts);
|
162
|
+
}
|
134
163
|
|
135
164
|
arb->contacts = contacts;
|
136
165
|
arb->numContacts = numContacts;
|
166
|
+
|
167
|
+
arb->handler = handler;
|
168
|
+
arb->swappedColl = (a->collision_type != handler->a);
|
169
|
+
|
170
|
+
arb->e = a->e * b->e;
|
171
|
+
arb->u = a->u * b->u;
|
172
|
+
arb->surface_vr = cpvsub(a->surface_v, b->surface_v);
|
173
|
+
|
174
|
+
// For collisions between two similar primitive types, the order could have been swapped.
|
175
|
+
arb->private_a = a; arb->private_b = b;
|
137
176
|
}
|
138
177
|
|
139
178
|
void
|
140
179
|
cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)
|
141
180
|
{
|
142
|
-
cpShape *shapea = arb->
|
143
|
-
cpShape *shapeb = arb->
|
144
|
-
|
145
|
-
cpFloat e = shapea->e * shapeb->e;
|
146
|
-
arb->u = shapea->u * shapeb->u;
|
147
|
-
arb->target_v = cpvsub(shapeb->surface_v, shapea->surface_v);
|
181
|
+
cpShape *shapea = arb->private_a;
|
182
|
+
cpShape *shapeb = arb->private_b;
|
148
183
|
|
149
184
|
cpBody *a = shapea->body;
|
150
185
|
cpBody *b = shapeb->body;
|
@@ -156,59 +191,42 @@ cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)
|
|
156
191
|
con->r1 = cpvsub(con->p, a->p);
|
157
192
|
con->r2 = cpvsub(con->p, b->p);
|
158
193
|
|
159
|
-
// Calculate the mass normal.
|
160
|
-
|
161
|
-
|
162
|
-
cpFloat r1cn = cpvcross(con->r1, con->n);
|
163
|
-
cpFloat r2cn = cpvcross(con->r2, con->n);
|
164
|
-
cpFloat kn = mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;
|
165
|
-
con->nMass = 1.0f/kn;
|
166
|
-
|
167
|
-
// Calculate the mass tangent.
|
168
|
-
cpVect t = cpvperp(con->n);
|
169
|
-
cpFloat r1ct = cpvcross(con->r1, t);
|
170
|
-
cpFloat r2ct = cpvcross(con->r2, t);
|
171
|
-
cpFloat kt = mass_sum + a->i_inv*r1ct*r1ct + b->i_inv*r2ct*r2ct;
|
172
|
-
con->tMass = 1.0f/kt;
|
194
|
+
// Calculate the mass normal and mass tangent.
|
195
|
+
con->nMass = 1.0f/k_scalar(a, b, con->r1, con->r2, con->n);
|
196
|
+
con->tMass = 1.0f/k_scalar(a, b, con->r1, con->r2, cpvperp(con->n));
|
173
197
|
|
174
198
|
// Calculate the target bias velocity.
|
175
199
|
con->bias = -cp_bias_coef*dt_inv*cpfmin(0.0f, con->dist + cp_collision_slop);
|
176
200
|
con->jBias = 0.0f;
|
177
201
|
|
178
202
|
// Calculate the target bounce velocity.
|
179
|
-
|
180
|
-
cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(con->r2), b->w));
|
181
|
-
con->bounce = cpvdot(con->n, cpvsub(v2, v1))*e;
|
203
|
+
con->bounce = normal_relative_velocity(a, b, con->r1, con->r2, con->n)*arb->e;//cpvdot(con->n, cpvsub(v2, v1))*e;
|
182
204
|
}
|
183
205
|
}
|
184
206
|
|
185
207
|
void
|
186
208
|
cpArbiterApplyCachedImpulse(cpArbiter *arb)
|
187
209
|
{
|
188
|
-
cpShape *shapea = arb->
|
189
|
-
cpShape *shapeb = arb->
|
210
|
+
cpShape *shapea = arb->private_a;
|
211
|
+
cpShape *shapeb = arb->private_b;
|
190
212
|
|
191
213
|
arb->u = shapea->u * shapeb->u;
|
192
|
-
arb->
|
214
|
+
arb->surface_vr = cpvsub(shapeb->surface_v, shapea->surface_v);
|
193
215
|
|
194
216
|
cpBody *a = shapea->body;
|
195
217
|
cpBody *b = shapeb->body;
|
196
218
|
|
197
219
|
for(int i=0; i<arb->numContacts; i++){
|
198
220
|
cpContact *con = &arb->contacts[i];
|
199
|
-
|
200
|
-
cpVect t = cpvperp(con->n);
|
201
|
-
cpVect j = cpvadd(cpvmult(con->n, con->jnAcc), cpvmult(t, con->jtAcc));
|
202
|
-
cpBodyApplyImpulse(a, cpvneg(j), con->r1);
|
203
|
-
cpBodyApplyImpulse(b, j, con->r2);
|
221
|
+
apply_impulses(a, b, con->r1, con->r2, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));
|
204
222
|
}
|
205
223
|
}
|
206
224
|
|
207
225
|
void
|
208
226
|
cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)
|
209
227
|
{
|
210
|
-
cpBody *a = arb->
|
211
|
-
cpBody *b = arb->
|
228
|
+
cpBody *a = arb->private_a->body;
|
229
|
+
cpBody *b = arb->private_b->body;
|
212
230
|
|
213
231
|
for(int i=0; i<arb->numContacts; i++){
|
214
232
|
cpContact *con = &arb->contacts[i];
|
@@ -228,14 +246,10 @@ cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)
|
|
228
246
|
jbn = con->jBias - jbnOld;
|
229
247
|
|
230
248
|
// Apply the bias impulse.
|
231
|
-
|
232
|
-
cpBodyApplyBiasImpulse(a, cpvneg(jb), r1);
|
233
|
-
cpBodyApplyBiasImpulse(b, jb, r2);
|
249
|
+
apply_bias_impulses(a, b, r1, r2, cpvmult(n, jbn));
|
234
250
|
|
235
251
|
// Calculate the relative velocity.
|
236
|
-
cpVect
|
237
|
-
cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
|
238
|
-
cpVect vr = cpvsub(v2, v1);
|
252
|
+
cpVect vr = relative_velocity(a, b, r1, r2);
|
239
253
|
cpFloat vrn = cpvdot(vr, n);
|
240
254
|
|
241
255
|
// Calculate and clamp the normal impulse.
|
@@ -245,8 +259,7 @@ cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)
|
|
245
259
|
jn = con->jnAcc - jnOld;
|
246
260
|
|
247
261
|
// Calculate the relative tangent velocity.
|
248
|
-
|
249
|
-
cpFloat vrt = cpvdot(cpvadd(vr, arb->target_v), t);
|
262
|
+
cpFloat vrt = cpvdot(cpvadd(vr, arb->surface_vr), cpvperp(n));
|
250
263
|
|
251
264
|
// Calculate and clamp the friction impulse.
|
252
265
|
cpFloat jtMax = arb->u*con->jnAcc;
|
@@ -256,8 +269,6 @@ cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)
|
|
256
269
|
jt = con->jtAcc - jtOld;
|
257
270
|
|
258
271
|
// Apply the final impulse.
|
259
|
-
|
260
|
-
cpBodyApplyImpulse(a, cpvneg(j), r1);
|
261
|
-
cpBodyApplyImpulse(b, j, r2);
|
272
|
+
apply_impulses(a, b, r1, r2, cpvrotate(n, cpv(jn, jt)));
|
262
273
|
}
|
263
274
|
}
|