reflexion 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/reflex/application.cpp +5 -5
  3. data/.doc/ext/reflex/body.cpp +167 -0
  4. data/.doc/ext/reflex/capture_event.cpp +4 -4
  5. data/.doc/ext/reflex/draw_event.cpp +4 -4
  6. data/.doc/ext/reflex/event.cpp +4 -4
  7. data/.doc/ext/reflex/fixture.cpp +101 -0
  8. data/.doc/ext/reflex/focus_event.cpp +4 -4
  9. data/.doc/ext/reflex/frame_event.cpp +4 -4
  10. data/.doc/ext/reflex/image_view.cpp +22 -5
  11. data/.doc/ext/reflex/key_event.cpp +4 -4
  12. data/.doc/ext/reflex/native.cpp +6 -0
  13. data/.doc/ext/reflex/pointer_event.cpp +4 -4
  14. data/.doc/ext/reflex/reflex.cpp +2 -3
  15. data/.doc/ext/reflex/scroll_event.cpp +4 -4
  16. data/.doc/ext/reflex/selector.cpp +4 -4
  17. data/.doc/ext/reflex/style.cpp +4 -4
  18. data/.doc/ext/reflex/style_length.cpp +4 -4
  19. data/.doc/ext/reflex/style_length2.cpp +4 -4
  20. data/.doc/ext/reflex/style_length4.cpp +4 -4
  21. data/.doc/ext/reflex/update_event.cpp +4 -4
  22. data/.doc/ext/reflex/view.cpp +110 -8
  23. data/.doc/ext/reflex/wheel_event.cpp +4 -4
  24. data/.doc/ext/reflex/window.cpp +36 -12
  25. data/README.md +2 -2
  26. data/Rakefile +2 -1
  27. data/VERSION +1 -1
  28. data/ext/reflex/application.cpp +8 -8
  29. data/ext/reflex/body.cpp +181 -0
  30. data/ext/reflex/capture_event.cpp +4 -4
  31. data/ext/reflex/draw_event.cpp +4 -4
  32. data/ext/reflex/event.cpp +4 -4
  33. data/ext/reflex/fixture.cpp +108 -0
  34. data/ext/reflex/focus_event.cpp +4 -4
  35. data/ext/reflex/frame_event.cpp +4 -4
  36. data/ext/reflex/image_view.cpp +24 -5
  37. data/ext/reflex/key_event.cpp +4 -4
  38. data/ext/reflex/native.cpp +6 -0
  39. data/ext/reflex/pointer_event.cpp +4 -4
  40. data/ext/reflex/reflex.cpp +2 -3
  41. data/ext/reflex/scroll_event.cpp +4 -4
  42. data/ext/reflex/selector.cpp +4 -4
  43. data/ext/reflex/style.cpp +4 -4
  44. data/ext/reflex/style_length.cpp +4 -4
  45. data/ext/reflex/style_length2.cpp +4 -4
  46. data/ext/reflex/style_length4.cpp +4 -4
  47. data/ext/reflex/update_event.cpp +4 -4
  48. data/ext/reflex/view.cpp +126 -12
  49. data/ext/reflex/wheel_event.cpp +4 -4
  50. data/ext/reflex/window.cpp +39 -12
  51. data/include/reflex/bitmap.h +20 -0
  52. data/include/reflex/body.h +82 -0
  53. data/include/reflex/bounds.h +20 -0
  54. data/include/reflex/color.h +20 -0
  55. data/include/reflex/color_space.h +20 -0
  56. data/include/reflex/defs.h +5 -1
  57. data/include/reflex/event.h +16 -25
  58. data/include/reflex/fixture.h +116 -0
  59. data/include/reflex/font.h +20 -0
  60. data/include/reflex/image.h +20 -0
  61. data/include/reflex/image_view.h +1 -1
  62. data/include/reflex/matrix.h +20 -0
  63. data/include/reflex/painter.h +20 -0
  64. data/include/reflex/point.h +24 -0
  65. data/include/reflex/ruby/application.h +6 -0
  66. data/include/reflex/ruby/body.h +41 -0
  67. data/include/reflex/ruby/event.h +68 -0
  68. data/include/reflex/ruby/fixture.h +41 -0
  69. data/include/reflex/ruby/image_view.h +14 -0
  70. data/include/reflex/ruby/selector.h +14 -0
  71. data/include/reflex/ruby/style.h +14 -0
  72. data/include/reflex/ruby/style_length.h +26 -0
  73. data/include/reflex/ruby/view.h +43 -39
  74. data/include/reflex/ruby/window.h +27 -21
  75. data/include/reflex/ruby.h +2 -0
  76. data/include/reflex/shader.h +20 -0
  77. data/include/reflex/style.h +2 -3
  78. data/include/reflex/texture.h +20 -0
  79. data/include/reflex/view.h +45 -24
  80. data/include/reflex/window.h +11 -14
  81. data/include/reflex.h +3 -0
  82. data/lib/reflex/application.rb +6 -2
  83. data/lib/reflex/body.rb +17 -0
  84. data/lib/reflex/fixture.rb +17 -0
  85. data/lib/reflex/view.rb +16 -1
  86. data/lib/reflex/window.rb +13 -1
  87. data/lib/reflex.rb +2 -0
  88. data/reflex.gemspec +1 -1
  89. data/samples/bats.rb +4 -3
  90. data/samples/checker.rb +4 -3
  91. data/samples/fans.rb +4 -3
  92. data/samples/fps.rb +5 -3
  93. data/samples/grid.rb +5 -4
  94. data/samples/hello.rb +1 -1
  95. data/samples/image.rb +3 -2
  96. data/samples/ios/hello/hello/main.cpp +12 -3
  97. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +376 -123
  98. data/samples/key.rb +5 -4
  99. data/samples/layout.rb +3 -2
  100. data/samples/model.rb +3 -2
  101. data/samples/osx/hello/hello/main.cpp +12 -3
  102. data/samples/osx/hello/hello.xcodeproj/project.pbxproj +375 -120
  103. data/samples/physics.rb +37 -0
  104. data/samples/repl.rb +3 -2
  105. data/samples/shader.rb +4 -4
  106. data/samples/shapes.rb +4 -4
  107. data/samples/text.rb +6 -4
  108. data/samples/tree.rb +5 -4
  109. data/samples/views.rb +3 -2
  110. data/samples/visuals.rb +1 -2
  111. data/src/body.cpp +244 -0
  112. data/src/event.cpp +18 -18
  113. data/src/fixture.cpp +108 -0
  114. data/src/image_view.cpp +1 -1
  115. data/src/ios/native_window.h +2 -0
  116. data/src/ios/native_window.mm +18 -1
  117. data/src/ios/opengl_view.mm +8 -0
  118. data/src/ios/window.mm +24 -3
  119. data/src/ios/window_data.h +3 -3
  120. data/src/osx/native_window.mm +17 -1
  121. data/src/osx/window.mm +24 -3
  122. data/src/osx/window_data.h +3 -3
  123. data/src/physics/Box2D/Box2D.h +68 -0
  124. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.cpp +193 -0
  125. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.h +105 -0
  126. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.cpp +99 -0
  127. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.h +91 -0
  128. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.cpp +138 -0
  129. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.h +74 -0
  130. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.cpp +467 -0
  131. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.h +101 -0
  132. data/src/physics/Box2D/Collision/Shapes/b2Shape.h +101 -0
  133. data/src/physics/Box2D/Collision/b2BroadPhase.cpp +119 -0
  134. data/src/physics/Box2D/Collision/b2BroadPhase.h +257 -0
  135. data/src/physics/Box2D/Collision/b2CollideCircle.cpp +154 -0
  136. data/src/physics/Box2D/Collision/b2CollideEdge.cpp +698 -0
  137. data/src/physics/Box2D/Collision/b2CollidePolygon.cpp +239 -0
  138. data/src/physics/Box2D/Collision/b2Collision.cpp +252 -0
  139. data/src/physics/Box2D/Collision/b2Collision.h +277 -0
  140. data/src/physics/Box2D/Collision/b2Distance.cpp +603 -0
  141. data/src/physics/Box2D/Collision/b2Distance.h +141 -0
  142. data/src/physics/Box2D/Collision/b2DynamicTree.cpp +778 -0
  143. data/src/physics/Box2D/Collision/b2DynamicTree.h +289 -0
  144. data/src/physics/Box2D/Collision/b2TimeOfImpact.cpp +486 -0
  145. data/src/physics/Box2D/Collision/b2TimeOfImpact.h +58 -0
  146. data/src/physics/Box2D/Common/b2BlockAllocator.cpp +215 -0
  147. data/src/physics/Box2D/Common/b2BlockAllocator.h +62 -0
  148. data/src/physics/Box2D/Common/b2Draw.cpp +44 -0
  149. data/src/physics/Box2D/Common/b2Draw.h +86 -0
  150. data/src/physics/Box2D/Common/b2GrowableStack.h +85 -0
  151. data/src/physics/Box2D/Common/b2Math.cpp +94 -0
  152. data/src/physics/Box2D/Common/b2Math.h +720 -0
  153. data/src/physics/Box2D/Common/b2Settings.cpp +44 -0
  154. data/src/physics/Box2D/Common/b2Settings.h +151 -0
  155. data/src/physics/Box2D/Common/b2StackAllocator.cpp +83 -0
  156. data/src/physics/Box2D/Common/b2StackAllocator.h +60 -0
  157. data/src/physics/Box2D/Common/b2Timer.cpp +101 -0
  158. data/src/physics/Box2D/Common/b2Timer.h +50 -0
  159. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +53 -0
  160. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +39 -0
  161. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +53 -0
  162. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +39 -0
  163. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.cpp +52 -0
  164. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.h +39 -0
  165. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.cpp +247 -0
  166. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.h +349 -0
  167. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +838 -0
  168. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.h +95 -0
  169. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +49 -0
  170. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +39 -0
  171. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +49 -0
  172. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +39 -0
  173. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +49 -0
  174. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +38 -0
  175. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +52 -0
  176. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.h +39 -0
  177. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +260 -0
  178. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.h +169 -0
  179. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +251 -0
  180. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.h +119 -0
  181. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.cpp +419 -0
  182. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.h +125 -0
  183. data/src/physics/Box2D/Dynamics/Joints/b2Joint.cpp +211 -0
  184. data/src/physics/Box2D/Dynamics/Joints/b2Joint.h +226 -0
  185. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.cpp +304 -0
  186. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.h +133 -0
  187. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.cpp +222 -0
  188. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.h +129 -0
  189. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +629 -0
  190. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.h +196 -0
  191. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +348 -0
  192. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.h +152 -0
  193. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +502 -0
  194. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.h +204 -0
  195. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.cpp +241 -0
  196. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.h +114 -0
  197. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.cpp +344 -0
  198. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.h +126 -0
  199. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.cpp +419 -0
  200. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.h +210 -0
  201. data/src/physics/Box2D/Dynamics/b2Body.cpp +549 -0
  202. data/src/physics/Box2D/Dynamics/b2Body.h +860 -0
  203. data/src/physics/Box2D/Dynamics/b2ContactManager.cpp +296 -0
  204. data/src/physics/Box2D/Dynamics/b2ContactManager.h +52 -0
  205. data/src/physics/Box2D/Dynamics/b2Fixture.cpp +303 -0
  206. data/src/physics/Box2D/Dynamics/b2Fixture.h +345 -0
  207. data/src/physics/Box2D/Dynamics/b2Island.cpp +539 -0
  208. data/src/physics/Box2D/Dynamics/b2Island.h +93 -0
  209. data/src/physics/Box2D/Dynamics/b2TimeStep.h +70 -0
  210. data/src/physics/Box2D/Dynamics/b2World.cpp +1339 -0
  211. data/src/physics/Box2D/Dynamics/b2World.h +354 -0
  212. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.cpp +36 -0
  213. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.h +155 -0
  214. data/src/physics/Box2D/Rope/b2Rope.cpp +259 -0
  215. data/src/physics/Box2D/Rope/b2Rope.h +115 -0
  216. data/src/style.cpp +2 -2
  217. data/src/view.cpp +217 -17
  218. data/src/window.cpp +25 -15
  219. data/src/world.cpp +206 -0
  220. data/src/world.h +96 -0
  221. data/task/box2d.rake +25 -0
  222. data/test/test_view.rb +5 -5
  223. metadata +125 -3
@@ -0,0 +1,838 @@
1
+ /*
2
+ * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
3
+ *
4
+ * This software is provided 'as-is', without any express or implied
5
+ * warranty. In no event will the authors be held liable for any damages
6
+ * arising from the use of this software.
7
+ * Permission is granted to anyone to use this software for any purpose,
8
+ * including commercial applications, and to alter it and redistribute it
9
+ * freely, subject to the following restrictions:
10
+ * 1. The origin of this software must not be misrepresented; you must not
11
+ * claim that you wrote the original software. If you use this software
12
+ * in a product, an acknowledgment in the product documentation would be
13
+ * appreciated but is not required.
14
+ * 2. Altered source versions must be plainly marked as such, and must not be
15
+ * misrepresented as being the original software.
16
+ * 3. This notice may not be removed or altered from any source distribution.
17
+ */
18
+
19
+ #include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
20
+
21
+ #include <Box2D/Dynamics/Contacts/b2Contact.h>
22
+ #include <Box2D/Dynamics/b2Body.h>
23
+ #include <Box2D/Dynamics/b2Fixture.h>
24
+ #include <Box2D/Dynamics/b2World.h>
25
+ #include <Box2D/Common/b2StackAllocator.h>
26
+
27
+ #define B2_DEBUG_SOLVER 0
28
+
29
+ bool g_blockSolve = true;
30
+
31
+ struct b2ContactPositionConstraint
32
+ {
33
+ b2Vec2 localPoints[b2_maxManifoldPoints];
34
+ b2Vec2 localNormal;
35
+ b2Vec2 localPoint;
36
+ int32 indexA;
37
+ int32 indexB;
38
+ float32 invMassA, invMassB;
39
+ b2Vec2 localCenterA, localCenterB;
40
+ float32 invIA, invIB;
41
+ b2Manifold::Type type;
42
+ float32 radiusA, radiusB;
43
+ int32 pointCount;
44
+ };
45
+
46
+ b2ContactSolver::b2ContactSolver(b2ContactSolverDef* def)
47
+ {
48
+ m_step = def->step;
49
+ m_allocator = def->allocator;
50
+ m_count = def->count;
51
+ m_positionConstraints = (b2ContactPositionConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactPositionConstraint));
52
+ m_velocityConstraints = (b2ContactVelocityConstraint*)m_allocator->Allocate(m_count * sizeof(b2ContactVelocityConstraint));
53
+ m_positions = def->positions;
54
+ m_velocities = def->velocities;
55
+ m_contacts = def->contacts;
56
+
57
+ // Initialize position independent portions of the constraints.
58
+ for (int32 i = 0; i < m_count; ++i)
59
+ {
60
+ b2Contact* contact = m_contacts[i];
61
+
62
+ b2Fixture* fixtureA = contact->m_fixtureA;
63
+ b2Fixture* fixtureB = contact->m_fixtureB;
64
+ b2Shape* shapeA = fixtureA->GetShape();
65
+ b2Shape* shapeB = fixtureB->GetShape();
66
+ float32 radiusA = shapeA->m_radius;
67
+ float32 radiusB = shapeB->m_radius;
68
+ b2Body* bodyA = fixtureA->GetBody();
69
+ b2Body* bodyB = fixtureB->GetBody();
70
+ b2Manifold* manifold = contact->GetManifold();
71
+
72
+ int32 pointCount = manifold->pointCount;
73
+ b2Assert(pointCount > 0);
74
+
75
+ b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
76
+ vc->friction = contact->m_friction;
77
+ vc->restitution = contact->m_restitution;
78
+ vc->tangentSpeed = contact->m_tangentSpeed;
79
+ vc->indexA = bodyA->m_islandIndex;
80
+ vc->indexB = bodyB->m_islandIndex;
81
+ vc->invMassA = bodyA->m_invMass;
82
+ vc->invMassB = bodyB->m_invMass;
83
+ vc->invIA = bodyA->m_invI;
84
+ vc->invIB = bodyB->m_invI;
85
+ vc->contactIndex = i;
86
+ vc->pointCount = pointCount;
87
+ vc->K.SetZero();
88
+ vc->normalMass.SetZero();
89
+
90
+ b2ContactPositionConstraint* pc = m_positionConstraints + i;
91
+ pc->indexA = bodyA->m_islandIndex;
92
+ pc->indexB = bodyB->m_islandIndex;
93
+ pc->invMassA = bodyA->m_invMass;
94
+ pc->invMassB = bodyB->m_invMass;
95
+ pc->localCenterA = bodyA->m_sweep.localCenter;
96
+ pc->localCenterB = bodyB->m_sweep.localCenter;
97
+ pc->invIA = bodyA->m_invI;
98
+ pc->invIB = bodyB->m_invI;
99
+ pc->localNormal = manifold->localNormal;
100
+ pc->localPoint = manifold->localPoint;
101
+ pc->pointCount = pointCount;
102
+ pc->radiusA = radiusA;
103
+ pc->radiusB = radiusB;
104
+ pc->type = manifold->type;
105
+
106
+ for (int32 j = 0; j < pointCount; ++j)
107
+ {
108
+ b2ManifoldPoint* cp = manifold->points + j;
109
+ b2VelocityConstraintPoint* vcp = vc->points + j;
110
+
111
+ if (m_step.warmStarting)
112
+ {
113
+ vcp->normalImpulse = m_step.dtRatio * cp->normalImpulse;
114
+ vcp->tangentImpulse = m_step.dtRatio * cp->tangentImpulse;
115
+ }
116
+ else
117
+ {
118
+ vcp->normalImpulse = 0.0f;
119
+ vcp->tangentImpulse = 0.0f;
120
+ }
121
+
122
+ vcp->rA.SetZero();
123
+ vcp->rB.SetZero();
124
+ vcp->normalMass = 0.0f;
125
+ vcp->tangentMass = 0.0f;
126
+ vcp->velocityBias = 0.0f;
127
+
128
+ pc->localPoints[j] = cp->localPoint;
129
+ }
130
+ }
131
+ }
132
+
133
+ b2ContactSolver::~b2ContactSolver()
134
+ {
135
+ m_allocator->Free(m_velocityConstraints);
136
+ m_allocator->Free(m_positionConstraints);
137
+ }
138
+
139
+ // Initialize position dependent portions of the velocity constraints.
140
+ void b2ContactSolver::InitializeVelocityConstraints()
141
+ {
142
+ for (int32 i = 0; i < m_count; ++i)
143
+ {
144
+ b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
145
+ b2ContactPositionConstraint* pc = m_positionConstraints + i;
146
+
147
+ float32 radiusA = pc->radiusA;
148
+ float32 radiusB = pc->radiusB;
149
+ b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold();
150
+
151
+ int32 indexA = vc->indexA;
152
+ int32 indexB = vc->indexB;
153
+
154
+ float32 mA = vc->invMassA;
155
+ float32 mB = vc->invMassB;
156
+ float32 iA = vc->invIA;
157
+ float32 iB = vc->invIB;
158
+ b2Vec2 localCenterA = pc->localCenterA;
159
+ b2Vec2 localCenterB = pc->localCenterB;
160
+
161
+ b2Vec2 cA = m_positions[indexA].c;
162
+ float32 aA = m_positions[indexA].a;
163
+ b2Vec2 vA = m_velocities[indexA].v;
164
+ float32 wA = m_velocities[indexA].w;
165
+
166
+ b2Vec2 cB = m_positions[indexB].c;
167
+ float32 aB = m_positions[indexB].a;
168
+ b2Vec2 vB = m_velocities[indexB].v;
169
+ float32 wB = m_velocities[indexB].w;
170
+
171
+ b2Assert(manifold->pointCount > 0);
172
+
173
+ b2Transform xfA, xfB;
174
+ xfA.q.Set(aA);
175
+ xfB.q.Set(aB);
176
+ xfA.p = cA - b2Mul(xfA.q, localCenterA);
177
+ xfB.p = cB - b2Mul(xfB.q, localCenterB);
178
+
179
+ b2WorldManifold worldManifold;
180
+ worldManifold.Initialize(manifold, xfA, radiusA, xfB, radiusB);
181
+
182
+ vc->normal = worldManifold.normal;
183
+
184
+ int32 pointCount = vc->pointCount;
185
+ for (int32 j = 0; j < pointCount; ++j)
186
+ {
187
+ b2VelocityConstraintPoint* vcp = vc->points + j;
188
+
189
+ vcp->rA = worldManifold.points[j] - cA;
190
+ vcp->rB = worldManifold.points[j] - cB;
191
+
192
+ float32 rnA = b2Cross(vcp->rA, vc->normal);
193
+ float32 rnB = b2Cross(vcp->rB, vc->normal);
194
+
195
+ float32 kNormal = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
196
+
197
+ vcp->normalMass = kNormal > 0.0f ? 1.0f / kNormal : 0.0f;
198
+
199
+ b2Vec2 tangent = b2Cross(vc->normal, 1.0f);
200
+
201
+ float32 rtA = b2Cross(vcp->rA, tangent);
202
+ float32 rtB = b2Cross(vcp->rB, tangent);
203
+
204
+ float32 kTangent = mA + mB + iA * rtA * rtA + iB * rtB * rtB;
205
+
206
+ vcp->tangentMass = kTangent > 0.0f ? 1.0f / kTangent : 0.0f;
207
+
208
+ // Setup a velocity bias for restitution.
209
+ vcp->velocityBias = 0.0f;
210
+ float32 vRel = b2Dot(vc->normal, vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA));
211
+ if (vRel < -b2_velocityThreshold)
212
+ {
213
+ vcp->velocityBias = -vc->restitution * vRel;
214
+ }
215
+ }
216
+
217
+ // If we have two points, then prepare the block solver.
218
+ if (vc->pointCount == 2 && g_blockSolve)
219
+ {
220
+ b2VelocityConstraintPoint* vcp1 = vc->points + 0;
221
+ b2VelocityConstraintPoint* vcp2 = vc->points + 1;
222
+
223
+ float32 rn1A = b2Cross(vcp1->rA, vc->normal);
224
+ float32 rn1B = b2Cross(vcp1->rB, vc->normal);
225
+ float32 rn2A = b2Cross(vcp2->rA, vc->normal);
226
+ float32 rn2B = b2Cross(vcp2->rB, vc->normal);
227
+
228
+ float32 k11 = mA + mB + iA * rn1A * rn1A + iB * rn1B * rn1B;
229
+ float32 k22 = mA + mB + iA * rn2A * rn2A + iB * rn2B * rn2B;
230
+ float32 k12 = mA + mB + iA * rn1A * rn2A + iB * rn1B * rn2B;
231
+
232
+ // Ensure a reasonable condition number.
233
+ const float32 k_maxConditionNumber = 1000.0f;
234
+ if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12))
235
+ {
236
+ // K is safe to invert.
237
+ vc->K.ex.Set(k11, k12);
238
+ vc->K.ey.Set(k12, k22);
239
+ vc->normalMass = vc->K.GetInverse();
240
+ }
241
+ else
242
+ {
243
+ // The constraints are redundant, just use one.
244
+ // TODO_ERIN use deepest?
245
+ vc->pointCount = 1;
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ void b2ContactSolver::WarmStart()
252
+ {
253
+ // Warm start.
254
+ for (int32 i = 0; i < m_count; ++i)
255
+ {
256
+ b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
257
+
258
+ int32 indexA = vc->indexA;
259
+ int32 indexB = vc->indexB;
260
+ float32 mA = vc->invMassA;
261
+ float32 iA = vc->invIA;
262
+ float32 mB = vc->invMassB;
263
+ float32 iB = vc->invIB;
264
+ int32 pointCount = vc->pointCount;
265
+
266
+ b2Vec2 vA = m_velocities[indexA].v;
267
+ float32 wA = m_velocities[indexA].w;
268
+ b2Vec2 vB = m_velocities[indexB].v;
269
+ float32 wB = m_velocities[indexB].w;
270
+
271
+ b2Vec2 normal = vc->normal;
272
+ b2Vec2 tangent = b2Cross(normal, 1.0f);
273
+
274
+ for (int32 j = 0; j < pointCount; ++j)
275
+ {
276
+ b2VelocityConstraintPoint* vcp = vc->points + j;
277
+ b2Vec2 P = vcp->normalImpulse * normal + vcp->tangentImpulse * tangent;
278
+ wA -= iA * b2Cross(vcp->rA, P);
279
+ vA -= mA * P;
280
+ wB += iB * b2Cross(vcp->rB, P);
281
+ vB += mB * P;
282
+ }
283
+
284
+ m_velocities[indexA].v = vA;
285
+ m_velocities[indexA].w = wA;
286
+ m_velocities[indexB].v = vB;
287
+ m_velocities[indexB].w = wB;
288
+ }
289
+ }
290
+
291
+ void b2ContactSolver::SolveVelocityConstraints()
292
+ {
293
+ for (int32 i = 0; i < m_count; ++i)
294
+ {
295
+ b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
296
+
297
+ int32 indexA = vc->indexA;
298
+ int32 indexB = vc->indexB;
299
+ float32 mA = vc->invMassA;
300
+ float32 iA = vc->invIA;
301
+ float32 mB = vc->invMassB;
302
+ float32 iB = vc->invIB;
303
+ int32 pointCount = vc->pointCount;
304
+
305
+ b2Vec2 vA = m_velocities[indexA].v;
306
+ float32 wA = m_velocities[indexA].w;
307
+ b2Vec2 vB = m_velocities[indexB].v;
308
+ float32 wB = m_velocities[indexB].w;
309
+
310
+ b2Vec2 normal = vc->normal;
311
+ b2Vec2 tangent = b2Cross(normal, 1.0f);
312
+ float32 friction = vc->friction;
313
+
314
+ b2Assert(pointCount == 1 || pointCount == 2);
315
+
316
+ // Solve tangent constraints first because non-penetration is more important
317
+ // than friction.
318
+ for (int32 j = 0; j < pointCount; ++j)
319
+ {
320
+ b2VelocityConstraintPoint* vcp = vc->points + j;
321
+
322
+ // Relative velocity at contact
323
+ b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
324
+
325
+ // Compute tangent force
326
+ float32 vt = b2Dot(dv, tangent) - vc->tangentSpeed;
327
+ float32 lambda = vcp->tangentMass * (-vt);
328
+
329
+ // b2Clamp the accumulated force
330
+ float32 maxFriction = friction * vcp->normalImpulse;
331
+ float32 newImpulse = b2Clamp(vcp->tangentImpulse + lambda, -maxFriction, maxFriction);
332
+ lambda = newImpulse - vcp->tangentImpulse;
333
+ vcp->tangentImpulse = newImpulse;
334
+
335
+ // Apply contact impulse
336
+ b2Vec2 P = lambda * tangent;
337
+
338
+ vA -= mA * P;
339
+ wA -= iA * b2Cross(vcp->rA, P);
340
+
341
+ vB += mB * P;
342
+ wB += iB * b2Cross(vcp->rB, P);
343
+ }
344
+
345
+ // Solve normal constraints
346
+ if (pointCount == 1 || g_blockSolve == false)
347
+ {
348
+ for (int32 i = 0; i < pointCount; ++i)
349
+ {
350
+ b2VelocityConstraintPoint* vcp = vc->points + i;
351
+
352
+ // Relative velocity at contact
353
+ b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
354
+
355
+ // Compute normal impulse
356
+ float32 vn = b2Dot(dv, normal);
357
+ float32 lambda = -vcp->normalMass * (vn - vcp->velocityBias);
358
+
359
+ // b2Clamp the accumulated impulse
360
+ float32 newImpulse = b2Max(vcp->normalImpulse + lambda, 0.0f);
361
+ lambda = newImpulse - vcp->normalImpulse;
362
+ vcp->normalImpulse = newImpulse;
363
+
364
+ // Apply contact impulse
365
+ b2Vec2 P = lambda * normal;
366
+ vA -= mA * P;
367
+ wA -= iA * b2Cross(vcp->rA, P);
368
+
369
+ vB += mB * P;
370
+ wB += iB * b2Cross(vcp->rB, P);
371
+ }
372
+ }
373
+ else
374
+ {
375
+ // Block solver developed in collaboration with Dirk Gregorius (back in 01/07 on Box2D_Lite).
376
+ // Build the mini LCP for this contact patch
377
+ //
378
+ // vn = A * x + b, vn >= 0, , vn >= 0, x >= 0 and vn_i * x_i = 0 with i = 1..2
379
+ //
380
+ // A = J * W * JT and J = ( -n, -r1 x n, n, r2 x n )
381
+ // b = vn0 - velocityBias
382
+ //
383
+ // The system is solved using the "Total enumeration method" (s. Murty). The complementary constraint vn_i * x_i
384
+ // implies that we must have in any solution either vn_i = 0 or x_i = 0. So for the 2D contact problem the cases
385
+ // vn1 = 0 and vn2 = 0, x1 = 0 and x2 = 0, x1 = 0 and vn2 = 0, x2 = 0 and vn1 = 0 need to be tested. The first valid
386
+ // solution that satisfies the problem is chosen.
387
+ //
388
+ // In order to account of the accumulated impulse 'a' (because of the iterative nature of the solver which only requires
389
+ // that the accumulated impulse is clamped and not the incremental impulse) we change the impulse variable (x_i).
390
+ //
391
+ // Substitute:
392
+ //
393
+ // x = a + d
394
+ //
395
+ // a := old total impulse
396
+ // x := new total impulse
397
+ // d := incremental impulse
398
+ //
399
+ // For the current iteration we extend the formula for the incremental impulse
400
+ // to compute the new total impulse:
401
+ //
402
+ // vn = A * d + b
403
+ // = A * (x - a) + b
404
+ // = A * x + b - A * a
405
+ // = A * x + b'
406
+ // b' = b - A * a;
407
+
408
+ b2VelocityConstraintPoint* cp1 = vc->points + 0;
409
+ b2VelocityConstraintPoint* cp2 = vc->points + 1;
410
+
411
+ b2Vec2 a(cp1->normalImpulse, cp2->normalImpulse);
412
+ b2Assert(a.x >= 0.0f && a.y >= 0.0f);
413
+
414
+ // Relative velocity at contact
415
+ b2Vec2 dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
416
+ b2Vec2 dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
417
+
418
+ // Compute normal velocity
419
+ float32 vn1 = b2Dot(dv1, normal);
420
+ float32 vn2 = b2Dot(dv2, normal);
421
+
422
+ b2Vec2 b;
423
+ b.x = vn1 - cp1->velocityBias;
424
+ b.y = vn2 - cp2->velocityBias;
425
+
426
+ // Compute b'
427
+ b -= b2Mul(vc->K, a);
428
+
429
+ const float32 k_errorTol = 1e-3f;
430
+ B2_NOT_USED(k_errorTol);
431
+
432
+ for (;;)
433
+ {
434
+ //
435
+ // Case 1: vn = 0
436
+ //
437
+ // 0 = A * x + b'
438
+ //
439
+ // Solve for x:
440
+ //
441
+ // x = - inv(A) * b'
442
+ //
443
+ b2Vec2 x = - b2Mul(vc->normalMass, b);
444
+
445
+ if (x.x >= 0.0f && x.y >= 0.0f)
446
+ {
447
+ // Get the incremental impulse
448
+ b2Vec2 d = x - a;
449
+
450
+ // Apply incremental impulse
451
+ b2Vec2 P1 = d.x * normal;
452
+ b2Vec2 P2 = d.y * normal;
453
+ vA -= mA * (P1 + P2);
454
+ wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
455
+
456
+ vB += mB * (P1 + P2);
457
+ wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
458
+
459
+ // Accumulate
460
+ cp1->normalImpulse = x.x;
461
+ cp2->normalImpulse = x.y;
462
+
463
+ #if B2_DEBUG_SOLVER == 1
464
+ // Postconditions
465
+ dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
466
+ dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
467
+
468
+ // Compute normal velocity
469
+ vn1 = b2Dot(dv1, normal);
470
+ vn2 = b2Dot(dv2, normal);
471
+
472
+ b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol);
473
+ b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol);
474
+ #endif
475
+ break;
476
+ }
477
+
478
+ //
479
+ // Case 2: vn1 = 0 and x2 = 0
480
+ //
481
+ // 0 = a11 * x1 + a12 * 0 + b1'
482
+ // vn2 = a21 * x1 + a22 * 0 + b2'
483
+ //
484
+ x.x = - cp1->normalMass * b.x;
485
+ x.y = 0.0f;
486
+ vn1 = 0.0f;
487
+ vn2 = vc->K.ex.y * x.x + b.y;
488
+
489
+ if (x.x >= 0.0f && vn2 >= 0.0f)
490
+ {
491
+ // Get the incremental impulse
492
+ b2Vec2 d = x - a;
493
+
494
+ // Apply incremental impulse
495
+ b2Vec2 P1 = d.x * normal;
496
+ b2Vec2 P2 = d.y * normal;
497
+ vA -= mA * (P1 + P2);
498
+ wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
499
+
500
+ vB += mB * (P1 + P2);
501
+ wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
502
+
503
+ // Accumulate
504
+ cp1->normalImpulse = x.x;
505
+ cp2->normalImpulse = x.y;
506
+
507
+ #if B2_DEBUG_SOLVER == 1
508
+ // Postconditions
509
+ dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
510
+
511
+ // Compute normal velocity
512
+ vn1 = b2Dot(dv1, normal);
513
+
514
+ b2Assert(b2Abs(vn1 - cp1->velocityBias) < k_errorTol);
515
+ #endif
516
+ break;
517
+ }
518
+
519
+
520
+ //
521
+ // Case 3: vn2 = 0 and x1 = 0
522
+ //
523
+ // vn1 = a11 * 0 + a12 * x2 + b1'
524
+ // 0 = a21 * 0 + a22 * x2 + b2'
525
+ //
526
+ x.x = 0.0f;
527
+ x.y = - cp2->normalMass * b.y;
528
+ vn1 = vc->K.ey.x * x.y + b.x;
529
+ vn2 = 0.0f;
530
+
531
+ if (x.y >= 0.0f && vn1 >= 0.0f)
532
+ {
533
+ // Resubstitute for the incremental impulse
534
+ b2Vec2 d = x - a;
535
+
536
+ // Apply incremental impulse
537
+ b2Vec2 P1 = d.x * normal;
538
+ b2Vec2 P2 = d.y * normal;
539
+ vA -= mA * (P1 + P2);
540
+ wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
541
+
542
+ vB += mB * (P1 + P2);
543
+ wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
544
+
545
+ // Accumulate
546
+ cp1->normalImpulse = x.x;
547
+ cp2->normalImpulse = x.y;
548
+
549
+ #if B2_DEBUG_SOLVER == 1
550
+ // Postconditions
551
+ dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
552
+
553
+ // Compute normal velocity
554
+ vn2 = b2Dot(dv2, normal);
555
+
556
+ b2Assert(b2Abs(vn2 - cp2->velocityBias) < k_errorTol);
557
+ #endif
558
+ break;
559
+ }
560
+
561
+ //
562
+ // Case 4: x1 = 0 and x2 = 0
563
+ //
564
+ // vn1 = b1
565
+ // vn2 = b2;
566
+ x.x = 0.0f;
567
+ x.y = 0.0f;
568
+ vn1 = b.x;
569
+ vn2 = b.y;
570
+
571
+ if (vn1 >= 0.0f && vn2 >= 0.0f )
572
+ {
573
+ // Resubstitute for the incremental impulse
574
+ b2Vec2 d = x - a;
575
+
576
+ // Apply incremental impulse
577
+ b2Vec2 P1 = d.x * normal;
578
+ b2Vec2 P2 = d.y * normal;
579
+ vA -= mA * (P1 + P2);
580
+ wA -= iA * (b2Cross(cp1->rA, P1) + b2Cross(cp2->rA, P2));
581
+
582
+ vB += mB * (P1 + P2);
583
+ wB += iB * (b2Cross(cp1->rB, P1) + b2Cross(cp2->rB, P2));
584
+
585
+ // Accumulate
586
+ cp1->normalImpulse = x.x;
587
+ cp2->normalImpulse = x.y;
588
+
589
+ break;
590
+ }
591
+
592
+ // No solution, give up. This is hit sometimes, but it doesn't seem to matter.
593
+ break;
594
+ }
595
+ }
596
+
597
+ m_velocities[indexA].v = vA;
598
+ m_velocities[indexA].w = wA;
599
+ m_velocities[indexB].v = vB;
600
+ m_velocities[indexB].w = wB;
601
+ }
602
+ }
603
+
604
+ void b2ContactSolver::StoreImpulses()
605
+ {
606
+ for (int32 i = 0; i < m_count; ++i)
607
+ {
608
+ b2ContactVelocityConstraint* vc = m_velocityConstraints + i;
609
+ b2Manifold* manifold = m_contacts[vc->contactIndex]->GetManifold();
610
+
611
+ for (int32 j = 0; j < vc->pointCount; ++j)
612
+ {
613
+ manifold->points[j].normalImpulse = vc->points[j].normalImpulse;
614
+ manifold->points[j].tangentImpulse = vc->points[j].tangentImpulse;
615
+ }
616
+ }
617
+ }
618
+
619
+ struct b2PositionSolverManifold
620
+ {
621
+ void Initialize(b2ContactPositionConstraint* pc, const b2Transform& xfA, const b2Transform& xfB, int32 index)
622
+ {
623
+ b2Assert(pc->pointCount > 0);
624
+
625
+ switch (pc->type)
626
+ {
627
+ case b2Manifold::e_circles:
628
+ {
629
+ b2Vec2 pointA = b2Mul(xfA, pc->localPoint);
630
+ b2Vec2 pointB = b2Mul(xfB, pc->localPoints[0]);
631
+ normal = pointB - pointA;
632
+ normal.Normalize();
633
+ point = 0.5f * (pointA + pointB);
634
+ separation = b2Dot(pointB - pointA, normal) - pc->radiusA - pc->radiusB;
635
+ }
636
+ break;
637
+
638
+ case b2Manifold::e_faceA:
639
+ {
640
+ normal = b2Mul(xfA.q, pc->localNormal);
641
+ b2Vec2 planePoint = b2Mul(xfA, pc->localPoint);
642
+
643
+ b2Vec2 clipPoint = b2Mul(xfB, pc->localPoints[index]);
644
+ separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB;
645
+ point = clipPoint;
646
+ }
647
+ break;
648
+
649
+ case b2Manifold::e_faceB:
650
+ {
651
+ normal = b2Mul(xfB.q, pc->localNormal);
652
+ b2Vec2 planePoint = b2Mul(xfB, pc->localPoint);
653
+
654
+ b2Vec2 clipPoint = b2Mul(xfA, pc->localPoints[index]);
655
+ separation = b2Dot(clipPoint - planePoint, normal) - pc->radiusA - pc->radiusB;
656
+ point = clipPoint;
657
+
658
+ // Ensure normal points from A to B
659
+ normal = -normal;
660
+ }
661
+ break;
662
+ }
663
+ }
664
+
665
+ b2Vec2 normal;
666
+ b2Vec2 point;
667
+ float32 separation;
668
+ };
669
+
670
+ // Sequential solver.
671
+ bool b2ContactSolver::SolvePositionConstraints()
672
+ {
673
+ float32 minSeparation = 0.0f;
674
+
675
+ for (int32 i = 0; i < m_count; ++i)
676
+ {
677
+ b2ContactPositionConstraint* pc = m_positionConstraints + i;
678
+
679
+ int32 indexA = pc->indexA;
680
+ int32 indexB = pc->indexB;
681
+ b2Vec2 localCenterA = pc->localCenterA;
682
+ float32 mA = pc->invMassA;
683
+ float32 iA = pc->invIA;
684
+ b2Vec2 localCenterB = pc->localCenterB;
685
+ float32 mB = pc->invMassB;
686
+ float32 iB = pc->invIB;
687
+ int32 pointCount = pc->pointCount;
688
+
689
+ b2Vec2 cA = m_positions[indexA].c;
690
+ float32 aA = m_positions[indexA].a;
691
+
692
+ b2Vec2 cB = m_positions[indexB].c;
693
+ float32 aB = m_positions[indexB].a;
694
+
695
+ // Solve normal constraints
696
+ for (int32 j = 0; j < pointCount; ++j)
697
+ {
698
+ b2Transform xfA, xfB;
699
+ xfA.q.Set(aA);
700
+ xfB.q.Set(aB);
701
+ xfA.p = cA - b2Mul(xfA.q, localCenterA);
702
+ xfB.p = cB - b2Mul(xfB.q, localCenterB);
703
+
704
+ b2PositionSolverManifold psm;
705
+ psm.Initialize(pc, xfA, xfB, j);
706
+ b2Vec2 normal = psm.normal;
707
+
708
+ b2Vec2 point = psm.point;
709
+ float32 separation = psm.separation;
710
+
711
+ b2Vec2 rA = point - cA;
712
+ b2Vec2 rB = point - cB;
713
+
714
+ // Track max constraint error.
715
+ minSeparation = b2Min(minSeparation, separation);
716
+
717
+ // Prevent large corrections and allow slop.
718
+ float32 C = b2Clamp(b2_baumgarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f);
719
+
720
+ // Compute the effective mass.
721
+ float32 rnA = b2Cross(rA, normal);
722
+ float32 rnB = b2Cross(rB, normal);
723
+ float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
724
+
725
+ // Compute normal impulse
726
+ float32 impulse = K > 0.0f ? - C / K : 0.0f;
727
+
728
+ b2Vec2 P = impulse * normal;
729
+
730
+ cA -= mA * P;
731
+ aA -= iA * b2Cross(rA, P);
732
+
733
+ cB += mB * P;
734
+ aB += iB * b2Cross(rB, P);
735
+ }
736
+
737
+ m_positions[indexA].c = cA;
738
+ m_positions[indexA].a = aA;
739
+
740
+ m_positions[indexB].c = cB;
741
+ m_positions[indexB].a = aB;
742
+ }
743
+
744
+ // We can't expect minSpeparation >= -b2_linearSlop because we don't
745
+ // push the separation above -b2_linearSlop.
746
+ return minSeparation >= -3.0f * b2_linearSlop;
747
+ }
748
+
749
+ // Sequential position solver for position constraints.
750
+ bool b2ContactSolver::SolveTOIPositionConstraints(int32 toiIndexA, int32 toiIndexB)
751
+ {
752
+ float32 minSeparation = 0.0f;
753
+
754
+ for (int32 i = 0; i < m_count; ++i)
755
+ {
756
+ b2ContactPositionConstraint* pc = m_positionConstraints + i;
757
+
758
+ int32 indexA = pc->indexA;
759
+ int32 indexB = pc->indexB;
760
+ b2Vec2 localCenterA = pc->localCenterA;
761
+ b2Vec2 localCenterB = pc->localCenterB;
762
+ int32 pointCount = pc->pointCount;
763
+
764
+ float32 mA = 0.0f;
765
+ float32 iA = 0.0f;
766
+ if (indexA == toiIndexA || indexA == toiIndexB)
767
+ {
768
+ mA = pc->invMassA;
769
+ iA = pc->invIA;
770
+ }
771
+
772
+ float32 mB = 0.0f;
773
+ float32 iB = 0.;
774
+ if (indexB == toiIndexA || indexB == toiIndexB)
775
+ {
776
+ mB = pc->invMassB;
777
+ iB = pc->invIB;
778
+ }
779
+
780
+ b2Vec2 cA = m_positions[indexA].c;
781
+ float32 aA = m_positions[indexA].a;
782
+
783
+ b2Vec2 cB = m_positions[indexB].c;
784
+ float32 aB = m_positions[indexB].a;
785
+
786
+ // Solve normal constraints
787
+ for (int32 j = 0; j < pointCount; ++j)
788
+ {
789
+ b2Transform xfA, xfB;
790
+ xfA.q.Set(aA);
791
+ xfB.q.Set(aB);
792
+ xfA.p = cA - b2Mul(xfA.q, localCenterA);
793
+ xfB.p = cB - b2Mul(xfB.q, localCenterB);
794
+
795
+ b2PositionSolverManifold psm;
796
+ psm.Initialize(pc, xfA, xfB, j);
797
+ b2Vec2 normal = psm.normal;
798
+
799
+ b2Vec2 point = psm.point;
800
+ float32 separation = psm.separation;
801
+
802
+ b2Vec2 rA = point - cA;
803
+ b2Vec2 rB = point - cB;
804
+
805
+ // Track max constraint error.
806
+ minSeparation = b2Min(minSeparation, separation);
807
+
808
+ // Prevent large corrections and allow slop.
809
+ float32 C = b2Clamp(b2_toiBaugarte * (separation + b2_linearSlop), -b2_maxLinearCorrection, 0.0f);
810
+
811
+ // Compute the effective mass.
812
+ float32 rnA = b2Cross(rA, normal);
813
+ float32 rnB = b2Cross(rB, normal);
814
+ float32 K = mA + mB + iA * rnA * rnA + iB * rnB * rnB;
815
+
816
+ // Compute normal impulse
817
+ float32 impulse = K > 0.0f ? - C / K : 0.0f;
818
+
819
+ b2Vec2 P = impulse * normal;
820
+
821
+ cA -= mA * P;
822
+ aA -= iA * b2Cross(rA, P);
823
+
824
+ cB += mB * P;
825
+ aB += iB * b2Cross(rB, P);
826
+ }
827
+
828
+ m_positions[indexA].c = cA;
829
+ m_positions[indexA].a = aA;
830
+
831
+ m_positions[indexB].c = cB;
832
+ m_positions[indexB].a = aB;
833
+ }
834
+
835
+ // We can't expect minSpeparation >= -b2_linearSlop because we don't
836
+ // push the separation above -b2_linearSlop.
837
+ return minSeparation >= -1.5f * b2_linearSlop;
838
+ }