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,141 +0,0 @@
1
-
2
- /*
3
- * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
4
- *
5
- * This software is provided 'as-is', without any express or implied
6
- * warranty. In no event will the authors be held liable for any damages
7
- * arising from the use of this software.
8
- * Permission is granted to anyone to use this software for any purpose,
9
- * including commercial applications, and to alter it and redistribute it
10
- * freely, subject to the following restrictions:
11
- * 1. The origin of this software must not be misrepresented; you must not
12
- * claim that you wrote the original software. If you use this software
13
- * in a product, an acknowledgment in the product documentation would be
14
- * appreciated but is not required.
15
- * 2. Altered source versions must be plainly marked as such, and must not be
16
- * misrepresented as being the original software.
17
- * 3. This notice may not be removed or altered from any source distribution.
18
- */
19
-
20
- #ifndef B2_DISTANCE_H
21
- #define B2_DISTANCE_H
22
-
23
- #include <Box2D/Common/b2Math.h>
24
-
25
- class b2Shape;
26
-
27
- /// A distance proxy is used by the GJK algorithm.
28
- /// It encapsulates any shape.
29
- struct b2DistanceProxy
30
- {
31
- b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {}
32
-
33
- /// Initialize the proxy using the given shape. The shape
34
- /// must remain in scope while the proxy is in use.
35
- void Set(const b2Shape* shape, int32 index);
36
-
37
- /// Get the supporting vertex index in the given direction.
38
- int32 GetSupport(const b2Vec2& d) const;
39
-
40
- /// Get the supporting vertex in the given direction.
41
- const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
42
-
43
- /// Get the vertex count.
44
- int32 GetVertexCount() const;
45
-
46
- /// Get a vertex by index. Used by b2Distance.
47
- const b2Vec2& GetVertex(int32 index) const;
48
-
49
- b2Vec2 m_buffer[2];
50
- const b2Vec2* m_vertices;
51
- int32 m_count;
52
- float32 m_radius;
53
- };
54
-
55
- /// Used to warm start b2Distance.
56
- /// Set count to zero on first call.
57
- struct b2SimplexCache
58
- {
59
- float32 metric; ///< length or area
60
- uint16 count;
61
- uint8 indexA[3]; ///< vertices on shape A
62
- uint8 indexB[3]; ///< vertices on shape B
63
- };
64
-
65
- /// Input for b2Distance.
66
- /// You have to option to use the shape radii
67
- /// in the computation. Even
68
- struct b2DistanceInput
69
- {
70
- b2DistanceProxy proxyA;
71
- b2DistanceProxy proxyB;
72
- b2Transform transformA;
73
- b2Transform transformB;
74
- bool useRadii;
75
- };
76
-
77
- /// Output for b2Distance.
78
- struct b2DistanceOutput
79
- {
80
- b2Vec2 pointA; ///< closest point on shapeA
81
- b2Vec2 pointB; ///< closest point on shapeB
82
- float32 distance;
83
- int32 iterations; ///< number of GJK iterations used
84
- };
85
-
86
- /// Compute the closest points between two shapes. Supports any combination of:
87
- /// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.
88
- /// On the first call set b2SimplexCache.count to zero.
89
- void b2Distance(b2DistanceOutput* output,
90
- b2SimplexCache* cache,
91
- const b2DistanceInput* input);
92
-
93
-
94
- //////////////////////////////////////////////////////////////////////////
95
-
96
- inline int32 b2DistanceProxy::GetVertexCount() const
97
- {
98
- return m_count;
99
- }
100
-
101
- inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const
102
- {
103
- b2Assert(0 <= index && index < m_count);
104
- return m_vertices[index];
105
- }
106
-
107
- inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const
108
- {
109
- int32 bestIndex = 0;
110
- float32 bestValue = b2Dot(m_vertices[0], d);
111
- for (int32 i = 1; i < m_count; ++i)
112
- {
113
- float32 value = b2Dot(m_vertices[i], d);
114
- if (value > bestValue)
115
- {
116
- bestIndex = i;
117
- bestValue = value;
118
- }
119
- }
120
-
121
- return bestIndex;
122
- }
123
-
124
- inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const
125
- {
126
- int32 bestIndex = 0;
127
- float32 bestValue = b2Dot(m_vertices[0], d);
128
- for (int32 i = 1; i < m_count; ++i)
129
- {
130
- float32 value = b2Dot(m_vertices[i], d);
131
- if (value > bestValue)
132
- {
133
- bestIndex = i;
134
- bestValue = value;
135
- }
136
- }
137
-
138
- return m_vertices[bestIndex];
139
- }
140
-
141
- #endif
@@ -1,778 +0,0 @@
1
- /*
2
- * Copyright (c) 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/b2DynamicTree.h>
20
- #include <string.h>
21
-
22
- b2DynamicTree::b2DynamicTree()
23
- {
24
- m_root = b2_nullNode;
25
-
26
- m_nodeCapacity = 16;
27
- m_nodeCount = 0;
28
- m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
29
- memset(m_nodes, 0, m_nodeCapacity * sizeof(b2TreeNode));
30
-
31
- // Build a linked list for the free list.
32
- for (int32 i = 0; i < m_nodeCapacity - 1; ++i)
33
- {
34
- m_nodes[i].next = i + 1;
35
- m_nodes[i].height = -1;
36
- }
37
- m_nodes[m_nodeCapacity-1].next = b2_nullNode;
38
- m_nodes[m_nodeCapacity-1].height = -1;
39
- m_freeList = 0;
40
-
41
- m_path = 0;
42
-
43
- m_insertionCount = 0;
44
- }
45
-
46
- b2DynamicTree::~b2DynamicTree()
47
- {
48
- // This frees the entire tree in one shot.
49
- b2Free(m_nodes);
50
- }
51
-
52
- // Allocate a node from the pool. Grow the pool if necessary.
53
- int32 b2DynamicTree::AllocateNode()
54
- {
55
- // Expand the node pool as needed.
56
- if (m_freeList == b2_nullNode)
57
- {
58
- b2Assert(m_nodeCount == m_nodeCapacity);
59
-
60
- // The free list is empty. Rebuild a bigger pool.
61
- b2TreeNode* oldNodes = m_nodes;
62
- m_nodeCapacity *= 2;
63
- m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
64
- memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2TreeNode));
65
- b2Free(oldNodes);
66
-
67
- // Build a linked list for the free list. The parent
68
- // pointer becomes the "next" pointer.
69
- for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i)
70
- {
71
- m_nodes[i].next = i + 1;
72
- m_nodes[i].height = -1;
73
- }
74
- m_nodes[m_nodeCapacity-1].next = b2_nullNode;
75
- m_nodes[m_nodeCapacity-1].height = -1;
76
- m_freeList = m_nodeCount;
77
- }
78
-
79
- // Peel a node off the free list.
80
- int32 nodeId = m_freeList;
81
- m_freeList = m_nodes[nodeId].next;
82
- m_nodes[nodeId].parent = b2_nullNode;
83
- m_nodes[nodeId].child1 = b2_nullNode;
84
- m_nodes[nodeId].child2 = b2_nullNode;
85
- m_nodes[nodeId].height = 0;
86
- m_nodes[nodeId].userData = NULL;
87
- ++m_nodeCount;
88
- return nodeId;
89
- }
90
-
91
- // Return a node to the pool.
92
- void b2DynamicTree::FreeNode(int32 nodeId)
93
- {
94
- b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
95
- b2Assert(0 < m_nodeCount);
96
- m_nodes[nodeId].next = m_freeList;
97
- m_nodes[nodeId].height = -1;
98
- m_freeList = nodeId;
99
- --m_nodeCount;
100
- }
101
-
102
- // Create a proxy in the tree as a leaf node. We return the index
103
- // of the node instead of a pointer so that we can grow
104
- // the node pool.
105
- int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
106
- {
107
- int32 proxyId = AllocateNode();
108
-
109
- // Fatten the aabb.
110
- b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
111
- m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
112
- m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
113
- m_nodes[proxyId].userData = userData;
114
- m_nodes[proxyId].height = 0;
115
-
116
- InsertLeaf(proxyId);
117
-
118
- return proxyId;
119
- }
120
-
121
- void b2DynamicTree::DestroyProxy(int32 proxyId)
122
- {
123
- b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
124
- b2Assert(m_nodes[proxyId].IsLeaf());
125
-
126
- RemoveLeaf(proxyId);
127
- FreeNode(proxyId);
128
- }
129
-
130
- bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
131
- {
132
- b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
133
-
134
- b2Assert(m_nodes[proxyId].IsLeaf());
135
-
136
- if (m_nodes[proxyId].aabb.Contains(aabb))
137
- {
138
- return false;
139
- }
140
-
141
- RemoveLeaf(proxyId);
142
-
143
- // Extend AABB.
144
- b2AABB b = aabb;
145
- b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
146
- b.lowerBound = b.lowerBound - r;
147
- b.upperBound = b.upperBound + r;
148
-
149
- // Predict AABB displacement.
150
- b2Vec2 d = b2_aabbMultiplier * displacement;
151
-
152
- if (d.x < 0.0f)
153
- {
154
- b.lowerBound.x += d.x;
155
- }
156
- else
157
- {
158
- b.upperBound.x += d.x;
159
- }
160
-
161
- if (d.y < 0.0f)
162
- {
163
- b.lowerBound.y += d.y;
164
- }
165
- else
166
- {
167
- b.upperBound.y += d.y;
168
- }
169
-
170
- m_nodes[proxyId].aabb = b;
171
-
172
- InsertLeaf(proxyId);
173
- return true;
174
- }
175
-
176
- void b2DynamicTree::InsertLeaf(int32 leaf)
177
- {
178
- ++m_insertionCount;
179
-
180
- if (m_root == b2_nullNode)
181
- {
182
- m_root = leaf;
183
- m_nodes[m_root].parent = b2_nullNode;
184
- return;
185
- }
186
-
187
- // Find the best sibling for this node
188
- b2AABB leafAABB = m_nodes[leaf].aabb;
189
- int32 index = m_root;
190
- while (m_nodes[index].IsLeaf() == false)
191
- {
192
- int32 child1 = m_nodes[index].child1;
193
- int32 child2 = m_nodes[index].child2;
194
-
195
- float32 area = m_nodes[index].aabb.GetPerimeter();
196
-
197
- b2AABB combinedAABB;
198
- combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
199
- float32 combinedArea = combinedAABB.GetPerimeter();
200
-
201
- // Cost of creating a new parent for this node and the new leaf
202
- float32 cost = 2.0f * combinedArea;
203
-
204
- // Minimum cost of pushing the leaf further down the tree
205
- float32 inheritanceCost = 2.0f * (combinedArea - area);
206
-
207
- // Cost of descending into child1
208
- float32 cost1;
209
- if (m_nodes[child1].IsLeaf())
210
- {
211
- b2AABB aabb;
212
- aabb.Combine(leafAABB, m_nodes[child1].aabb);
213
- cost1 = aabb.GetPerimeter() + inheritanceCost;
214
- }
215
- else
216
- {
217
- b2AABB aabb;
218
- aabb.Combine(leafAABB, m_nodes[child1].aabb);
219
- float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
220
- float32 newArea = aabb.GetPerimeter();
221
- cost1 = (newArea - oldArea) + inheritanceCost;
222
- }
223
-
224
- // Cost of descending into child2
225
- float32 cost2;
226
- if (m_nodes[child2].IsLeaf())
227
- {
228
- b2AABB aabb;
229
- aabb.Combine(leafAABB, m_nodes[child2].aabb);
230
- cost2 = aabb.GetPerimeter() + inheritanceCost;
231
- }
232
- else
233
- {
234
- b2AABB aabb;
235
- aabb.Combine(leafAABB, m_nodes[child2].aabb);
236
- float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
237
- float32 newArea = aabb.GetPerimeter();
238
- cost2 = newArea - oldArea + inheritanceCost;
239
- }
240
-
241
- // Descend according to the minimum cost.
242
- if (cost < cost1 && cost < cost2)
243
- {
244
- break;
245
- }
246
-
247
- // Descend
248
- if (cost1 < cost2)
249
- {
250
- index = child1;
251
- }
252
- else
253
- {
254
- index = child2;
255
- }
256
- }
257
-
258
- int32 sibling = index;
259
-
260
- // Create a new parent.
261
- int32 oldParent = m_nodes[sibling].parent;
262
- int32 newParent = AllocateNode();
263
- m_nodes[newParent].parent = oldParent;
264
- m_nodes[newParent].userData = NULL;
265
- m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb);
266
- m_nodes[newParent].height = m_nodes[sibling].height + 1;
267
-
268
- if (oldParent != b2_nullNode)
269
- {
270
- // The sibling was not the root.
271
- if (m_nodes[oldParent].child1 == sibling)
272
- {
273
- m_nodes[oldParent].child1 = newParent;
274
- }
275
- else
276
- {
277
- m_nodes[oldParent].child2 = newParent;
278
- }
279
-
280
- m_nodes[newParent].child1 = sibling;
281
- m_nodes[newParent].child2 = leaf;
282
- m_nodes[sibling].parent = newParent;
283
- m_nodes[leaf].parent = newParent;
284
- }
285
- else
286
- {
287
- // The sibling was the root.
288
- m_nodes[newParent].child1 = sibling;
289
- m_nodes[newParent].child2 = leaf;
290
- m_nodes[sibling].parent = newParent;
291
- m_nodes[leaf].parent = newParent;
292
- m_root = newParent;
293
- }
294
-
295
- // Walk back up the tree fixing heights and AABBs
296
- index = m_nodes[leaf].parent;
297
- while (index != b2_nullNode)
298
- {
299
- index = Balance(index);
300
-
301
- int32 child1 = m_nodes[index].child1;
302
- int32 child2 = m_nodes[index].child2;
303
-
304
- b2Assert(child1 != b2_nullNode);
305
- b2Assert(child2 != b2_nullNode);
306
-
307
- m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
308
- m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
309
-
310
- index = m_nodes[index].parent;
311
- }
312
-
313
- //Validate();
314
- }
315
-
316
- void b2DynamicTree::RemoveLeaf(int32 leaf)
317
- {
318
- if (leaf == m_root)
319
- {
320
- m_root = b2_nullNode;
321
- return;
322
- }
323
-
324
- int32 parent = m_nodes[leaf].parent;
325
- int32 grandParent = m_nodes[parent].parent;
326
- int32 sibling;
327
- if (m_nodes[parent].child1 == leaf)
328
- {
329
- sibling = m_nodes[parent].child2;
330
- }
331
- else
332
- {
333
- sibling = m_nodes[parent].child1;
334
- }
335
-
336
- if (grandParent != b2_nullNode)
337
- {
338
- // Destroy parent and connect sibling to grandParent.
339
- if (m_nodes[grandParent].child1 == parent)
340
- {
341
- m_nodes[grandParent].child1 = sibling;
342
- }
343
- else
344
- {
345
- m_nodes[grandParent].child2 = sibling;
346
- }
347
- m_nodes[sibling].parent = grandParent;
348
- FreeNode(parent);
349
-
350
- // Adjust ancestor bounds.
351
- int32 index = grandParent;
352
- while (index != b2_nullNode)
353
- {
354
- index = Balance(index);
355
-
356
- int32 child1 = m_nodes[index].child1;
357
- int32 child2 = m_nodes[index].child2;
358
-
359
- m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
360
- m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
361
-
362
- index = m_nodes[index].parent;
363
- }
364
- }
365
- else
366
- {
367
- m_root = sibling;
368
- m_nodes[sibling].parent = b2_nullNode;
369
- FreeNode(parent);
370
- }
371
-
372
- //Validate();
373
- }
374
-
375
- // Perform a left or right rotation if node A is imbalanced.
376
- // Returns the new root index.
377
- int32 b2DynamicTree::Balance(int32 iA)
378
- {
379
- b2Assert(iA != b2_nullNode);
380
-
381
- b2TreeNode* A = m_nodes + iA;
382
- if (A->IsLeaf() || A->height < 2)
383
- {
384
- return iA;
385
- }
386
-
387
- int32 iB = A->child1;
388
- int32 iC = A->child2;
389
- b2Assert(0 <= iB && iB < m_nodeCapacity);
390
- b2Assert(0 <= iC && iC < m_nodeCapacity);
391
-
392
- b2TreeNode* B = m_nodes + iB;
393
- b2TreeNode* C = m_nodes + iC;
394
-
395
- int32 balance = C->height - B->height;
396
-
397
- // Rotate C up
398
- if (balance > 1)
399
- {
400
- int32 iF = C->child1;
401
- int32 iG = C->child2;
402
- b2TreeNode* F = m_nodes + iF;
403
- b2TreeNode* G = m_nodes + iG;
404
- b2Assert(0 <= iF && iF < m_nodeCapacity);
405
- b2Assert(0 <= iG && iG < m_nodeCapacity);
406
-
407
- // Swap A and C
408
- C->child1 = iA;
409
- C->parent = A->parent;
410
- A->parent = iC;
411
-
412
- // A's old parent should point to C
413
- if (C->parent != b2_nullNode)
414
- {
415
- if (m_nodes[C->parent].child1 == iA)
416
- {
417
- m_nodes[C->parent].child1 = iC;
418
- }
419
- else
420
- {
421
- b2Assert(m_nodes[C->parent].child2 == iA);
422
- m_nodes[C->parent].child2 = iC;
423
- }
424
- }
425
- else
426
- {
427
- m_root = iC;
428
- }
429
-
430
- // Rotate
431
- if (F->height > G->height)
432
- {
433
- C->child2 = iF;
434
- A->child2 = iG;
435
- G->parent = iA;
436
- A->aabb.Combine(B->aabb, G->aabb);
437
- C->aabb.Combine(A->aabb, F->aabb);
438
-
439
- A->height = 1 + b2Max(B->height, G->height);
440
- C->height = 1 + b2Max(A->height, F->height);
441
- }
442
- else
443
- {
444
- C->child2 = iG;
445
- A->child2 = iF;
446
- F->parent = iA;
447
- A->aabb.Combine(B->aabb, F->aabb);
448
- C->aabb.Combine(A->aabb, G->aabb);
449
-
450
- A->height = 1 + b2Max(B->height, F->height);
451
- C->height = 1 + b2Max(A->height, G->height);
452
- }
453
-
454
- return iC;
455
- }
456
-
457
- // Rotate B up
458
- if (balance < -1)
459
- {
460
- int32 iD = B->child1;
461
- int32 iE = B->child2;
462
- b2TreeNode* D = m_nodes + iD;
463
- b2TreeNode* E = m_nodes + iE;
464
- b2Assert(0 <= iD && iD < m_nodeCapacity);
465
- b2Assert(0 <= iE && iE < m_nodeCapacity);
466
-
467
- // Swap A and B
468
- B->child1 = iA;
469
- B->parent = A->parent;
470
- A->parent = iB;
471
-
472
- // A's old parent should point to B
473
- if (B->parent != b2_nullNode)
474
- {
475
- if (m_nodes[B->parent].child1 == iA)
476
- {
477
- m_nodes[B->parent].child1 = iB;
478
- }
479
- else
480
- {
481
- b2Assert(m_nodes[B->parent].child2 == iA);
482
- m_nodes[B->parent].child2 = iB;
483
- }
484
- }
485
- else
486
- {
487
- m_root = iB;
488
- }
489
-
490
- // Rotate
491
- if (D->height > E->height)
492
- {
493
- B->child2 = iD;
494
- A->child1 = iE;
495
- E->parent = iA;
496
- A->aabb.Combine(C->aabb, E->aabb);
497
- B->aabb.Combine(A->aabb, D->aabb);
498
-
499
- A->height = 1 + b2Max(C->height, E->height);
500
- B->height = 1 + b2Max(A->height, D->height);
501
- }
502
- else
503
- {
504
- B->child2 = iE;
505
- A->child1 = iD;
506
- D->parent = iA;
507
- A->aabb.Combine(C->aabb, D->aabb);
508
- B->aabb.Combine(A->aabb, E->aabb);
509
-
510
- A->height = 1 + b2Max(C->height, D->height);
511
- B->height = 1 + b2Max(A->height, E->height);
512
- }
513
-
514
- return iB;
515
- }
516
-
517
- return iA;
518
- }
519
-
520
- int32 b2DynamicTree::GetHeight() const
521
- {
522
- if (m_root == b2_nullNode)
523
- {
524
- return 0;
525
- }
526
-
527
- return m_nodes[m_root].height;
528
- }
529
-
530
- //
531
- float32 b2DynamicTree::GetAreaRatio() const
532
- {
533
- if (m_root == b2_nullNode)
534
- {
535
- return 0.0f;
536
- }
537
-
538
- const b2TreeNode* root = m_nodes + m_root;
539
- float32 rootArea = root->aabb.GetPerimeter();
540
-
541
- float32 totalArea = 0.0f;
542
- for (int32 i = 0; i < m_nodeCapacity; ++i)
543
- {
544
- const b2TreeNode* node = m_nodes + i;
545
- if (node->height < 0)
546
- {
547
- // Free node in pool
548
- continue;
549
- }
550
-
551
- totalArea += node->aabb.GetPerimeter();
552
- }
553
-
554
- return totalArea / rootArea;
555
- }
556
-
557
- // Compute the height of a sub-tree.
558
- int32 b2DynamicTree::ComputeHeight(int32 nodeId) const
559
- {
560
- b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
561
- b2TreeNode* node = m_nodes + nodeId;
562
-
563
- if (node->IsLeaf())
564
- {
565
- return 0;
566
- }
567
-
568
- int32 height1 = ComputeHeight(node->child1);
569
- int32 height2 = ComputeHeight(node->child2);
570
- return 1 + b2Max(height1, height2);
571
- }
572
-
573
- int32 b2DynamicTree::ComputeHeight() const
574
- {
575
- int32 height = ComputeHeight(m_root);
576
- return height;
577
- }
578
-
579
- void b2DynamicTree::ValidateStructure(int32 index) const
580
- {
581
- if (index == b2_nullNode)
582
- {
583
- return;
584
- }
585
-
586
- if (index == m_root)
587
- {
588
- b2Assert(m_nodes[index].parent == b2_nullNode);
589
- }
590
-
591
- const b2TreeNode* node = m_nodes + index;
592
-
593
- int32 child1 = node->child1;
594
- int32 child2 = node->child2;
595
-
596
- if (node->IsLeaf())
597
- {
598
- b2Assert(child1 == b2_nullNode);
599
- b2Assert(child2 == b2_nullNode);
600
- b2Assert(node->height == 0);
601
- return;
602
- }
603
-
604
- b2Assert(0 <= child1 && child1 < m_nodeCapacity);
605
- b2Assert(0 <= child2 && child2 < m_nodeCapacity);
606
-
607
- b2Assert(m_nodes[child1].parent == index);
608
- b2Assert(m_nodes[child2].parent == index);
609
-
610
- ValidateStructure(child1);
611
- ValidateStructure(child2);
612
- }
613
-
614
- void b2DynamicTree::ValidateMetrics(int32 index) const
615
- {
616
- if (index == b2_nullNode)
617
- {
618
- return;
619
- }
620
-
621
- const b2TreeNode* node = m_nodes + index;
622
-
623
- int32 child1 = node->child1;
624
- int32 child2 = node->child2;
625
-
626
- if (node->IsLeaf())
627
- {
628
- b2Assert(child1 == b2_nullNode);
629
- b2Assert(child2 == b2_nullNode);
630
- b2Assert(node->height == 0);
631
- return;
632
- }
633
-
634
- b2Assert(0 <= child1 && child1 < m_nodeCapacity);
635
- b2Assert(0 <= child2 && child2 < m_nodeCapacity);
636
-
637
- int32 height1 = m_nodes[child1].height;
638
- int32 height2 = m_nodes[child2].height;
639
- int32 height;
640
- height = 1 + b2Max(height1, height2);
641
- b2Assert(node->height == height);
642
-
643
- b2AABB aabb;
644
- aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
645
-
646
- b2Assert(aabb.lowerBound == node->aabb.lowerBound);
647
- b2Assert(aabb.upperBound == node->aabb.upperBound);
648
-
649
- ValidateMetrics(child1);
650
- ValidateMetrics(child2);
651
- }
652
-
653
- void b2DynamicTree::Validate() const
654
- {
655
- ValidateStructure(m_root);
656
- ValidateMetrics(m_root);
657
-
658
- int32 freeCount = 0;
659
- int32 freeIndex = m_freeList;
660
- while (freeIndex != b2_nullNode)
661
- {
662
- b2Assert(0 <= freeIndex && freeIndex < m_nodeCapacity);
663
- freeIndex = m_nodes[freeIndex].next;
664
- ++freeCount;
665
- }
666
-
667
- b2Assert(GetHeight() == ComputeHeight());
668
-
669
- b2Assert(m_nodeCount + freeCount == m_nodeCapacity);
670
- }
671
-
672
- int32 b2DynamicTree::GetMaxBalance() const
673
- {
674
- int32 maxBalance = 0;
675
- for (int32 i = 0; i < m_nodeCapacity; ++i)
676
- {
677
- const b2TreeNode* node = m_nodes + i;
678
- if (node->height <= 1)
679
- {
680
- continue;
681
- }
682
-
683
- b2Assert(node->IsLeaf() == false);
684
-
685
- int32 child1 = node->child1;
686
- int32 child2 = node->child2;
687
- int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height);
688
- maxBalance = b2Max(maxBalance, balance);
689
- }
690
-
691
- return maxBalance;
692
- }
693
-
694
- void b2DynamicTree::RebuildBottomUp()
695
- {
696
- int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
697
- int32 count = 0;
698
-
699
- // Build array of leaves. Free the rest.
700
- for (int32 i = 0; i < m_nodeCapacity; ++i)
701
- {
702
- if (m_nodes[i].height < 0)
703
- {
704
- // free node in pool
705
- continue;
706
- }
707
-
708
- if (m_nodes[i].IsLeaf())
709
- {
710
- m_nodes[i].parent = b2_nullNode;
711
- nodes[count] = i;
712
- ++count;
713
- }
714
- else
715
- {
716
- FreeNode(i);
717
- }
718
- }
719
-
720
- while (count > 1)
721
- {
722
- float32 minCost = b2_maxFloat;
723
- int32 iMin = -1, jMin = -1;
724
- for (int32 i = 0; i < count; ++i)
725
- {
726
- b2AABB aabbi = m_nodes[nodes[i]].aabb;
727
-
728
- for (int32 j = i + 1; j < count; ++j)
729
- {
730
- b2AABB aabbj = m_nodes[nodes[j]].aabb;
731
- b2AABB b;
732
- b.Combine(aabbi, aabbj);
733
- float32 cost = b.GetPerimeter();
734
- if (cost < minCost)
735
- {
736
- iMin = i;
737
- jMin = j;
738
- minCost = cost;
739
- }
740
- }
741
- }
742
-
743
- int32 index1 = nodes[iMin];
744
- int32 index2 = nodes[jMin];
745
- b2TreeNode* child1 = m_nodes + index1;
746
- b2TreeNode* child2 = m_nodes + index2;
747
-
748
- int32 parentIndex = AllocateNode();
749
- b2TreeNode* parent = m_nodes + parentIndex;
750
- parent->child1 = index1;
751
- parent->child2 = index2;
752
- parent->height = 1 + b2Max(child1->height, child2->height);
753
- parent->aabb.Combine(child1->aabb, child2->aabb);
754
- parent->parent = b2_nullNode;
755
-
756
- child1->parent = parentIndex;
757
- child2->parent = parentIndex;
758
-
759
- nodes[jMin] = nodes[count-1];
760
- nodes[iMin] = parentIndex;
761
- --count;
762
- }
763
-
764
- m_root = nodes[0];
765
- b2Free(nodes);
766
-
767
- Validate();
768
- }
769
-
770
- void b2DynamicTree::ShiftOrigin(const b2Vec2& newOrigin)
771
- {
772
- // Build array of leaves. Free the rest.
773
- for (int32 i = 0; i < m_nodeCapacity; ++i)
774
- {
775
- m_nodes[i].aabb.lowerBound -= newOrigin;
776
- m_nodes[i].aabb.upperBound -= newOrigin;
777
- }
778
- }