reflexion 0.1.7 → 0.1.8

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.
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,603 @@
1
+ /*
2
+ * Copyright (c) 2007-2009 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/Collision/b2Distance.h>
20
+ #include <Box2D/Collision/Shapes/b2CircleShape.h>
21
+ #include <Box2D/Collision/Shapes/b2EdgeShape.h>
22
+ #include <Box2D/Collision/Shapes/b2ChainShape.h>
23
+ #include <Box2D/Collision/Shapes/b2PolygonShape.h>
24
+
25
+ // GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.
26
+ int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
27
+
28
+ void b2DistanceProxy::Set(const b2Shape* shape, int32 index)
29
+ {
30
+ switch (shape->GetType())
31
+ {
32
+ case b2Shape::e_circle:
33
+ {
34
+ const b2CircleShape* circle = static_cast<const b2CircleShape*>(shape);
35
+ m_vertices = &circle->m_p;
36
+ m_count = 1;
37
+ m_radius = circle->m_radius;
38
+ }
39
+ break;
40
+
41
+ case b2Shape::e_polygon:
42
+ {
43
+ const b2PolygonShape* polygon = static_cast<const b2PolygonShape*>(shape);
44
+ m_vertices = polygon->m_vertices;
45
+ m_count = polygon->m_count;
46
+ m_radius = polygon->m_radius;
47
+ }
48
+ break;
49
+
50
+ case b2Shape::e_chain:
51
+ {
52
+ const b2ChainShape* chain = static_cast<const b2ChainShape*>(shape);
53
+ b2Assert(0 <= index && index < chain->m_count);
54
+
55
+ m_buffer[0] = chain->m_vertices[index];
56
+ if (index + 1 < chain->m_count)
57
+ {
58
+ m_buffer[1] = chain->m_vertices[index + 1];
59
+ }
60
+ else
61
+ {
62
+ m_buffer[1] = chain->m_vertices[0];
63
+ }
64
+
65
+ m_vertices = m_buffer;
66
+ m_count = 2;
67
+ m_radius = chain->m_radius;
68
+ }
69
+ break;
70
+
71
+ case b2Shape::e_edge:
72
+ {
73
+ const b2EdgeShape* edge = static_cast<const b2EdgeShape*>(shape);
74
+ m_vertices = &edge->m_vertex1;
75
+ m_count = 2;
76
+ m_radius = edge->m_radius;
77
+ }
78
+ break;
79
+
80
+ default:
81
+ b2Assert(false);
82
+ }
83
+ }
84
+
85
+
86
+ struct b2SimplexVertex
87
+ {
88
+ b2Vec2 wA; // support point in proxyA
89
+ b2Vec2 wB; // support point in proxyB
90
+ b2Vec2 w; // wB - wA
91
+ float32 a; // barycentric coordinate for closest point
92
+ int32 indexA; // wA index
93
+ int32 indexB; // wB index
94
+ };
95
+
96
+ struct b2Simplex
97
+ {
98
+ void ReadCache( const b2SimplexCache* cache,
99
+ const b2DistanceProxy* proxyA, const b2Transform& transformA,
100
+ const b2DistanceProxy* proxyB, const b2Transform& transformB)
101
+ {
102
+ b2Assert(cache->count <= 3);
103
+
104
+ // Copy data from cache.
105
+ m_count = cache->count;
106
+ b2SimplexVertex* vertices = &m_v1;
107
+ for (int32 i = 0; i < m_count; ++i)
108
+ {
109
+ b2SimplexVertex* v = vertices + i;
110
+ v->indexA = cache->indexA[i];
111
+ v->indexB = cache->indexB[i];
112
+ b2Vec2 wALocal = proxyA->GetVertex(v->indexA);
113
+ b2Vec2 wBLocal = proxyB->GetVertex(v->indexB);
114
+ v->wA = b2Mul(transformA, wALocal);
115
+ v->wB = b2Mul(transformB, wBLocal);
116
+ v->w = v->wB - v->wA;
117
+ v->a = 0.0f;
118
+ }
119
+
120
+ // Compute the new simplex metric, if it is substantially different than
121
+ // old metric then flush the simplex.
122
+ if (m_count > 1)
123
+ {
124
+ float32 metric1 = cache->metric;
125
+ float32 metric2 = GetMetric();
126
+ if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon)
127
+ {
128
+ // Reset the simplex.
129
+ m_count = 0;
130
+ }
131
+ }
132
+
133
+ // If the cache is empty or invalid ...
134
+ if (m_count == 0)
135
+ {
136
+ b2SimplexVertex* v = vertices + 0;
137
+ v->indexA = 0;
138
+ v->indexB = 0;
139
+ b2Vec2 wALocal = proxyA->GetVertex(0);
140
+ b2Vec2 wBLocal = proxyB->GetVertex(0);
141
+ v->wA = b2Mul(transformA, wALocal);
142
+ v->wB = b2Mul(transformB, wBLocal);
143
+ v->w = v->wB - v->wA;
144
+ v->a = 1.0f;
145
+ m_count = 1;
146
+ }
147
+ }
148
+
149
+ void WriteCache(b2SimplexCache* cache) const
150
+ {
151
+ cache->metric = GetMetric();
152
+ cache->count = uint16(m_count);
153
+ const b2SimplexVertex* vertices = &m_v1;
154
+ for (int32 i = 0; i < m_count; ++i)
155
+ {
156
+ cache->indexA[i] = uint8(vertices[i].indexA);
157
+ cache->indexB[i] = uint8(vertices[i].indexB);
158
+ }
159
+ }
160
+
161
+ b2Vec2 GetSearchDirection() const
162
+ {
163
+ switch (m_count)
164
+ {
165
+ case 1:
166
+ return -m_v1.w;
167
+
168
+ case 2:
169
+ {
170
+ b2Vec2 e12 = m_v2.w - m_v1.w;
171
+ float32 sgn = b2Cross(e12, -m_v1.w);
172
+ if (sgn > 0.0f)
173
+ {
174
+ // Origin is left of e12.
175
+ return b2Cross(1.0f, e12);
176
+ }
177
+ else
178
+ {
179
+ // Origin is right of e12.
180
+ return b2Cross(e12, 1.0f);
181
+ }
182
+ }
183
+
184
+ default:
185
+ b2Assert(false);
186
+ return b2Vec2_zero;
187
+ }
188
+ }
189
+
190
+ b2Vec2 GetClosestPoint() const
191
+ {
192
+ switch (m_count)
193
+ {
194
+ case 0:
195
+ b2Assert(false);
196
+ return b2Vec2_zero;
197
+
198
+ case 1:
199
+ return m_v1.w;
200
+
201
+ case 2:
202
+ return m_v1.a * m_v1.w + m_v2.a * m_v2.w;
203
+
204
+ case 3:
205
+ return b2Vec2_zero;
206
+
207
+ default:
208
+ b2Assert(false);
209
+ return b2Vec2_zero;
210
+ }
211
+ }
212
+
213
+ void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const
214
+ {
215
+ switch (m_count)
216
+ {
217
+ case 0:
218
+ b2Assert(false);
219
+ break;
220
+
221
+ case 1:
222
+ *pA = m_v1.wA;
223
+ *pB = m_v1.wB;
224
+ break;
225
+
226
+ case 2:
227
+ *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA;
228
+ *pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB;
229
+ break;
230
+
231
+ case 3:
232
+ *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA;
233
+ *pB = *pA;
234
+ break;
235
+
236
+ default:
237
+ b2Assert(false);
238
+ break;
239
+ }
240
+ }
241
+
242
+ float32 GetMetric() const
243
+ {
244
+ switch (m_count)
245
+ {
246
+ case 0:
247
+ b2Assert(false);
248
+ return 0.0f;
249
+
250
+ case 1:
251
+ return 0.0f;
252
+
253
+ case 2:
254
+ return b2Distance(m_v1.w, m_v2.w);
255
+
256
+ case 3:
257
+ return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w);
258
+
259
+ default:
260
+ b2Assert(false);
261
+ return 0.0f;
262
+ }
263
+ }
264
+
265
+ void Solve2();
266
+ void Solve3();
267
+
268
+ b2SimplexVertex m_v1, m_v2, m_v3;
269
+ int32 m_count;
270
+ };
271
+
272
+
273
+ // Solve a line segment using barycentric coordinates.
274
+ //
275
+ // p = a1 * w1 + a2 * w2
276
+ // a1 + a2 = 1
277
+ //
278
+ // The vector from the origin to the closest point on the line is
279
+ // perpendicular to the line.
280
+ // e12 = w2 - w1
281
+ // dot(p, e) = 0
282
+ // a1 * dot(w1, e) + a2 * dot(w2, e) = 0
283
+ //
284
+ // 2-by-2 linear system
285
+ // [1 1 ][a1] = [1]
286
+ // [w1.e12 w2.e12][a2] = [0]
287
+ //
288
+ // Define
289
+ // d12_1 = dot(w2, e12)
290
+ // d12_2 = -dot(w1, e12)
291
+ // d12 = d12_1 + d12_2
292
+ //
293
+ // Solution
294
+ // a1 = d12_1 / d12
295
+ // a2 = d12_2 / d12
296
+ void b2Simplex::Solve2()
297
+ {
298
+ b2Vec2 w1 = m_v1.w;
299
+ b2Vec2 w2 = m_v2.w;
300
+ b2Vec2 e12 = w2 - w1;
301
+
302
+ // w1 region
303
+ float32 d12_2 = -b2Dot(w1, e12);
304
+ if (d12_2 <= 0.0f)
305
+ {
306
+ // a2 <= 0, so we clamp it to 0
307
+ m_v1.a = 1.0f;
308
+ m_count = 1;
309
+ return;
310
+ }
311
+
312
+ // w2 region
313
+ float32 d12_1 = b2Dot(w2, e12);
314
+ if (d12_1 <= 0.0f)
315
+ {
316
+ // a1 <= 0, so we clamp it to 0
317
+ m_v2.a = 1.0f;
318
+ m_count = 1;
319
+ m_v1 = m_v2;
320
+ return;
321
+ }
322
+
323
+ // Must be in e12 region.
324
+ float32 inv_d12 = 1.0f / (d12_1 + d12_2);
325
+ m_v1.a = d12_1 * inv_d12;
326
+ m_v2.a = d12_2 * inv_d12;
327
+ m_count = 2;
328
+ }
329
+
330
+ // Possible regions:
331
+ // - points[2]
332
+ // - edge points[0]-points[2]
333
+ // - edge points[1]-points[2]
334
+ // - inside the triangle
335
+ void b2Simplex::Solve3()
336
+ {
337
+ b2Vec2 w1 = m_v1.w;
338
+ b2Vec2 w2 = m_v2.w;
339
+ b2Vec2 w3 = m_v3.w;
340
+
341
+ // Edge12
342
+ // [1 1 ][a1] = [1]
343
+ // [w1.e12 w2.e12][a2] = [0]
344
+ // a3 = 0
345
+ b2Vec2 e12 = w2 - w1;
346
+ float32 w1e12 = b2Dot(w1, e12);
347
+ float32 w2e12 = b2Dot(w2, e12);
348
+ float32 d12_1 = w2e12;
349
+ float32 d12_2 = -w1e12;
350
+
351
+ // Edge13
352
+ // [1 1 ][a1] = [1]
353
+ // [w1.e13 w3.e13][a3] = [0]
354
+ // a2 = 0
355
+ b2Vec2 e13 = w3 - w1;
356
+ float32 w1e13 = b2Dot(w1, e13);
357
+ float32 w3e13 = b2Dot(w3, e13);
358
+ float32 d13_1 = w3e13;
359
+ float32 d13_2 = -w1e13;
360
+
361
+ // Edge23
362
+ // [1 1 ][a2] = [1]
363
+ // [w2.e23 w3.e23][a3] = [0]
364
+ // a1 = 0
365
+ b2Vec2 e23 = w3 - w2;
366
+ float32 w2e23 = b2Dot(w2, e23);
367
+ float32 w3e23 = b2Dot(w3, e23);
368
+ float32 d23_1 = w3e23;
369
+ float32 d23_2 = -w2e23;
370
+
371
+ // Triangle123
372
+ float32 n123 = b2Cross(e12, e13);
373
+
374
+ float32 d123_1 = n123 * b2Cross(w2, w3);
375
+ float32 d123_2 = n123 * b2Cross(w3, w1);
376
+ float32 d123_3 = n123 * b2Cross(w1, w2);
377
+
378
+ // w1 region
379
+ if (d12_2 <= 0.0f && d13_2 <= 0.0f)
380
+ {
381
+ m_v1.a = 1.0f;
382
+ m_count = 1;
383
+ return;
384
+ }
385
+
386
+ // e12
387
+ if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f)
388
+ {
389
+ float32 inv_d12 = 1.0f / (d12_1 + d12_2);
390
+ m_v1.a = d12_1 * inv_d12;
391
+ m_v2.a = d12_2 * inv_d12;
392
+ m_count = 2;
393
+ return;
394
+ }
395
+
396
+ // e13
397
+ if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f)
398
+ {
399
+ float32 inv_d13 = 1.0f / (d13_1 + d13_2);
400
+ m_v1.a = d13_1 * inv_d13;
401
+ m_v3.a = d13_2 * inv_d13;
402
+ m_count = 2;
403
+ m_v2 = m_v3;
404
+ return;
405
+ }
406
+
407
+ // w2 region
408
+ if (d12_1 <= 0.0f && d23_2 <= 0.0f)
409
+ {
410
+ m_v2.a = 1.0f;
411
+ m_count = 1;
412
+ m_v1 = m_v2;
413
+ return;
414
+ }
415
+
416
+ // w3 region
417
+ if (d13_1 <= 0.0f && d23_1 <= 0.0f)
418
+ {
419
+ m_v3.a = 1.0f;
420
+ m_count = 1;
421
+ m_v1 = m_v3;
422
+ return;
423
+ }
424
+
425
+ // e23
426
+ if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f)
427
+ {
428
+ float32 inv_d23 = 1.0f / (d23_1 + d23_2);
429
+ m_v2.a = d23_1 * inv_d23;
430
+ m_v3.a = d23_2 * inv_d23;
431
+ m_count = 2;
432
+ m_v1 = m_v3;
433
+ return;
434
+ }
435
+
436
+ // Must be in triangle123
437
+ float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3);
438
+ m_v1.a = d123_1 * inv_d123;
439
+ m_v2.a = d123_2 * inv_d123;
440
+ m_v3.a = d123_3 * inv_d123;
441
+ m_count = 3;
442
+ }
443
+
444
+ void b2Distance(b2DistanceOutput* output,
445
+ b2SimplexCache* cache,
446
+ const b2DistanceInput* input)
447
+ {
448
+ ++b2_gjkCalls;
449
+
450
+ const b2DistanceProxy* proxyA = &input->proxyA;
451
+ const b2DistanceProxy* proxyB = &input->proxyB;
452
+
453
+ b2Transform transformA = input->transformA;
454
+ b2Transform transformB = input->transformB;
455
+
456
+ // Initialize the simplex.
457
+ b2Simplex simplex;
458
+ simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);
459
+
460
+ // Get simplex vertices as an array.
461
+ b2SimplexVertex* vertices = &simplex.m_v1;
462
+ const int32 k_maxIters = 20;
463
+
464
+ // These store the vertices of the last simplex so that we
465
+ // can check for duplicates and prevent cycling.
466
+ int32 saveA[3], saveB[3];
467
+ int32 saveCount = 0;
468
+
469
+ float32 distanceSqr1 = b2_maxFloat;
470
+ float32 distanceSqr2 = distanceSqr1;
471
+
472
+ // Main iteration loop.
473
+ int32 iter = 0;
474
+ while (iter < k_maxIters)
475
+ {
476
+ // Copy simplex so we can identify duplicates.
477
+ saveCount = simplex.m_count;
478
+ for (int32 i = 0; i < saveCount; ++i)
479
+ {
480
+ saveA[i] = vertices[i].indexA;
481
+ saveB[i] = vertices[i].indexB;
482
+ }
483
+
484
+ switch (simplex.m_count)
485
+ {
486
+ case 1:
487
+ break;
488
+
489
+ case 2:
490
+ simplex.Solve2();
491
+ break;
492
+
493
+ case 3:
494
+ simplex.Solve3();
495
+ break;
496
+
497
+ default:
498
+ b2Assert(false);
499
+ }
500
+
501
+ // If we have 3 points, then the origin is in the corresponding triangle.
502
+ if (simplex.m_count == 3)
503
+ {
504
+ break;
505
+ }
506
+
507
+ // Compute closest point.
508
+ b2Vec2 p = simplex.GetClosestPoint();
509
+ distanceSqr2 = p.LengthSquared();
510
+
511
+ // Ensure progress
512
+ if (distanceSqr2 >= distanceSqr1)
513
+ {
514
+ //break;
515
+ }
516
+ distanceSqr1 = distanceSqr2;
517
+
518
+ // Get search direction.
519
+ b2Vec2 d = simplex.GetSearchDirection();
520
+
521
+ // Ensure the search direction is numerically fit.
522
+ if (d.LengthSquared() < b2_epsilon * b2_epsilon)
523
+ {
524
+ // The origin is probably contained by a line segment
525
+ // or triangle. Thus the shapes are overlapped.
526
+
527
+ // We can't return zero here even though there may be overlap.
528
+ // In case the simplex is a point, segment, or triangle it is difficult
529
+ // to determine if the origin is contained in the CSO or very close to it.
530
+ break;
531
+ }
532
+
533
+ // Compute a tentative new simplex vertex using support points.
534
+ b2SimplexVertex* vertex = vertices + simplex.m_count;
535
+ vertex->indexA = proxyA->GetSupport(b2MulT(transformA.q, -d));
536
+ vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA));
537
+ b2Vec2 wBLocal;
538
+ vertex->indexB = proxyB->GetSupport(b2MulT(transformB.q, d));
539
+ vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB));
540
+ vertex->w = vertex->wB - vertex->wA;
541
+
542
+ // Iteration count is equated to the number of support point calls.
543
+ ++iter;
544
+ ++b2_gjkIters;
545
+
546
+ // Check for duplicate support points. This is the main termination criteria.
547
+ bool duplicate = false;
548
+ for (int32 i = 0; i < saveCount; ++i)
549
+ {
550
+ if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i])
551
+ {
552
+ duplicate = true;
553
+ break;
554
+ }
555
+ }
556
+
557
+ // If we found a duplicate support point we must exit to avoid cycling.
558
+ if (duplicate)
559
+ {
560
+ break;
561
+ }
562
+
563
+ // New vertex is ok and needed.
564
+ ++simplex.m_count;
565
+ }
566
+
567
+ b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter);
568
+
569
+ // Prepare output.
570
+ simplex.GetWitnessPoints(&output->pointA, &output->pointB);
571
+ output->distance = b2Distance(output->pointA, output->pointB);
572
+ output->iterations = iter;
573
+
574
+ // Cache the simplex.
575
+ simplex.WriteCache(cache);
576
+
577
+ // Apply radii if requested.
578
+ if (input->useRadii)
579
+ {
580
+ float32 rA = proxyA->m_radius;
581
+ float32 rB = proxyB->m_radius;
582
+
583
+ if (output->distance > rA + rB && output->distance > b2_epsilon)
584
+ {
585
+ // Shapes are still no overlapped.
586
+ // Move the witness points to the outer surface.
587
+ output->distance -= rA + rB;
588
+ b2Vec2 normal = output->pointB - output->pointA;
589
+ normal.Normalize();
590
+ output->pointA += rA * normal;
591
+ output->pointB -= rB * normal;
592
+ }
593
+ else
594
+ {
595
+ // Shapes are overlapped when radii are considered.
596
+ // Move the witness points to the middle.
597
+ b2Vec2 p = 0.5f * (output->pointA + output->pointB);
598
+ output->pointA = p;
599
+ output->pointB = p;
600
+ output->distance = 0.0f;
601
+ }
602
+ }
603
+ }