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
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/clean'
4
- require 'rake/extensiontask'
5
- require 'rake/gempackagetask'
6
-
7
- CHIPMUNK_VERSION = "4.1.0"
8
-
9
- dlext = Config::CONFIG['DLEXT']
10
-
11
- CLEAN.include("ext/**/*.#{dlext}", "ext/**/.log", "ext/**/.o", "ext/**/*~", "ext/**/*#*", "ext/**/.obj", "ext/**/.def", "ext/**/.pdb")
12
- CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o", "doc/**")
13
-
14
- Rake::ExtensionTask.new('chipmunk')
15
-
16
- spec = Gem::Specification.new do |s|
17
- s.name = "chipmunk"
18
- s.summary = "ruby bindings for the chipmunk physics engine"
19
- s.description = s.summary
20
- s.version = CHIPMUNK_VERSION
21
- s.author = "Scott Lembcke, Beoran, John Mair (banisterfiend)"
22
- s.email = 'jrmair@gmail.com'
23
- s.date = Time.now.strftime '%Y-%m-%d'
24
- s.require_path = 'lib'
25
- s.homepage = "http://code.google.com/p/chipmunk-physics/"
26
- s.platform = Gem::Platform::RUBY
27
- s.extensions = FileList["ext/**/extconf.rb"]
28
- s.files = ["Rakefile", "lib/chipmunk.rb"] + FileList["ext/**/extconf.rb", "ext/**/*.h",
29
- "ext/**/*.c"].to_a
30
- end
31
-
32
- Rake::GemPackageTask.new(spec) do |pkg|
33
- pkg.need_zip = false
34
- pkg.need_tar = false
35
- end
36
-
37
- Rake::ExtensionTask.new('chipmunk', spec) do |ext|
38
- ext.cross_compile = true
39
- ext.cross_platform = 'i386-mswin32'
40
- end
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
@@ -19,7 +19,8 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include "stdlib.h"
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 *)calloc(numVerts, sizeof(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
- free(tVerts);
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"
@@ -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, unsigned int hash)
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
- cpContactsSumImpulses(cpContact *contacts, int numContacts)
47
+ cpArbiterTotalImpulse(cpArbiter *arb)
48
48
  {
49
+ cpContact *contacts = arb->contacts;
49
50
  cpVect sum = cpvzero;
50
51
 
51
- for(int i=0; i<numContacts; i++){
52
+ for(int i=0, count=arb->numContacts; i<count; i++){
52
53
  cpContact *con = &contacts[i];
53
- cpVect j = cpvmult(con->n, con->jnAcc);
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
- cpContactsSumImpulsesWithFriction(cpContact *contacts, int numContacts)
61
+ cpArbiterTotalImpulseWithFriction(cpArbiter *arb)
62
62
  {
63
+ cpContact *contacts = arb->contacts;
63
64
  cpVect sum = cpvzero;
64
65
 
65
- for(int i=0; i<numContacts; i++){
66
+ for(int i=0, count=arb->numContacts; i<count; i++){
66
67
  cpContact *con = &contacts[i];
67
- cpVect t = cpvperp(con->n);
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 *)calloc(1, sizeof(cpArbiter));
101
+ return (cpArbiter *)cpcalloc(1, sizeof(cpArbiter));
79
102
  }
80
103
 
81
104
  cpArbiter*
82
- cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b, int stamp)
105
+ cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b)
83
106
  {
84
107
  arb->numContacts = 0;
85
108
  arb->contacts = NULL;
86
109
 
87
- arb->a = a;
88
- arb->b = b;
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, int stamp)
120
+ cpArbiterNew(cpShape *a, cpShape *b)
97
121
  {
98
- return cpArbiterInit(cpArbiterAlloc(), a, b, stamp);
122
+ return cpArbiterInit(cpArbiterAlloc(), a, b);
99
123
  }
100
124
 
101
125
  void
102
126
  cpArbiterDestroy(cpArbiter *arb)
103
127
  {
104
- free(arb->contacts);
128
+ // if(arb->contacts) cpfree(arb->contacts);
105
129
  }
106
130
 
107
131
  void
108
132
  cpArbiterFree(cpArbiter *arb)
109
133
  {
110
- if(arb) cpArbiterDestroy(arb);
111
- free(arb);
134
+ if(arb){
135
+ cpArbiterDestroy(arb);
136
+ cpfree(arb);
137
+ }
112
138
  }
113
139
 
114
140
  void
115
- cpArbiterInject(cpArbiter *arb, cpContact *contacts, int numContacts)
141
+ cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)
116
142
  {
117
- // Iterate over the possible pairs to look for hash value matches.
118
- for(int i=0; i<arb->numContacts; i++){
119
- cpContact *old = &arb->contacts[i];
120
-
121
- for(int j=0; j<numContacts; j++){
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
- // This could trigger false possitives.
125
- if(new_contact->hash == old->hash){
126
- // Copy the persistant contact information.
127
- new_contact->jnAcc = old->jnAcc;
128
- new_contact->jtAcc = old->jtAcc;
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
- free(arb->contacts);
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->a;
143
- cpShape *shapeb = arb->b;
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
- cpFloat mass_sum = a->m_inv + b->m_inv;
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
- cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(con->r1), a->w));
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->a;
189
- cpShape *shapeb = arb->b;
210
+ cpShape *shapea = arb->private_a;
211
+ cpShape *shapeb = arb->private_b;
190
212
 
191
213
  arb->u = shapea->u * shapeb->u;
192
- arb->target_v = cpvsub(shapeb->surface_v, shapea->surface_v);
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->a->body;
211
- cpBody *b = arb->b->body;
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
- cpVect jb = cpvmult(n, jbn);
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 v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
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
- cpVect t = cpvperp(n);
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
- cpVect j = cpvadd(cpvmult(n, jn), cpvmult(t, jt));
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
  }