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,698 @@
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/b2Collision.h>
20
+ #include <Box2D/Collision/Shapes/b2CircleShape.h>
21
+ #include <Box2D/Collision/Shapes/b2EdgeShape.h>
22
+ #include <Box2D/Collision/Shapes/b2PolygonShape.h>
23
+
24
+
25
+ // Compute contact points for edge versus circle.
26
+ // This accounts for edge connectivity.
27
+ void b2CollideEdgeAndCircle(b2Manifold* manifold,
28
+ const b2EdgeShape* edgeA, const b2Transform& xfA,
29
+ const b2CircleShape* circleB, const b2Transform& xfB)
30
+ {
31
+ manifold->pointCount = 0;
32
+
33
+ // Compute circle in frame of edge
34
+ b2Vec2 Q = b2MulT(xfA, b2Mul(xfB, circleB->m_p));
35
+
36
+ b2Vec2 A = edgeA->m_vertex1, B = edgeA->m_vertex2;
37
+ b2Vec2 e = B - A;
38
+
39
+ // Barycentric coordinates
40
+ float32 u = b2Dot(e, B - Q);
41
+ float32 v = b2Dot(e, Q - A);
42
+
43
+ float32 radius = edgeA->m_radius + circleB->m_radius;
44
+
45
+ b2ContactFeature cf;
46
+ cf.indexB = 0;
47
+ cf.typeB = b2ContactFeature::e_vertex;
48
+
49
+ // Region A
50
+ if (v <= 0.0f)
51
+ {
52
+ b2Vec2 P = A;
53
+ b2Vec2 d = Q - P;
54
+ float32 dd = b2Dot(d, d);
55
+ if (dd > radius * radius)
56
+ {
57
+ return;
58
+ }
59
+
60
+ // Is there an edge connected to A?
61
+ if (edgeA->m_hasVertex0)
62
+ {
63
+ b2Vec2 A1 = edgeA->m_vertex0;
64
+ b2Vec2 B1 = A;
65
+ b2Vec2 e1 = B1 - A1;
66
+ float32 u1 = b2Dot(e1, B1 - Q);
67
+
68
+ // Is the circle in Region AB of the previous edge?
69
+ if (u1 > 0.0f)
70
+ {
71
+ return;
72
+ }
73
+ }
74
+
75
+ cf.indexA = 0;
76
+ cf.typeA = b2ContactFeature::e_vertex;
77
+ manifold->pointCount = 1;
78
+ manifold->type = b2Manifold::e_circles;
79
+ manifold->localNormal.SetZero();
80
+ manifold->localPoint = P;
81
+ manifold->points[0].id.key = 0;
82
+ manifold->points[0].id.cf = cf;
83
+ manifold->points[0].localPoint = circleB->m_p;
84
+ return;
85
+ }
86
+
87
+ // Region B
88
+ if (u <= 0.0f)
89
+ {
90
+ b2Vec2 P = B;
91
+ b2Vec2 d = Q - P;
92
+ float32 dd = b2Dot(d, d);
93
+ if (dd > radius * radius)
94
+ {
95
+ return;
96
+ }
97
+
98
+ // Is there an edge connected to B?
99
+ if (edgeA->m_hasVertex3)
100
+ {
101
+ b2Vec2 B2 = edgeA->m_vertex3;
102
+ b2Vec2 A2 = B;
103
+ b2Vec2 e2 = B2 - A2;
104
+ float32 v2 = b2Dot(e2, Q - A2);
105
+
106
+ // Is the circle in Region AB of the next edge?
107
+ if (v2 > 0.0f)
108
+ {
109
+ return;
110
+ }
111
+ }
112
+
113
+ cf.indexA = 1;
114
+ cf.typeA = b2ContactFeature::e_vertex;
115
+ manifold->pointCount = 1;
116
+ manifold->type = b2Manifold::e_circles;
117
+ manifold->localNormal.SetZero();
118
+ manifold->localPoint = P;
119
+ manifold->points[0].id.key = 0;
120
+ manifold->points[0].id.cf = cf;
121
+ manifold->points[0].localPoint = circleB->m_p;
122
+ return;
123
+ }
124
+
125
+ // Region AB
126
+ float32 den = b2Dot(e, e);
127
+ b2Assert(den > 0.0f);
128
+ b2Vec2 P = (1.0f / den) * (u * A + v * B);
129
+ b2Vec2 d = Q - P;
130
+ float32 dd = b2Dot(d, d);
131
+ if (dd > radius * radius)
132
+ {
133
+ return;
134
+ }
135
+
136
+ b2Vec2 n(-e.y, e.x);
137
+ if (b2Dot(n, Q - A) < 0.0f)
138
+ {
139
+ n.Set(-n.x, -n.y);
140
+ }
141
+ n.Normalize();
142
+
143
+ cf.indexA = 0;
144
+ cf.typeA = b2ContactFeature::e_face;
145
+ manifold->pointCount = 1;
146
+ manifold->type = b2Manifold::e_faceA;
147
+ manifold->localNormal = n;
148
+ manifold->localPoint = A;
149
+ manifold->points[0].id.key = 0;
150
+ manifold->points[0].id.cf = cf;
151
+ manifold->points[0].localPoint = circleB->m_p;
152
+ }
153
+
154
+ // This structure is used to keep track of the best separating axis.
155
+ struct b2EPAxis
156
+ {
157
+ enum Type
158
+ {
159
+ e_unknown,
160
+ e_edgeA,
161
+ e_edgeB
162
+ };
163
+
164
+ Type type;
165
+ int32 index;
166
+ float32 separation;
167
+ };
168
+
169
+ // This holds polygon B expressed in frame A.
170
+ struct b2TempPolygon
171
+ {
172
+ b2Vec2 vertices[b2_maxPolygonVertices];
173
+ b2Vec2 normals[b2_maxPolygonVertices];
174
+ int32 count;
175
+ };
176
+
177
+ // Reference face used for clipping
178
+ struct b2ReferenceFace
179
+ {
180
+ int32 i1, i2;
181
+
182
+ b2Vec2 v1, v2;
183
+
184
+ b2Vec2 normal;
185
+
186
+ b2Vec2 sideNormal1;
187
+ float32 sideOffset1;
188
+
189
+ b2Vec2 sideNormal2;
190
+ float32 sideOffset2;
191
+ };
192
+
193
+ // This class collides and edge and a polygon, taking into account edge adjacency.
194
+ struct b2EPCollider
195
+ {
196
+ void Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
197
+ const b2PolygonShape* polygonB, const b2Transform& xfB);
198
+ b2EPAxis ComputeEdgeSeparation();
199
+ b2EPAxis ComputePolygonSeparation();
200
+
201
+ enum VertexType
202
+ {
203
+ e_isolated,
204
+ e_concave,
205
+ e_convex
206
+ };
207
+
208
+ b2TempPolygon m_polygonB;
209
+
210
+ b2Transform m_xf;
211
+ b2Vec2 m_centroidB;
212
+ b2Vec2 m_v0, m_v1, m_v2, m_v3;
213
+ b2Vec2 m_normal0, m_normal1, m_normal2;
214
+ b2Vec2 m_normal;
215
+ VertexType m_type1, m_type2;
216
+ b2Vec2 m_lowerLimit, m_upperLimit;
217
+ float32 m_radius;
218
+ bool m_front;
219
+ };
220
+
221
+ // Algorithm:
222
+ // 1. Classify v1 and v2
223
+ // 2. Classify polygon centroid as front or back
224
+ // 3. Flip normal if necessary
225
+ // 4. Initialize normal range to [-pi, pi] about face normal
226
+ // 5. Adjust normal range according to adjacent edges
227
+ // 6. Visit each separating axes, only accept axes within the range
228
+ // 7. Return if _any_ axis indicates separation
229
+ // 8. Clip
230
+ void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
231
+ const b2PolygonShape* polygonB, const b2Transform& xfB)
232
+ {
233
+ m_xf = b2MulT(xfA, xfB);
234
+
235
+ m_centroidB = b2Mul(m_xf, polygonB->m_centroid);
236
+
237
+ m_v0 = edgeA->m_vertex0;
238
+ m_v1 = edgeA->m_vertex1;
239
+ m_v2 = edgeA->m_vertex2;
240
+ m_v3 = edgeA->m_vertex3;
241
+
242
+ bool hasVertex0 = edgeA->m_hasVertex0;
243
+ bool hasVertex3 = edgeA->m_hasVertex3;
244
+
245
+ b2Vec2 edge1 = m_v2 - m_v1;
246
+ edge1.Normalize();
247
+ m_normal1.Set(edge1.y, -edge1.x);
248
+ float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1);
249
+ float32 offset0 = 0.0f, offset2 = 0.0f;
250
+ bool convex1 = false, convex2 = false;
251
+
252
+ // Is there a preceding edge?
253
+ if (hasVertex0)
254
+ {
255
+ b2Vec2 edge0 = m_v1 - m_v0;
256
+ edge0.Normalize();
257
+ m_normal0.Set(edge0.y, -edge0.x);
258
+ convex1 = b2Cross(edge0, edge1) >= 0.0f;
259
+ offset0 = b2Dot(m_normal0, m_centroidB - m_v0);
260
+ }
261
+
262
+ // Is there a following edge?
263
+ if (hasVertex3)
264
+ {
265
+ b2Vec2 edge2 = m_v3 - m_v2;
266
+ edge2.Normalize();
267
+ m_normal2.Set(edge2.y, -edge2.x);
268
+ convex2 = b2Cross(edge1, edge2) > 0.0f;
269
+ offset2 = b2Dot(m_normal2, m_centroidB - m_v2);
270
+ }
271
+
272
+ // Determine front or back collision. Determine collision normal limits.
273
+ if (hasVertex0 && hasVertex3)
274
+ {
275
+ if (convex1 && convex2)
276
+ {
277
+ m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
278
+ if (m_front)
279
+ {
280
+ m_normal = m_normal1;
281
+ m_lowerLimit = m_normal0;
282
+ m_upperLimit = m_normal2;
283
+ }
284
+ else
285
+ {
286
+ m_normal = -m_normal1;
287
+ m_lowerLimit = -m_normal1;
288
+ m_upperLimit = -m_normal1;
289
+ }
290
+ }
291
+ else if (convex1)
292
+ {
293
+ m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
294
+ if (m_front)
295
+ {
296
+ m_normal = m_normal1;
297
+ m_lowerLimit = m_normal0;
298
+ m_upperLimit = m_normal1;
299
+ }
300
+ else
301
+ {
302
+ m_normal = -m_normal1;
303
+ m_lowerLimit = -m_normal2;
304
+ m_upperLimit = -m_normal1;
305
+ }
306
+ }
307
+ else if (convex2)
308
+ {
309
+ m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
310
+ if (m_front)
311
+ {
312
+ m_normal = m_normal1;
313
+ m_lowerLimit = m_normal1;
314
+ m_upperLimit = m_normal2;
315
+ }
316
+ else
317
+ {
318
+ m_normal = -m_normal1;
319
+ m_lowerLimit = -m_normal1;
320
+ m_upperLimit = -m_normal0;
321
+ }
322
+ }
323
+ else
324
+ {
325
+ m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
326
+ if (m_front)
327
+ {
328
+ m_normal = m_normal1;
329
+ m_lowerLimit = m_normal1;
330
+ m_upperLimit = m_normal1;
331
+ }
332
+ else
333
+ {
334
+ m_normal = -m_normal1;
335
+ m_lowerLimit = -m_normal2;
336
+ m_upperLimit = -m_normal0;
337
+ }
338
+ }
339
+ }
340
+ else if (hasVertex0)
341
+ {
342
+ if (convex1)
343
+ {
344
+ m_front = offset0 >= 0.0f || offset1 >= 0.0f;
345
+ if (m_front)
346
+ {
347
+ m_normal = m_normal1;
348
+ m_lowerLimit = m_normal0;
349
+ m_upperLimit = -m_normal1;
350
+ }
351
+ else
352
+ {
353
+ m_normal = -m_normal1;
354
+ m_lowerLimit = m_normal1;
355
+ m_upperLimit = -m_normal1;
356
+ }
357
+ }
358
+ else
359
+ {
360
+ m_front = offset0 >= 0.0f && offset1 >= 0.0f;
361
+ if (m_front)
362
+ {
363
+ m_normal = m_normal1;
364
+ m_lowerLimit = m_normal1;
365
+ m_upperLimit = -m_normal1;
366
+ }
367
+ else
368
+ {
369
+ m_normal = -m_normal1;
370
+ m_lowerLimit = m_normal1;
371
+ m_upperLimit = -m_normal0;
372
+ }
373
+ }
374
+ }
375
+ else if (hasVertex3)
376
+ {
377
+ if (convex2)
378
+ {
379
+ m_front = offset1 >= 0.0f || offset2 >= 0.0f;
380
+ if (m_front)
381
+ {
382
+ m_normal = m_normal1;
383
+ m_lowerLimit = -m_normal1;
384
+ m_upperLimit = m_normal2;
385
+ }
386
+ else
387
+ {
388
+ m_normal = -m_normal1;
389
+ m_lowerLimit = -m_normal1;
390
+ m_upperLimit = m_normal1;
391
+ }
392
+ }
393
+ else
394
+ {
395
+ m_front = offset1 >= 0.0f && offset2 >= 0.0f;
396
+ if (m_front)
397
+ {
398
+ m_normal = m_normal1;
399
+ m_lowerLimit = -m_normal1;
400
+ m_upperLimit = m_normal1;
401
+ }
402
+ else
403
+ {
404
+ m_normal = -m_normal1;
405
+ m_lowerLimit = -m_normal2;
406
+ m_upperLimit = m_normal1;
407
+ }
408
+ }
409
+ }
410
+ else
411
+ {
412
+ m_front = offset1 >= 0.0f;
413
+ if (m_front)
414
+ {
415
+ m_normal = m_normal1;
416
+ m_lowerLimit = -m_normal1;
417
+ m_upperLimit = -m_normal1;
418
+ }
419
+ else
420
+ {
421
+ m_normal = -m_normal1;
422
+ m_lowerLimit = m_normal1;
423
+ m_upperLimit = m_normal1;
424
+ }
425
+ }
426
+
427
+ // Get polygonB in frameA
428
+ m_polygonB.count = polygonB->m_count;
429
+ for (int32 i = 0; i < polygonB->m_count; ++i)
430
+ {
431
+ m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]);
432
+ m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]);
433
+ }
434
+
435
+ m_radius = 2.0f * b2_polygonRadius;
436
+
437
+ manifold->pointCount = 0;
438
+
439
+ b2EPAxis edgeAxis = ComputeEdgeSeparation();
440
+
441
+ // If no valid normal can be found than this edge should not collide.
442
+ if (edgeAxis.type == b2EPAxis::e_unknown)
443
+ {
444
+ return;
445
+ }
446
+
447
+ if (edgeAxis.separation > m_radius)
448
+ {
449
+ return;
450
+ }
451
+
452
+ b2EPAxis polygonAxis = ComputePolygonSeparation();
453
+ if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius)
454
+ {
455
+ return;
456
+ }
457
+
458
+ // Use hysteresis for jitter reduction.
459
+ const float32 k_relativeTol = 0.98f;
460
+ const float32 k_absoluteTol = 0.001f;
461
+
462
+ b2EPAxis primaryAxis;
463
+ if (polygonAxis.type == b2EPAxis::e_unknown)
464
+ {
465
+ primaryAxis = edgeAxis;
466
+ }
467
+ else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
468
+ {
469
+ primaryAxis = polygonAxis;
470
+ }
471
+ else
472
+ {
473
+ primaryAxis = edgeAxis;
474
+ }
475
+
476
+ b2ClipVertex ie[2];
477
+ b2ReferenceFace rf;
478
+ if (primaryAxis.type == b2EPAxis::e_edgeA)
479
+ {
480
+ manifold->type = b2Manifold::e_faceA;
481
+
482
+ // Search for the polygon normal that is most anti-parallel to the edge normal.
483
+ int32 bestIndex = 0;
484
+ float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]);
485
+ for (int32 i = 1; i < m_polygonB.count; ++i)
486
+ {
487
+ float32 value = b2Dot(m_normal, m_polygonB.normals[i]);
488
+ if (value < bestValue)
489
+ {
490
+ bestValue = value;
491
+ bestIndex = i;
492
+ }
493
+ }
494
+
495
+ int32 i1 = bestIndex;
496
+ int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;
497
+
498
+ ie[0].v = m_polygonB.vertices[i1];
499
+ ie[0].id.cf.indexA = 0;
500
+ ie[0].id.cf.indexB = static_cast<uint8>(i1);
501
+ ie[0].id.cf.typeA = b2ContactFeature::e_face;
502
+ ie[0].id.cf.typeB = b2ContactFeature::e_vertex;
503
+
504
+ ie[1].v = m_polygonB.vertices[i2];
505
+ ie[1].id.cf.indexA = 0;
506
+ ie[1].id.cf.indexB = static_cast<uint8>(i2);
507
+ ie[1].id.cf.typeA = b2ContactFeature::e_face;
508
+ ie[1].id.cf.typeB = b2ContactFeature::e_vertex;
509
+
510
+ if (m_front)
511
+ {
512
+ rf.i1 = 0;
513
+ rf.i2 = 1;
514
+ rf.v1 = m_v1;
515
+ rf.v2 = m_v2;
516
+ rf.normal = m_normal1;
517
+ }
518
+ else
519
+ {
520
+ rf.i1 = 1;
521
+ rf.i2 = 0;
522
+ rf.v1 = m_v2;
523
+ rf.v2 = m_v1;
524
+ rf.normal = -m_normal1;
525
+ }
526
+ }
527
+ else
528
+ {
529
+ manifold->type = b2Manifold::e_faceB;
530
+
531
+ ie[0].v = m_v1;
532
+ ie[0].id.cf.indexA = 0;
533
+ ie[0].id.cf.indexB = static_cast<uint8>(primaryAxis.index);
534
+ ie[0].id.cf.typeA = b2ContactFeature::e_vertex;
535
+ ie[0].id.cf.typeB = b2ContactFeature::e_face;
536
+
537
+ ie[1].v = m_v2;
538
+ ie[1].id.cf.indexA = 0;
539
+ ie[1].id.cf.indexB = static_cast<uint8>(primaryAxis.index);
540
+ ie[1].id.cf.typeA = b2ContactFeature::e_vertex;
541
+ ie[1].id.cf.typeB = b2ContactFeature::e_face;
542
+
543
+ rf.i1 = primaryAxis.index;
544
+ rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
545
+ rf.v1 = m_polygonB.vertices[rf.i1];
546
+ rf.v2 = m_polygonB.vertices[rf.i2];
547
+ rf.normal = m_polygonB.normals[rf.i1];
548
+ }
549
+
550
+ rf.sideNormal1.Set(rf.normal.y, -rf.normal.x);
551
+ rf.sideNormal2 = -rf.sideNormal1;
552
+ rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1);
553
+ rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2);
554
+
555
+ // Clip incident edge against extruded edge1 side edges.
556
+ b2ClipVertex clipPoints1[2];
557
+ b2ClipVertex clipPoints2[2];
558
+ int32 np;
559
+
560
+ // Clip to box side 1
561
+ np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);
562
+
563
+ if (np < b2_maxManifoldPoints)
564
+ {
565
+ return;
566
+ }
567
+
568
+ // Clip to negative box side 1
569
+ np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);
570
+
571
+ if (np < b2_maxManifoldPoints)
572
+ {
573
+ return;
574
+ }
575
+
576
+ // Now clipPoints2 contains the clipped points.
577
+ if (primaryAxis.type == b2EPAxis::e_edgeA)
578
+ {
579
+ manifold->localNormal = rf.normal;
580
+ manifold->localPoint = rf.v1;
581
+ }
582
+ else
583
+ {
584
+ manifold->localNormal = polygonB->m_normals[rf.i1];
585
+ manifold->localPoint = polygonB->m_vertices[rf.i1];
586
+ }
587
+
588
+ int32 pointCount = 0;
589
+ for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
590
+ {
591
+ float32 separation;
592
+
593
+ separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1);
594
+
595
+ if (separation <= m_radius)
596
+ {
597
+ b2ManifoldPoint* cp = manifold->points + pointCount;
598
+
599
+ if (primaryAxis.type == b2EPAxis::e_edgeA)
600
+ {
601
+ cp->localPoint = b2MulT(m_xf, clipPoints2[i].v);
602
+ cp->id = clipPoints2[i].id;
603
+ }
604
+ else
605
+ {
606
+ cp->localPoint = clipPoints2[i].v;
607
+ cp->id.cf.typeA = clipPoints2[i].id.cf.typeB;
608
+ cp->id.cf.typeB = clipPoints2[i].id.cf.typeA;
609
+ cp->id.cf.indexA = clipPoints2[i].id.cf.indexB;
610
+ cp->id.cf.indexB = clipPoints2[i].id.cf.indexA;
611
+ }
612
+
613
+ ++pointCount;
614
+ }
615
+ }
616
+
617
+ manifold->pointCount = pointCount;
618
+ }
619
+
620
+ b2EPAxis b2EPCollider::ComputeEdgeSeparation()
621
+ {
622
+ b2EPAxis axis;
623
+ axis.type = b2EPAxis::e_edgeA;
624
+ axis.index = m_front ? 0 : 1;
625
+ axis.separation = FLT_MAX;
626
+
627
+ for (int32 i = 0; i < m_polygonB.count; ++i)
628
+ {
629
+ float32 s = b2Dot(m_normal, m_polygonB.vertices[i] - m_v1);
630
+ if (s < axis.separation)
631
+ {
632
+ axis.separation = s;
633
+ }
634
+ }
635
+
636
+ return axis;
637
+ }
638
+
639
+ b2EPAxis b2EPCollider::ComputePolygonSeparation()
640
+ {
641
+ b2EPAxis axis;
642
+ axis.type = b2EPAxis::e_unknown;
643
+ axis.index = -1;
644
+ axis.separation = -FLT_MAX;
645
+
646
+ b2Vec2 perp(-m_normal.y, m_normal.x);
647
+
648
+ for (int32 i = 0; i < m_polygonB.count; ++i)
649
+ {
650
+ b2Vec2 n = -m_polygonB.normals[i];
651
+
652
+ float32 s1 = b2Dot(n, m_polygonB.vertices[i] - m_v1);
653
+ float32 s2 = b2Dot(n, m_polygonB.vertices[i] - m_v2);
654
+ float32 s = b2Min(s1, s2);
655
+
656
+ if (s > m_radius)
657
+ {
658
+ // No collision
659
+ axis.type = b2EPAxis::e_edgeB;
660
+ axis.index = i;
661
+ axis.separation = s;
662
+ return axis;
663
+ }
664
+
665
+ // Adjacency
666
+ if (b2Dot(n, perp) >= 0.0f)
667
+ {
668
+ if (b2Dot(n - m_upperLimit, m_normal) < -b2_angularSlop)
669
+ {
670
+ continue;
671
+ }
672
+ }
673
+ else
674
+ {
675
+ if (b2Dot(n - m_lowerLimit, m_normal) < -b2_angularSlop)
676
+ {
677
+ continue;
678
+ }
679
+ }
680
+
681
+ if (s > axis.separation)
682
+ {
683
+ axis.type = b2EPAxis::e_edgeB;
684
+ axis.index = i;
685
+ axis.separation = s;
686
+ }
687
+ }
688
+
689
+ return axis;
690
+ }
691
+
692
+ void b2CollideEdgeAndPolygon( b2Manifold* manifold,
693
+ const b2EdgeShape* edgeA, const b2Transform& xfA,
694
+ const b2PolygonShape* polygonB, const b2Transform& xfB)
695
+ {
696
+ b2EPCollider collider;
697
+ collider.Collide(manifold, edgeA, xfA, polygonB, xfB);
698
+ }