reflexion 0.1.11 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (333) hide show
  1. checksums.yaml +5 -5
  2. data/.doc/ext/reflex/application.cpp +9 -5
  3. data/.doc/ext/reflex/capture_event.cpp +4 -9
  4. data/.doc/ext/reflex/contact_event.cpp +17 -13
  5. data/.doc/ext/reflex/draw_event.cpp +3 -8
  6. data/.doc/ext/reflex/ellipse_shape.cpp +51 -24
  7. data/.doc/ext/reflex/event.cpp +0 -4
  8. data/.doc/ext/reflex/filter.cpp +81 -0
  9. data/.doc/ext/reflex/focus_event.cpp +9 -13
  10. data/.doc/ext/reflex/frame_event.cpp +47 -14
  11. data/.doc/ext/reflex/image_view.cpp +1 -10
  12. data/.doc/ext/reflex/key_event.cpp +9 -14
  13. data/.doc/ext/reflex/line_shape.cpp +99 -0
  14. data/.doc/ext/reflex/motion_event.cpp +73 -0
  15. data/.doc/ext/reflex/native.cpp +18 -18
  16. data/.doc/ext/reflex/pointer_event.cpp +27 -25
  17. data/.doc/ext/reflex/polygon_shape.cpp +65 -0
  18. data/.doc/ext/reflex/rect_shape.cpp +102 -23
  19. data/.doc/ext/reflex/reflex.cpp +24 -3
  20. data/.doc/ext/reflex/scroll_event.cpp +8 -15
  21. data/.doc/ext/reflex/selector.cpp +43 -15
  22. data/.doc/ext/reflex/shape.cpp +211 -0
  23. data/.doc/ext/reflex/style.cpp +359 -185
  24. data/.doc/ext/reflex/style_length.cpp +163 -35
  25. data/.doc/ext/reflex/timer.cpp +101 -0
  26. data/.doc/ext/reflex/timer_event.cpp +123 -0
  27. data/.doc/ext/reflex/update_event.cpp +12 -8
  28. data/.doc/ext/reflex/view.cpp +548 -144
  29. data/.doc/ext/reflex/wheel_event.cpp +5 -28
  30. data/.doc/ext/reflex/window.cpp +7 -15
  31. data/LICENSE +21 -0
  32. data/README.md +1 -1
  33. data/Rakefile +14 -12
  34. data/VERSION +1 -1
  35. data/ext/reflex/application.cpp +10 -5
  36. data/ext/reflex/capture_event.cpp +4 -9
  37. data/ext/reflex/contact_event.cpp +18 -13
  38. data/ext/reflex/defs.h +5 -2
  39. data/ext/reflex/draw_event.cpp +3 -8
  40. data/ext/reflex/ellipse_shape.cpp +56 -25
  41. data/ext/reflex/event.cpp +0 -4
  42. data/ext/reflex/extconf.rb +1 -2
  43. data/ext/reflex/filter.cpp +86 -0
  44. data/ext/reflex/focus_event.cpp +11 -15
  45. data/ext/reflex/frame_event.cpp +52 -14
  46. data/ext/reflex/image_view.cpp +1 -10
  47. data/ext/reflex/key_event.cpp +9 -14
  48. data/ext/reflex/line_shape.cpp +104 -0
  49. data/ext/reflex/motion_event.cpp +77 -0
  50. data/ext/reflex/native.cpp +18 -18
  51. data/ext/reflex/pointer_event.cpp +27 -25
  52. data/ext/reflex/polygon_shape.cpp +68 -0
  53. data/ext/reflex/rect_shape.cpp +113 -24
  54. data/ext/reflex/reflex.cpp +24 -3
  55. data/ext/reflex/scroll_event.cpp +8 -15
  56. data/ext/reflex/selector.cpp +46 -16
  57. data/ext/reflex/selector.h +130 -0
  58. data/ext/reflex/shape.cpp +231 -0
  59. data/ext/reflex/style.cpp +363 -192
  60. data/ext/reflex/style_length.cpp +164 -37
  61. data/ext/reflex/timer.cpp +108 -0
  62. data/ext/reflex/timer_event.cpp +133 -0
  63. data/ext/reflex/update_event.cpp +13 -8
  64. data/ext/reflex/view.cpp +594 -150
  65. data/ext/reflex/wheel_event.cpp +5 -30
  66. data/ext/reflex/window.cpp +7 -15
  67. data/include/reflex.h +5 -4
  68. data/include/reflex/application.h +2 -0
  69. data/include/reflex/debug.h +22 -0
  70. data/include/reflex/defs.h +45 -2
  71. data/include/reflex/event.h +55 -11
  72. data/include/reflex/exception.h +17 -2
  73. data/include/reflex/filter.h +56 -0
  74. data/include/reflex/image_view.h +1 -1
  75. data/include/reflex/ruby.h +6 -4
  76. data/include/reflex/ruby/application.h +17 -9
  77. data/include/reflex/ruby/event.h +22 -0
  78. data/include/reflex/ruby/filter.h +69 -0
  79. data/include/reflex/ruby/reflex.h +1 -0
  80. data/include/reflex/ruby/selector.h +1 -1
  81. data/include/reflex/ruby/shape.h +140 -0
  82. data/include/reflex/ruby/style.h +1 -1
  83. data/include/reflex/ruby/timer.h +69 -0
  84. data/include/reflex/ruby/view.h +43 -76
  85. data/include/reflex/ruby/window.h +17 -32
  86. data/include/reflex/selector.h +54 -2
  87. data/include/reflex/shape.h +211 -0
  88. data/include/reflex/style.h +136 -76
  89. data/include/reflex/timer.h +73 -0
  90. data/include/reflex/view.h +181 -59
  91. data/include/reflex/window.h +4 -3
  92. data/lib/reflex.rb +13 -6
  93. data/lib/reflex/application.rb +6 -3
  94. data/lib/reflex/button.rb +2 -2
  95. data/lib/reflex/{texture.rb → camera.rb} +2 -2
  96. data/lib/reflex/capture_event.rb +7 -6
  97. data/lib/reflex/contact_event.rb +10 -12
  98. data/lib/reflex/draw_event.rb +6 -1
  99. data/lib/reflex/ellipse_shape.rb +27 -0
  100. data/lib/reflex/filter.rb +18 -0
  101. data/lib/reflex/fixture.rb +4 -0
  102. data/lib/reflex/focus_event.rb +10 -12
  103. data/lib/reflex/frame_event.rb +1 -1
  104. data/lib/reflex/helper.rb +17 -29
  105. data/lib/reflex/key_event.rb +13 -11
  106. data/lib/reflex/line_shape.rb +18 -0
  107. data/lib/reflex/matrix.rb +13 -0
  108. data/lib/reflex/module.rb +4 -19
  109. data/lib/reflex/pointer_event.rb +28 -35
  110. data/lib/reflex/polygon.rb +14 -0
  111. data/lib/reflex/polygon_shape.rb +23 -0
  112. data/lib/reflex/polyline.rb +13 -0
  113. data/lib/reflex/rect_shape.rb +20 -0
  114. data/lib/reflex/reflex.rb +1 -3
  115. data/lib/reflex/scroll_event.rb +1 -1
  116. data/lib/reflex/selector.rb +2 -2
  117. data/lib/reflex/shape.rb +62 -0
  118. data/lib/reflex/style.rb +78 -11
  119. data/lib/reflex/style_length.rb +0 -11
  120. data/lib/reflex/text_view.rb +7 -24
  121. data/lib/reflex/timer.rb +30 -0
  122. data/lib/reflex/timer_event.rb +29 -0
  123. data/lib/reflex/update_event.rb +1 -1
  124. data/lib/reflex/view.rb +127 -32
  125. data/lib/reflex/wheel_event.rb +9 -1
  126. data/lib/reflex/window.rb +29 -9
  127. data/lib/reflexion.rb +23 -7
  128. data/reflex.gemspec +7 -8
  129. data/samples/bats.rb +4 -4
  130. data/samples/camera.rb +32 -0
  131. data/samples/fans.rb +1 -1
  132. data/samples/fps.rb +5 -3
  133. data/samples/hello.rb +4 -6
  134. data/samples/image.rb +5 -4
  135. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +0 -2
  136. data/samples/layout.rb +16 -7
  137. data/samples/model.rb +10 -7
  138. data/samples/physics.rb +22 -20
  139. data/samples/reflexion/breakout.rb +4 -5
  140. data/samples/reflexion/hello.rb +2 -2
  141. data/samples/reflexion/jump_action.rb +191 -0
  142. data/samples/reflexion/noise.rb +23 -0
  143. data/samples/reflexion/paint.rb +7 -6
  144. data/samples/reflexion/physics.rb +15 -8
  145. data/samples/reflexion/pulse.rb +24 -10
  146. data/samples/shader.rb +8 -6
  147. data/samples/shapes.rb +79 -14
  148. data/samples/tree.rb +9 -10
  149. data/samples/views.rb +3 -3
  150. data/samples/visuals.rb +2 -5
  151. data/src/body.cpp +146 -345
  152. data/src/body.h +91 -0
  153. data/src/event.cpp +65 -15
  154. data/src/exception.cpp +13 -3
  155. data/src/filter.cpp +76 -0
  156. data/src/fixture.cpp +164 -39
  157. data/src/fixture.h +85 -0
  158. data/src/image_view.cpp +4 -4
  159. data/src/ios/app_delegate.h +5 -10
  160. data/src/ios/app_delegate.mm +79 -41
  161. data/src/ios/application.h +32 -0
  162. data/src/ios/application.mm +35 -25
  163. data/src/ios/event.mm +8 -4
  164. data/src/ios/reflex.mm +0 -7
  165. data/src/ios/view_controller.h +37 -0
  166. data/src/ios/view_controller.mm +424 -0
  167. data/src/ios/window.h +40 -0
  168. data/src/ios/window.mm +59 -250
  169. data/src/osx/app_delegate.h +5 -10
  170. data/src/osx/app_delegate.mm +52 -55
  171. data/src/osx/application.h +32 -0
  172. data/src/osx/application.mm +44 -39
  173. data/src/osx/native_window.h +0 -15
  174. data/src/osx/native_window.mm +127 -127
  175. data/src/osx/opengl_view.h +0 -2
  176. data/src/osx/opengl_view.mm +12 -3
  177. data/src/osx/reflex.mm +0 -9
  178. data/src/osx/window.h +42 -0
  179. data/src/osx/window.mm +45 -252
  180. data/src/selector.cpp +232 -7
  181. data/src/selector.h +52 -0
  182. data/src/shape.cpp +1191 -0
  183. data/src/shape.h +61 -0
  184. data/src/style.cpp +573 -376
  185. data/src/style.h +39 -0
  186. data/src/timer.cpp +288 -0
  187. data/src/timer.h +55 -0
  188. data/src/view.cpp +1624 -984
  189. data/src/view.h +56 -0
  190. data/src/win32/window.cpp +3 -4
  191. data/src/window.cpp +302 -20
  192. data/src/window.h +94 -0
  193. data/src/world.cpp +112 -111
  194. data/src/world.h +34 -53
  195. data/task/box2d.rake +31 -10
  196. data/test/test_capture_event.rb +8 -6
  197. data/test/test_pointer_event.rb +130 -0
  198. data/test/test_selector.rb +1 -1
  199. data/test/test_shape.rb +71 -0
  200. data/test/test_style.rb +77 -11
  201. data/test/test_style_length.rb +42 -13
  202. data/test/test_view.rb +138 -14
  203. metadata +118 -202
  204. data/.doc/ext/reflex/arc_shape.cpp +0 -89
  205. data/.doc/ext/reflex/body.cpp +0 -299
  206. data/.doc/ext/reflex/fixture.cpp +0 -101
  207. data/.doc/ext/reflex/shape_view.cpp +0 -153
  208. data/ext/reflex/arc_shape.cpp +0 -94
  209. data/ext/reflex/body.cpp +0 -328
  210. data/ext/reflex/fixture.cpp +0 -108
  211. data/ext/reflex/shape_view.cpp +0 -161
  212. data/include/reflex/bitmap.h +0 -20
  213. data/include/reflex/body.h +0 -128
  214. data/include/reflex/bounds.h +0 -20
  215. data/include/reflex/color.h +0 -20
  216. data/include/reflex/color_space.h +0 -20
  217. data/include/reflex/fixture.h +0 -117
  218. data/include/reflex/font.h +0 -20
  219. data/include/reflex/image.h +0 -20
  220. data/include/reflex/matrix.h +0 -20
  221. data/include/reflex/painter.h +0 -20
  222. data/include/reflex/point.h +0 -24
  223. data/include/reflex/ruby/body.h +0 -41
  224. data/include/reflex/ruby/fixture.h +0 -41
  225. data/include/reflex/ruby/shape_view.h +0 -96
  226. data/include/reflex/shader.h +0 -20
  227. data/include/reflex/shape_view.h +0 -146
  228. data/include/reflex/texture.h +0 -20
  229. data/lib/reflex/body.rb +0 -22
  230. data/lib/reflex/flags.rb +0 -18
  231. data/lib/reflex/shape_view.rb +0 -25
  232. data/src/ios/application_data.h +0 -45
  233. data/src/ios/native_window.h +0 -39
  234. data/src/ios/native_window.mm +0 -224
  235. data/src/ios/opengl_view.h +0 -13
  236. data/src/ios/opengl_view.mm +0 -139
  237. data/src/ios/window_data.h +0 -75
  238. data/src/osx/application_data.h +0 -45
  239. data/src/osx/window_data.h +0 -75
  240. data/src/physics/Box2D/Box2D.h +0 -68
  241. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.cpp +0 -193
  242. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.h +0 -105
  243. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.cpp +0 -99
  244. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.h +0 -91
  245. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.cpp +0 -138
  246. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.h +0 -74
  247. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.cpp +0 -467
  248. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.h +0 -101
  249. data/src/physics/Box2D/Collision/Shapes/b2Shape.h +0 -101
  250. data/src/physics/Box2D/Collision/b2BroadPhase.cpp +0 -119
  251. data/src/physics/Box2D/Collision/b2BroadPhase.h +0 -257
  252. data/src/physics/Box2D/Collision/b2CollideCircle.cpp +0 -154
  253. data/src/physics/Box2D/Collision/b2CollideEdge.cpp +0 -698
  254. data/src/physics/Box2D/Collision/b2CollidePolygon.cpp +0 -239
  255. data/src/physics/Box2D/Collision/b2Collision.cpp +0 -252
  256. data/src/physics/Box2D/Collision/b2Collision.h +0 -277
  257. data/src/physics/Box2D/Collision/b2Distance.cpp +0 -603
  258. data/src/physics/Box2D/Collision/b2Distance.h +0 -141
  259. data/src/physics/Box2D/Collision/b2DynamicTree.cpp +0 -778
  260. data/src/physics/Box2D/Collision/b2DynamicTree.h +0 -289
  261. data/src/physics/Box2D/Collision/b2TimeOfImpact.cpp +0 -486
  262. data/src/physics/Box2D/Collision/b2TimeOfImpact.h +0 -58
  263. data/src/physics/Box2D/Common/b2BlockAllocator.cpp +0 -215
  264. data/src/physics/Box2D/Common/b2BlockAllocator.h +0 -62
  265. data/src/physics/Box2D/Common/b2Draw.cpp +0 -44
  266. data/src/physics/Box2D/Common/b2Draw.h +0 -86
  267. data/src/physics/Box2D/Common/b2GrowableStack.h +0 -85
  268. data/src/physics/Box2D/Common/b2Math.cpp +0 -94
  269. data/src/physics/Box2D/Common/b2Math.h +0 -720
  270. data/src/physics/Box2D/Common/b2Settings.cpp +0 -44
  271. data/src/physics/Box2D/Common/b2Settings.h +0 -151
  272. data/src/physics/Box2D/Common/b2StackAllocator.cpp +0 -83
  273. data/src/physics/Box2D/Common/b2StackAllocator.h +0 -60
  274. data/src/physics/Box2D/Common/b2Timer.cpp +0 -101
  275. data/src/physics/Box2D/Common/b2Timer.h +0 -50
  276. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +0 -53
  277. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +0 -39
  278. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +0 -53
  279. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +0 -39
  280. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.cpp +0 -52
  281. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.h +0 -39
  282. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.cpp +0 -247
  283. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.h +0 -349
  284. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +0 -838
  285. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.h +0 -95
  286. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +0 -49
  287. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +0 -39
  288. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +0 -49
  289. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +0 -39
  290. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +0 -49
  291. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +0 -38
  292. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +0 -52
  293. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.h +0 -39
  294. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +0 -260
  295. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.h +0 -169
  296. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +0 -251
  297. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.h +0 -119
  298. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.cpp +0 -419
  299. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.h +0 -125
  300. data/src/physics/Box2D/Dynamics/Joints/b2Joint.cpp +0 -211
  301. data/src/physics/Box2D/Dynamics/Joints/b2Joint.h +0 -226
  302. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.cpp +0 -304
  303. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.h +0 -133
  304. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.cpp +0 -222
  305. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.h +0 -129
  306. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +0 -629
  307. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.h +0 -196
  308. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +0 -348
  309. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.h +0 -152
  310. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +0 -502
  311. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.h +0 -204
  312. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.cpp +0 -241
  313. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.h +0 -114
  314. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.cpp +0 -344
  315. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.h +0 -126
  316. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.cpp +0 -419
  317. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.h +0 -210
  318. data/src/physics/Box2D/Dynamics/b2Body.cpp +0 -549
  319. data/src/physics/Box2D/Dynamics/b2Body.h +0 -860
  320. data/src/physics/Box2D/Dynamics/b2ContactManager.cpp +0 -296
  321. data/src/physics/Box2D/Dynamics/b2ContactManager.h +0 -52
  322. data/src/physics/Box2D/Dynamics/b2Fixture.cpp +0 -303
  323. data/src/physics/Box2D/Dynamics/b2Fixture.h +0 -345
  324. data/src/physics/Box2D/Dynamics/b2Island.cpp +0 -539
  325. data/src/physics/Box2D/Dynamics/b2Island.h +0 -93
  326. data/src/physics/Box2D/Dynamics/b2TimeStep.h +0 -70
  327. data/src/physics/Box2D/Dynamics/b2World.cpp +0 -1339
  328. data/src/physics/Box2D/Dynamics/b2World.h +0 -354
  329. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.cpp +0 -36
  330. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.h +0 -155
  331. data/src/physics/Box2D/Rope/b2Rope.cpp +0 -259
  332. data/src/physics/Box2D/Rope/b2Rope.h +0 -115
  333. data/src/shape_view.cpp +0 -306
@@ -1,349 +0,0 @@
1
- /*
2
- * Copyright (c) 2006-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
- #ifndef B2_CONTACT_H
20
- #define B2_CONTACT_H
21
-
22
- #include <Box2D/Common/b2Math.h>
23
- #include <Box2D/Collision/b2Collision.h>
24
- #include <Box2D/Collision/Shapes/b2Shape.h>
25
- #include <Box2D/Dynamics/b2Fixture.h>
26
-
27
- class b2Body;
28
- class b2Contact;
29
- class b2Fixture;
30
- class b2World;
31
- class b2BlockAllocator;
32
- class b2StackAllocator;
33
- class b2ContactListener;
34
-
35
- /// Friction mixing law. The idea is to allow either fixture to drive the restitution to zero.
36
- /// For example, anything slides on ice.
37
- inline float32 b2MixFriction(float32 friction1, float32 friction2)
38
- {
39
- return b2Sqrt(friction1 * friction2);
40
- }
41
-
42
- /// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.
43
- /// For example, a superball bounces on anything.
44
- inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
45
- {
46
- return restitution1 > restitution2 ? restitution1 : restitution2;
47
- }
48
-
49
- typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA,
50
- b2Fixture* fixtureB, int32 indexB,
51
- b2BlockAllocator* allocator);
52
- typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
53
-
54
- struct b2ContactRegister
55
- {
56
- b2ContactCreateFcn* createFcn;
57
- b2ContactDestroyFcn* destroyFcn;
58
- bool primary;
59
- };
60
-
61
- /// A contact edge is used to connect bodies and contacts together
62
- /// in a contact graph where each body is a node and each contact
63
- /// is an edge. A contact edge belongs to a doubly linked list
64
- /// maintained in each attached body. Each contact has two contact
65
- /// nodes, one for each attached body.
66
- struct b2ContactEdge
67
- {
68
- b2Body* other; ///< provides quick access to the other body attached.
69
- b2Contact* contact; ///< the contact
70
- b2ContactEdge* prev; ///< the previous contact edge in the body's contact list
71
- b2ContactEdge* next; ///< the next contact edge in the body's contact list
72
- };
73
-
74
- /// The class manages contact between two shapes. A contact exists for each overlapping
75
- /// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
76
- /// that has no contact points.
77
- class b2Contact
78
- {
79
- public:
80
-
81
- /// Get the contact manifold. Do not modify the manifold unless you understand the
82
- /// internals of Box2D.
83
- b2Manifold* GetManifold();
84
- const b2Manifold* GetManifold() const;
85
-
86
- /// Get the world manifold.
87
- void GetWorldManifold(b2WorldManifold* worldManifold) const;
88
-
89
- /// Is this contact touching?
90
- bool IsTouching() const;
91
-
92
- /// Enable/disable this contact. This can be used inside the pre-solve
93
- /// contact listener. The contact is only disabled for the current
94
- /// time step (or sub-step in continuous collisions).
95
- void SetEnabled(bool flag);
96
-
97
- /// Has this contact been disabled?
98
- bool IsEnabled() const;
99
-
100
- /// Get the next contact in the world's contact list.
101
- b2Contact* GetNext();
102
- const b2Contact* GetNext() const;
103
-
104
- /// Get fixture A in this contact.
105
- b2Fixture* GetFixtureA();
106
- const b2Fixture* GetFixtureA() const;
107
-
108
- /// Get the child primitive index for fixture A.
109
- int32 GetChildIndexA() const;
110
-
111
- /// Get fixture B in this contact.
112
- b2Fixture* GetFixtureB();
113
- const b2Fixture* GetFixtureB() const;
114
-
115
- /// Get the child primitive index for fixture B.
116
- int32 GetChildIndexB() const;
117
-
118
- /// Override the default friction mixture. You can call this in b2ContactListener::PreSolve.
119
- /// This value persists until set or reset.
120
- void SetFriction(float32 friction);
121
-
122
- /// Get the friction.
123
- float32 GetFriction() const;
124
-
125
- /// Reset the friction mixture to the default value.
126
- void ResetFriction();
127
-
128
- /// Override the default restitution mixture. You can call this in b2ContactListener::PreSolve.
129
- /// The value persists until you set or reset.
130
- void SetRestitution(float32 restitution);
131
-
132
- /// Get the restitution.
133
- float32 GetRestitution() const;
134
-
135
- /// Reset the restitution to the default value.
136
- void ResetRestitution();
137
-
138
- /// Set the desired tangent speed for a conveyor belt behavior. In meters per second.
139
- void SetTangentSpeed(float32 speed);
140
-
141
- /// Get the desired tangent speed. In meters per second.
142
- float32 GetTangentSpeed() const;
143
-
144
- /// Evaluate this contact with your own manifold and transforms.
145
- virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
146
-
147
- protected:
148
- friend class b2ContactManager;
149
- friend class b2World;
150
- friend class b2ContactSolver;
151
- friend class b2Body;
152
- friend class b2Fixture;
153
-
154
- // Flags stored in m_flags
155
- enum
156
- {
157
- // Used when crawling contact graph when forming islands.
158
- e_islandFlag = 0x0001,
159
-
160
- // Set when the shapes are touching.
161
- e_touchingFlag = 0x0002,
162
-
163
- // This contact can be disabled (by user)
164
- e_enabledFlag = 0x0004,
165
-
166
- // This contact needs filtering because a fixture filter was changed.
167
- e_filterFlag = 0x0008,
168
-
169
- // This bullet contact had a TOI event
170
- e_bulletHitFlag = 0x0010,
171
-
172
- // This contact has a valid TOI in m_toi
173
- e_toiFlag = 0x0020
174
- };
175
-
176
- /// Flag this contact for filtering. Filtering will occur the next time step.
177
- void FlagForFiltering();
178
-
179
- static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
180
- b2Shape::Type typeA, b2Shape::Type typeB);
181
- static void InitializeRegisters();
182
- static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
183
- static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
184
- static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
185
-
186
- b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
187
- b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
188
- virtual ~b2Contact() {}
189
-
190
- void Update(b2ContactListener* listener);
191
-
192
- static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
193
- static bool s_initialized;
194
-
195
- uint32 m_flags;
196
-
197
- // World pool and list pointers.
198
- b2Contact* m_prev;
199
- b2Contact* m_next;
200
-
201
- // Nodes for connecting bodies.
202
- b2ContactEdge m_nodeA;
203
- b2ContactEdge m_nodeB;
204
-
205
- b2Fixture* m_fixtureA;
206
- b2Fixture* m_fixtureB;
207
-
208
- int32 m_indexA;
209
- int32 m_indexB;
210
-
211
- b2Manifold m_manifold;
212
-
213
- int32 m_toiCount;
214
- float32 m_toi;
215
-
216
- float32 m_friction;
217
- float32 m_restitution;
218
-
219
- float32 m_tangentSpeed;
220
- };
221
-
222
- inline b2Manifold* b2Contact::GetManifold()
223
- {
224
- return &m_manifold;
225
- }
226
-
227
- inline const b2Manifold* b2Contact::GetManifold() const
228
- {
229
- return &m_manifold;
230
- }
231
-
232
- inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
233
- {
234
- const b2Body* bodyA = m_fixtureA->GetBody();
235
- const b2Body* bodyB = m_fixtureB->GetBody();
236
- const b2Shape* shapeA = m_fixtureA->GetShape();
237
- const b2Shape* shapeB = m_fixtureB->GetShape();
238
-
239
- worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
240
- }
241
-
242
- inline void b2Contact::SetEnabled(bool flag)
243
- {
244
- if (flag)
245
- {
246
- m_flags |= e_enabledFlag;
247
- }
248
- else
249
- {
250
- m_flags &= ~e_enabledFlag;
251
- }
252
- }
253
-
254
- inline bool b2Contact::IsEnabled() const
255
- {
256
- return (m_flags & e_enabledFlag) == e_enabledFlag;
257
- }
258
-
259
- inline bool b2Contact::IsTouching() const
260
- {
261
- return (m_flags & e_touchingFlag) == e_touchingFlag;
262
- }
263
-
264
- inline b2Contact* b2Contact::GetNext()
265
- {
266
- return m_next;
267
- }
268
-
269
- inline const b2Contact* b2Contact::GetNext() const
270
- {
271
- return m_next;
272
- }
273
-
274
- inline b2Fixture* b2Contact::GetFixtureA()
275
- {
276
- return m_fixtureA;
277
- }
278
-
279
- inline const b2Fixture* b2Contact::GetFixtureA() const
280
- {
281
- return m_fixtureA;
282
- }
283
-
284
- inline b2Fixture* b2Contact::GetFixtureB()
285
- {
286
- return m_fixtureB;
287
- }
288
-
289
- inline int32 b2Contact::GetChildIndexA() const
290
- {
291
- return m_indexA;
292
- }
293
-
294
- inline const b2Fixture* b2Contact::GetFixtureB() const
295
- {
296
- return m_fixtureB;
297
- }
298
-
299
- inline int32 b2Contact::GetChildIndexB() const
300
- {
301
- return m_indexB;
302
- }
303
-
304
- inline void b2Contact::FlagForFiltering()
305
- {
306
- m_flags |= e_filterFlag;
307
- }
308
-
309
- inline void b2Contact::SetFriction(float32 friction)
310
- {
311
- m_friction = friction;
312
- }
313
-
314
- inline float32 b2Contact::GetFriction() const
315
- {
316
- return m_friction;
317
- }
318
-
319
- inline void b2Contact::ResetFriction()
320
- {
321
- m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
322
- }
323
-
324
- inline void b2Contact::SetRestitution(float32 restitution)
325
- {
326
- m_restitution = restitution;
327
- }
328
-
329
- inline float32 b2Contact::GetRestitution() const
330
- {
331
- return m_restitution;
332
- }
333
-
334
- inline void b2Contact::ResetRestitution()
335
- {
336
- m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
337
- }
338
-
339
- inline void b2Contact::SetTangentSpeed(float32 speed)
340
- {
341
- m_tangentSpeed = speed;
342
- }
343
-
344
- inline float32 b2Contact::GetTangentSpeed() const
345
- {
346
- return m_tangentSpeed;
347
- }
348
-
349
- #endif
@@ -1,838 +0,0 @@
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
- }