reflexion 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/reflex/application.cpp +5 -5
  3. data/.doc/ext/reflex/body.cpp +167 -0
  4. data/.doc/ext/reflex/capture_event.cpp +4 -4
  5. data/.doc/ext/reflex/draw_event.cpp +4 -4
  6. data/.doc/ext/reflex/event.cpp +4 -4
  7. data/.doc/ext/reflex/fixture.cpp +101 -0
  8. data/.doc/ext/reflex/focus_event.cpp +4 -4
  9. data/.doc/ext/reflex/frame_event.cpp +4 -4
  10. data/.doc/ext/reflex/image_view.cpp +22 -5
  11. data/.doc/ext/reflex/key_event.cpp +4 -4
  12. data/.doc/ext/reflex/native.cpp +6 -0
  13. data/.doc/ext/reflex/pointer_event.cpp +4 -4
  14. data/.doc/ext/reflex/reflex.cpp +2 -3
  15. data/.doc/ext/reflex/scroll_event.cpp +4 -4
  16. data/.doc/ext/reflex/selector.cpp +4 -4
  17. data/.doc/ext/reflex/style.cpp +4 -4
  18. data/.doc/ext/reflex/style_length.cpp +4 -4
  19. data/.doc/ext/reflex/style_length2.cpp +4 -4
  20. data/.doc/ext/reflex/style_length4.cpp +4 -4
  21. data/.doc/ext/reflex/update_event.cpp +4 -4
  22. data/.doc/ext/reflex/view.cpp +110 -8
  23. data/.doc/ext/reflex/wheel_event.cpp +4 -4
  24. data/.doc/ext/reflex/window.cpp +36 -12
  25. data/README.md +2 -2
  26. data/Rakefile +2 -1
  27. data/VERSION +1 -1
  28. data/ext/reflex/application.cpp +8 -8
  29. data/ext/reflex/body.cpp +181 -0
  30. data/ext/reflex/capture_event.cpp +4 -4
  31. data/ext/reflex/draw_event.cpp +4 -4
  32. data/ext/reflex/event.cpp +4 -4
  33. data/ext/reflex/fixture.cpp +108 -0
  34. data/ext/reflex/focus_event.cpp +4 -4
  35. data/ext/reflex/frame_event.cpp +4 -4
  36. data/ext/reflex/image_view.cpp +24 -5
  37. data/ext/reflex/key_event.cpp +4 -4
  38. data/ext/reflex/native.cpp +6 -0
  39. data/ext/reflex/pointer_event.cpp +4 -4
  40. data/ext/reflex/reflex.cpp +2 -3
  41. data/ext/reflex/scroll_event.cpp +4 -4
  42. data/ext/reflex/selector.cpp +4 -4
  43. data/ext/reflex/style.cpp +4 -4
  44. data/ext/reflex/style_length.cpp +4 -4
  45. data/ext/reflex/style_length2.cpp +4 -4
  46. data/ext/reflex/style_length4.cpp +4 -4
  47. data/ext/reflex/update_event.cpp +4 -4
  48. data/ext/reflex/view.cpp +126 -12
  49. data/ext/reflex/wheel_event.cpp +4 -4
  50. data/ext/reflex/window.cpp +39 -12
  51. data/include/reflex/bitmap.h +20 -0
  52. data/include/reflex/body.h +82 -0
  53. data/include/reflex/bounds.h +20 -0
  54. data/include/reflex/color.h +20 -0
  55. data/include/reflex/color_space.h +20 -0
  56. data/include/reflex/defs.h +5 -1
  57. data/include/reflex/event.h +16 -25
  58. data/include/reflex/fixture.h +116 -0
  59. data/include/reflex/font.h +20 -0
  60. data/include/reflex/image.h +20 -0
  61. data/include/reflex/image_view.h +1 -1
  62. data/include/reflex/matrix.h +20 -0
  63. data/include/reflex/painter.h +20 -0
  64. data/include/reflex/point.h +24 -0
  65. data/include/reflex/ruby/application.h +6 -0
  66. data/include/reflex/ruby/body.h +41 -0
  67. data/include/reflex/ruby/event.h +68 -0
  68. data/include/reflex/ruby/fixture.h +41 -0
  69. data/include/reflex/ruby/image_view.h +14 -0
  70. data/include/reflex/ruby/selector.h +14 -0
  71. data/include/reflex/ruby/style.h +14 -0
  72. data/include/reflex/ruby/style_length.h +26 -0
  73. data/include/reflex/ruby/view.h +43 -39
  74. data/include/reflex/ruby/window.h +27 -21
  75. data/include/reflex/ruby.h +2 -0
  76. data/include/reflex/shader.h +20 -0
  77. data/include/reflex/style.h +2 -3
  78. data/include/reflex/texture.h +20 -0
  79. data/include/reflex/view.h +45 -24
  80. data/include/reflex/window.h +11 -14
  81. data/include/reflex.h +3 -0
  82. data/lib/reflex/application.rb +6 -2
  83. data/lib/reflex/body.rb +17 -0
  84. data/lib/reflex/fixture.rb +17 -0
  85. data/lib/reflex/view.rb +16 -1
  86. data/lib/reflex/window.rb +13 -1
  87. data/lib/reflex.rb +2 -0
  88. data/reflex.gemspec +1 -1
  89. data/samples/bats.rb +4 -3
  90. data/samples/checker.rb +4 -3
  91. data/samples/fans.rb +4 -3
  92. data/samples/fps.rb +5 -3
  93. data/samples/grid.rb +5 -4
  94. data/samples/hello.rb +1 -1
  95. data/samples/image.rb +3 -2
  96. data/samples/ios/hello/hello/main.cpp +12 -3
  97. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +376 -123
  98. data/samples/key.rb +5 -4
  99. data/samples/layout.rb +3 -2
  100. data/samples/model.rb +3 -2
  101. data/samples/osx/hello/hello/main.cpp +12 -3
  102. data/samples/osx/hello/hello.xcodeproj/project.pbxproj +375 -120
  103. data/samples/physics.rb +37 -0
  104. data/samples/repl.rb +3 -2
  105. data/samples/shader.rb +4 -4
  106. data/samples/shapes.rb +4 -4
  107. data/samples/text.rb +6 -4
  108. data/samples/tree.rb +5 -4
  109. data/samples/views.rb +3 -2
  110. data/samples/visuals.rb +1 -2
  111. data/src/body.cpp +244 -0
  112. data/src/event.cpp +18 -18
  113. data/src/fixture.cpp +108 -0
  114. data/src/image_view.cpp +1 -1
  115. data/src/ios/native_window.h +2 -0
  116. data/src/ios/native_window.mm +18 -1
  117. data/src/ios/opengl_view.mm +8 -0
  118. data/src/ios/window.mm +24 -3
  119. data/src/ios/window_data.h +3 -3
  120. data/src/osx/native_window.mm +17 -1
  121. data/src/osx/window.mm +24 -3
  122. data/src/osx/window_data.h +3 -3
  123. data/src/physics/Box2D/Box2D.h +68 -0
  124. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.cpp +193 -0
  125. data/src/physics/Box2D/Collision/Shapes/b2ChainShape.h +105 -0
  126. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.cpp +99 -0
  127. data/src/physics/Box2D/Collision/Shapes/b2CircleShape.h +91 -0
  128. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.cpp +138 -0
  129. data/src/physics/Box2D/Collision/Shapes/b2EdgeShape.h +74 -0
  130. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.cpp +467 -0
  131. data/src/physics/Box2D/Collision/Shapes/b2PolygonShape.h +101 -0
  132. data/src/physics/Box2D/Collision/Shapes/b2Shape.h +101 -0
  133. data/src/physics/Box2D/Collision/b2BroadPhase.cpp +119 -0
  134. data/src/physics/Box2D/Collision/b2BroadPhase.h +257 -0
  135. data/src/physics/Box2D/Collision/b2CollideCircle.cpp +154 -0
  136. data/src/physics/Box2D/Collision/b2CollideEdge.cpp +698 -0
  137. data/src/physics/Box2D/Collision/b2CollidePolygon.cpp +239 -0
  138. data/src/physics/Box2D/Collision/b2Collision.cpp +252 -0
  139. data/src/physics/Box2D/Collision/b2Collision.h +277 -0
  140. data/src/physics/Box2D/Collision/b2Distance.cpp +603 -0
  141. data/src/physics/Box2D/Collision/b2Distance.h +141 -0
  142. data/src/physics/Box2D/Collision/b2DynamicTree.cpp +778 -0
  143. data/src/physics/Box2D/Collision/b2DynamicTree.h +289 -0
  144. data/src/physics/Box2D/Collision/b2TimeOfImpact.cpp +486 -0
  145. data/src/physics/Box2D/Collision/b2TimeOfImpact.h +58 -0
  146. data/src/physics/Box2D/Common/b2BlockAllocator.cpp +215 -0
  147. data/src/physics/Box2D/Common/b2BlockAllocator.h +62 -0
  148. data/src/physics/Box2D/Common/b2Draw.cpp +44 -0
  149. data/src/physics/Box2D/Common/b2Draw.h +86 -0
  150. data/src/physics/Box2D/Common/b2GrowableStack.h +85 -0
  151. data/src/physics/Box2D/Common/b2Math.cpp +94 -0
  152. data/src/physics/Box2D/Common/b2Math.h +720 -0
  153. data/src/physics/Box2D/Common/b2Settings.cpp +44 -0
  154. data/src/physics/Box2D/Common/b2Settings.h +151 -0
  155. data/src/physics/Box2D/Common/b2StackAllocator.cpp +83 -0
  156. data/src/physics/Box2D/Common/b2StackAllocator.h +60 -0
  157. data/src/physics/Box2D/Common/b2Timer.cpp +101 -0
  158. data/src/physics/Box2D/Common/b2Timer.h +50 -0
  159. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.cpp +53 -0
  160. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndCircleContact.h +39 -0
  161. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.cpp +53 -0
  162. data/src/physics/Box2D/Dynamics/Contacts/b2ChainAndPolygonContact.h +39 -0
  163. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.cpp +52 -0
  164. data/src/physics/Box2D/Dynamics/Contacts/b2CircleContact.h +39 -0
  165. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.cpp +247 -0
  166. data/src/physics/Box2D/Dynamics/Contacts/b2Contact.h +349 -0
  167. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.cpp +838 -0
  168. data/src/physics/Box2D/Dynamics/Contacts/b2ContactSolver.h +95 -0
  169. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.cpp +49 -0
  170. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndCircleContact.h +39 -0
  171. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.cpp +49 -0
  172. data/src/physics/Box2D/Dynamics/Contacts/b2EdgeAndPolygonContact.h +39 -0
  173. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp +49 -0
  174. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h +38 -0
  175. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.cpp +52 -0
  176. data/src/physics/Box2D/Dynamics/Contacts/b2PolygonContact.h +39 -0
  177. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.cpp +260 -0
  178. data/src/physics/Box2D/Dynamics/Joints/b2DistanceJoint.h +169 -0
  179. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.cpp +251 -0
  180. data/src/physics/Box2D/Dynamics/Joints/b2FrictionJoint.h +119 -0
  181. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.cpp +419 -0
  182. data/src/physics/Box2D/Dynamics/Joints/b2GearJoint.h +125 -0
  183. data/src/physics/Box2D/Dynamics/Joints/b2Joint.cpp +211 -0
  184. data/src/physics/Box2D/Dynamics/Joints/b2Joint.h +226 -0
  185. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.cpp +304 -0
  186. data/src/physics/Box2D/Dynamics/Joints/b2MotorJoint.h +133 -0
  187. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.cpp +222 -0
  188. data/src/physics/Box2D/Dynamics/Joints/b2MouseJoint.h +129 -0
  189. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp +629 -0
  190. data/src/physics/Box2D/Dynamics/Joints/b2PrismaticJoint.h +196 -0
  191. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.cpp +348 -0
  192. data/src/physics/Box2D/Dynamics/Joints/b2PulleyJoint.h +152 -0
  193. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp +502 -0
  194. data/src/physics/Box2D/Dynamics/Joints/b2RevoluteJoint.h +204 -0
  195. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.cpp +241 -0
  196. data/src/physics/Box2D/Dynamics/Joints/b2RopeJoint.h +114 -0
  197. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.cpp +344 -0
  198. data/src/physics/Box2D/Dynamics/Joints/b2WeldJoint.h +126 -0
  199. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.cpp +419 -0
  200. data/src/physics/Box2D/Dynamics/Joints/b2WheelJoint.h +210 -0
  201. data/src/physics/Box2D/Dynamics/b2Body.cpp +549 -0
  202. data/src/physics/Box2D/Dynamics/b2Body.h +860 -0
  203. data/src/physics/Box2D/Dynamics/b2ContactManager.cpp +296 -0
  204. data/src/physics/Box2D/Dynamics/b2ContactManager.h +52 -0
  205. data/src/physics/Box2D/Dynamics/b2Fixture.cpp +303 -0
  206. data/src/physics/Box2D/Dynamics/b2Fixture.h +345 -0
  207. data/src/physics/Box2D/Dynamics/b2Island.cpp +539 -0
  208. data/src/physics/Box2D/Dynamics/b2Island.h +93 -0
  209. data/src/physics/Box2D/Dynamics/b2TimeStep.h +70 -0
  210. data/src/physics/Box2D/Dynamics/b2World.cpp +1339 -0
  211. data/src/physics/Box2D/Dynamics/b2World.h +354 -0
  212. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.cpp +36 -0
  213. data/src/physics/Box2D/Dynamics/b2WorldCallbacks.h +155 -0
  214. data/src/physics/Box2D/Rope/b2Rope.cpp +259 -0
  215. data/src/physics/Box2D/Rope/b2Rope.h +115 -0
  216. data/src/style.cpp +2 -2
  217. data/src/view.cpp +217 -17
  218. data/src/window.cpp +25 -15
  219. data/src/world.cpp +206 -0
  220. data/src/world.h +96 -0
  221. data/task/box2d.rake +25 -0
  222. data/test/test_view.rb +5 -5
  223. metadata +125 -3
@@ -0,0 +1,1339 @@
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/b2World.h>
20
+ #include <Box2D/Dynamics/b2Body.h>
21
+ #include <Box2D/Dynamics/b2Fixture.h>
22
+ #include <Box2D/Dynamics/b2Island.h>
23
+ #include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
24
+ #include <Box2D/Dynamics/Contacts/b2Contact.h>
25
+ #include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
26
+ #include <Box2D/Collision/b2Collision.h>
27
+ #include <Box2D/Collision/b2BroadPhase.h>
28
+ #include <Box2D/Collision/Shapes/b2CircleShape.h>
29
+ #include <Box2D/Collision/Shapes/b2EdgeShape.h>
30
+ #include <Box2D/Collision/Shapes/b2ChainShape.h>
31
+ #include <Box2D/Collision/Shapes/b2PolygonShape.h>
32
+ #include <Box2D/Collision/b2TimeOfImpact.h>
33
+ #include <Box2D/Common/b2Draw.h>
34
+ #include <Box2D/Common/b2Timer.h>
35
+ #include <new>
36
+
37
+ b2World::b2World(const b2Vec2& gravity)
38
+ {
39
+ m_destructionListener = NULL;
40
+ g_debugDraw = NULL;
41
+
42
+ m_bodyList = NULL;
43
+ m_jointList = NULL;
44
+
45
+ m_bodyCount = 0;
46
+ m_jointCount = 0;
47
+
48
+ m_warmStarting = true;
49
+ m_continuousPhysics = true;
50
+ m_subStepping = false;
51
+
52
+ m_stepComplete = true;
53
+
54
+ m_allowSleep = true;
55
+ m_gravity = gravity;
56
+
57
+ m_flags = e_clearForces;
58
+
59
+ m_inv_dt0 = 0.0f;
60
+
61
+ m_contactManager.m_allocator = &m_blockAllocator;
62
+
63
+ memset(&m_profile, 0, sizeof(b2Profile));
64
+ }
65
+
66
+ b2World::~b2World()
67
+ {
68
+ // Some shapes allocate using b2Alloc.
69
+ b2Body* b = m_bodyList;
70
+ while (b)
71
+ {
72
+ b2Body* bNext = b->m_next;
73
+
74
+ b2Fixture* f = b->m_fixtureList;
75
+ while (f)
76
+ {
77
+ b2Fixture* fNext = f->m_next;
78
+ f->m_proxyCount = 0;
79
+ f->Destroy(&m_blockAllocator);
80
+ f = fNext;
81
+ }
82
+
83
+ b = bNext;
84
+ }
85
+ }
86
+
87
+ void b2World::SetDestructionListener(b2DestructionListener* listener)
88
+ {
89
+ m_destructionListener = listener;
90
+ }
91
+
92
+ void b2World::SetContactFilter(b2ContactFilter* filter)
93
+ {
94
+ m_contactManager.m_contactFilter = filter;
95
+ }
96
+
97
+ void b2World::SetContactListener(b2ContactListener* listener)
98
+ {
99
+ m_contactManager.m_contactListener = listener;
100
+ }
101
+
102
+ void b2World::SetDebugDraw(b2Draw* debugDraw)
103
+ {
104
+ g_debugDraw = debugDraw;
105
+ }
106
+
107
+ b2Body* b2World::CreateBody(const b2BodyDef* def)
108
+ {
109
+ b2Assert(IsLocked() == false);
110
+ if (IsLocked())
111
+ {
112
+ return NULL;
113
+ }
114
+
115
+ void* mem = m_blockAllocator.Allocate(sizeof(b2Body));
116
+ b2Body* b = new (mem) b2Body(def, this);
117
+
118
+ // Add to world doubly linked list.
119
+ b->m_prev = NULL;
120
+ b->m_next = m_bodyList;
121
+ if (m_bodyList)
122
+ {
123
+ m_bodyList->m_prev = b;
124
+ }
125
+ m_bodyList = b;
126
+ ++m_bodyCount;
127
+
128
+ return b;
129
+ }
130
+
131
+ void b2World::DestroyBody(b2Body* b)
132
+ {
133
+ b2Assert(m_bodyCount > 0);
134
+ b2Assert(IsLocked() == false);
135
+ if (IsLocked())
136
+ {
137
+ return;
138
+ }
139
+
140
+ // Delete the attached joints.
141
+ b2JointEdge* je = b->m_jointList;
142
+ while (je)
143
+ {
144
+ b2JointEdge* je0 = je;
145
+ je = je->next;
146
+
147
+ if (m_destructionListener)
148
+ {
149
+ m_destructionListener->SayGoodbye(je0->joint);
150
+ }
151
+
152
+ DestroyJoint(je0->joint);
153
+
154
+ b->m_jointList = je;
155
+ }
156
+ b->m_jointList = NULL;
157
+
158
+ // Delete the attached contacts.
159
+ b2ContactEdge* ce = b->m_contactList;
160
+ while (ce)
161
+ {
162
+ b2ContactEdge* ce0 = ce;
163
+ ce = ce->next;
164
+ m_contactManager.Destroy(ce0->contact);
165
+ }
166
+ b->m_contactList = NULL;
167
+
168
+ // Delete the attached fixtures. This destroys broad-phase proxies.
169
+ b2Fixture* f = b->m_fixtureList;
170
+ while (f)
171
+ {
172
+ b2Fixture* f0 = f;
173
+ f = f->m_next;
174
+
175
+ if (m_destructionListener)
176
+ {
177
+ m_destructionListener->SayGoodbye(f0);
178
+ }
179
+
180
+ f0->DestroyProxies(&m_contactManager.m_broadPhase);
181
+ f0->Destroy(&m_blockAllocator);
182
+ f0->~b2Fixture();
183
+ m_blockAllocator.Free(f0, sizeof(b2Fixture));
184
+
185
+ b->m_fixtureList = f;
186
+ b->m_fixtureCount -= 1;
187
+ }
188
+ b->m_fixtureList = NULL;
189
+ b->m_fixtureCount = 0;
190
+
191
+ // Remove world body list.
192
+ if (b->m_prev)
193
+ {
194
+ b->m_prev->m_next = b->m_next;
195
+ }
196
+
197
+ if (b->m_next)
198
+ {
199
+ b->m_next->m_prev = b->m_prev;
200
+ }
201
+
202
+ if (b == m_bodyList)
203
+ {
204
+ m_bodyList = b->m_next;
205
+ }
206
+
207
+ --m_bodyCount;
208
+ b->~b2Body();
209
+ m_blockAllocator.Free(b, sizeof(b2Body));
210
+ }
211
+
212
+ b2Joint* b2World::CreateJoint(const b2JointDef* def)
213
+ {
214
+ b2Assert(IsLocked() == false);
215
+ if (IsLocked())
216
+ {
217
+ return NULL;
218
+ }
219
+
220
+ b2Joint* j = b2Joint::Create(def, &m_blockAllocator);
221
+
222
+ // Connect to the world list.
223
+ j->m_prev = NULL;
224
+ j->m_next = m_jointList;
225
+ if (m_jointList)
226
+ {
227
+ m_jointList->m_prev = j;
228
+ }
229
+ m_jointList = j;
230
+ ++m_jointCount;
231
+
232
+ // Connect to the bodies' doubly linked lists.
233
+ j->m_edgeA.joint = j;
234
+ j->m_edgeA.other = j->m_bodyB;
235
+ j->m_edgeA.prev = NULL;
236
+ j->m_edgeA.next = j->m_bodyA->m_jointList;
237
+ if (j->m_bodyA->m_jointList) j->m_bodyA->m_jointList->prev = &j->m_edgeA;
238
+ j->m_bodyA->m_jointList = &j->m_edgeA;
239
+
240
+ j->m_edgeB.joint = j;
241
+ j->m_edgeB.other = j->m_bodyA;
242
+ j->m_edgeB.prev = NULL;
243
+ j->m_edgeB.next = j->m_bodyB->m_jointList;
244
+ if (j->m_bodyB->m_jointList) j->m_bodyB->m_jointList->prev = &j->m_edgeB;
245
+ j->m_bodyB->m_jointList = &j->m_edgeB;
246
+
247
+ b2Body* bodyA = def->bodyA;
248
+ b2Body* bodyB = def->bodyB;
249
+
250
+ // If the joint prevents collisions, then flag any contacts for filtering.
251
+ if (def->collideConnected == false)
252
+ {
253
+ b2ContactEdge* edge = bodyB->GetContactList();
254
+ while (edge)
255
+ {
256
+ if (edge->other == bodyA)
257
+ {
258
+ // Flag the contact for filtering at the next time step (where either
259
+ // body is awake).
260
+ edge->contact->FlagForFiltering();
261
+ }
262
+
263
+ edge = edge->next;
264
+ }
265
+ }
266
+
267
+ // Note: creating a joint doesn't wake the bodies.
268
+
269
+ return j;
270
+ }
271
+
272
+ void b2World::DestroyJoint(b2Joint* j)
273
+ {
274
+ b2Assert(IsLocked() == false);
275
+ if (IsLocked())
276
+ {
277
+ return;
278
+ }
279
+
280
+ bool collideConnected = j->m_collideConnected;
281
+
282
+ // Remove from the doubly linked list.
283
+ if (j->m_prev)
284
+ {
285
+ j->m_prev->m_next = j->m_next;
286
+ }
287
+
288
+ if (j->m_next)
289
+ {
290
+ j->m_next->m_prev = j->m_prev;
291
+ }
292
+
293
+ if (j == m_jointList)
294
+ {
295
+ m_jointList = j->m_next;
296
+ }
297
+
298
+ // Disconnect from island graph.
299
+ b2Body* bodyA = j->m_bodyA;
300
+ b2Body* bodyB = j->m_bodyB;
301
+
302
+ // Wake up connected bodies.
303
+ bodyA->SetAwake(true);
304
+ bodyB->SetAwake(true);
305
+
306
+ // Remove from body 1.
307
+ if (j->m_edgeA.prev)
308
+ {
309
+ j->m_edgeA.prev->next = j->m_edgeA.next;
310
+ }
311
+
312
+ if (j->m_edgeA.next)
313
+ {
314
+ j->m_edgeA.next->prev = j->m_edgeA.prev;
315
+ }
316
+
317
+ if (&j->m_edgeA == bodyA->m_jointList)
318
+ {
319
+ bodyA->m_jointList = j->m_edgeA.next;
320
+ }
321
+
322
+ j->m_edgeA.prev = NULL;
323
+ j->m_edgeA.next = NULL;
324
+
325
+ // Remove from body 2
326
+ if (j->m_edgeB.prev)
327
+ {
328
+ j->m_edgeB.prev->next = j->m_edgeB.next;
329
+ }
330
+
331
+ if (j->m_edgeB.next)
332
+ {
333
+ j->m_edgeB.next->prev = j->m_edgeB.prev;
334
+ }
335
+
336
+ if (&j->m_edgeB == bodyB->m_jointList)
337
+ {
338
+ bodyB->m_jointList = j->m_edgeB.next;
339
+ }
340
+
341
+ j->m_edgeB.prev = NULL;
342
+ j->m_edgeB.next = NULL;
343
+
344
+ b2Joint::Destroy(j, &m_blockAllocator);
345
+
346
+ b2Assert(m_jointCount > 0);
347
+ --m_jointCount;
348
+
349
+ // If the joint prevents collisions, then flag any contacts for filtering.
350
+ if (collideConnected == false)
351
+ {
352
+ b2ContactEdge* edge = bodyB->GetContactList();
353
+ while (edge)
354
+ {
355
+ if (edge->other == bodyA)
356
+ {
357
+ // Flag the contact for filtering at the next time step (where either
358
+ // body is awake).
359
+ edge->contact->FlagForFiltering();
360
+ }
361
+
362
+ edge = edge->next;
363
+ }
364
+ }
365
+ }
366
+
367
+ //
368
+ void b2World::SetAllowSleeping(bool flag)
369
+ {
370
+ if (flag == m_allowSleep)
371
+ {
372
+ return;
373
+ }
374
+
375
+ m_allowSleep = flag;
376
+ if (m_allowSleep == false)
377
+ {
378
+ for (b2Body* b = m_bodyList; b; b = b->m_next)
379
+ {
380
+ b->SetAwake(true);
381
+ }
382
+ }
383
+ }
384
+
385
+ // Find islands, integrate and solve constraints, solve position constraints
386
+ void b2World::Solve(const b2TimeStep& step)
387
+ {
388
+ m_profile.solveInit = 0.0f;
389
+ m_profile.solveVelocity = 0.0f;
390
+ m_profile.solvePosition = 0.0f;
391
+
392
+ // Size the island for the worst case.
393
+ b2Island island(m_bodyCount,
394
+ m_contactManager.m_contactCount,
395
+ m_jointCount,
396
+ &m_stackAllocator,
397
+ m_contactManager.m_contactListener);
398
+
399
+ // Clear all the island flags.
400
+ for (b2Body* b = m_bodyList; b; b = b->m_next)
401
+ {
402
+ b->m_flags &= ~b2Body::e_islandFlag;
403
+ }
404
+ for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
405
+ {
406
+ c->m_flags &= ~b2Contact::e_islandFlag;
407
+ }
408
+ for (b2Joint* j = m_jointList; j; j = j->m_next)
409
+ {
410
+ j->m_islandFlag = false;
411
+ }
412
+
413
+ // Build and simulate all awake islands.
414
+ int32 stackSize = m_bodyCount;
415
+ b2Body** stack = (b2Body**)m_stackAllocator.Allocate(stackSize * sizeof(b2Body*));
416
+ for (b2Body* seed = m_bodyList; seed; seed = seed->m_next)
417
+ {
418
+ if (seed->m_flags & b2Body::e_islandFlag)
419
+ {
420
+ continue;
421
+ }
422
+
423
+ if (seed->IsAwake() == false || seed->IsActive() == false)
424
+ {
425
+ continue;
426
+ }
427
+
428
+ // The seed can be dynamic or kinematic.
429
+ if (seed->GetType() == b2_staticBody)
430
+ {
431
+ continue;
432
+ }
433
+
434
+ // Reset island and stack.
435
+ island.Clear();
436
+ int32 stackCount = 0;
437
+ stack[stackCount++] = seed;
438
+ seed->m_flags |= b2Body::e_islandFlag;
439
+
440
+ // Perform a depth first search (DFS) on the constraint graph.
441
+ while (stackCount > 0)
442
+ {
443
+ // Grab the next body off the stack and add it to the island.
444
+ b2Body* b = stack[--stackCount];
445
+ b2Assert(b->IsActive() == true);
446
+ island.Add(b);
447
+
448
+ // Make sure the body is awake.
449
+ b->SetAwake(true);
450
+
451
+ // To keep islands as small as possible, we don't
452
+ // propagate islands across static bodies.
453
+ if (b->GetType() == b2_staticBody)
454
+ {
455
+ continue;
456
+ }
457
+
458
+ // Search all contacts connected to this body.
459
+ for (b2ContactEdge* ce = b->m_contactList; ce; ce = ce->next)
460
+ {
461
+ b2Contact* contact = ce->contact;
462
+
463
+ // Has this contact already been added to an island?
464
+ if (contact->m_flags & b2Contact::e_islandFlag)
465
+ {
466
+ continue;
467
+ }
468
+
469
+ // Is this contact solid and touching?
470
+ if (contact->IsEnabled() == false ||
471
+ contact->IsTouching() == false)
472
+ {
473
+ continue;
474
+ }
475
+
476
+ // Skip sensors.
477
+ bool sensorA = contact->m_fixtureA->m_isSensor;
478
+ bool sensorB = contact->m_fixtureB->m_isSensor;
479
+ if (sensorA || sensorB)
480
+ {
481
+ continue;
482
+ }
483
+
484
+ island.Add(contact);
485
+ contact->m_flags |= b2Contact::e_islandFlag;
486
+
487
+ b2Body* other = ce->other;
488
+
489
+ // Was the other body already added to this island?
490
+ if (other->m_flags & b2Body::e_islandFlag)
491
+ {
492
+ continue;
493
+ }
494
+
495
+ b2Assert(stackCount < stackSize);
496
+ stack[stackCount++] = other;
497
+ other->m_flags |= b2Body::e_islandFlag;
498
+ }
499
+
500
+ // Search all joints connect to this body.
501
+ for (b2JointEdge* je = b->m_jointList; je; je = je->next)
502
+ {
503
+ if (je->joint->m_islandFlag == true)
504
+ {
505
+ continue;
506
+ }
507
+
508
+ b2Body* other = je->other;
509
+
510
+ // Don't simulate joints connected to inactive bodies.
511
+ if (other->IsActive() == false)
512
+ {
513
+ continue;
514
+ }
515
+
516
+ island.Add(je->joint);
517
+ je->joint->m_islandFlag = true;
518
+
519
+ if (other->m_flags & b2Body::e_islandFlag)
520
+ {
521
+ continue;
522
+ }
523
+
524
+ b2Assert(stackCount < stackSize);
525
+ stack[stackCount++] = other;
526
+ other->m_flags |= b2Body::e_islandFlag;
527
+ }
528
+ }
529
+
530
+ b2Profile profile;
531
+ island.Solve(&profile, step, m_gravity, m_allowSleep);
532
+ m_profile.solveInit += profile.solveInit;
533
+ m_profile.solveVelocity += profile.solveVelocity;
534
+ m_profile.solvePosition += profile.solvePosition;
535
+
536
+ // Post solve cleanup.
537
+ for (int32 i = 0; i < island.m_bodyCount; ++i)
538
+ {
539
+ // Allow static bodies to participate in other islands.
540
+ b2Body* b = island.m_bodies[i];
541
+ if (b->GetType() == b2_staticBody)
542
+ {
543
+ b->m_flags &= ~b2Body::e_islandFlag;
544
+ }
545
+ }
546
+ }
547
+
548
+ m_stackAllocator.Free(stack);
549
+
550
+ {
551
+ b2Timer timer;
552
+ // Synchronize fixtures, check for out of range bodies.
553
+ for (b2Body* b = m_bodyList; b; b = b->GetNext())
554
+ {
555
+ // If a body was not in an island then it did not move.
556
+ if ((b->m_flags & b2Body::e_islandFlag) == 0)
557
+ {
558
+ continue;
559
+ }
560
+
561
+ if (b->GetType() == b2_staticBody)
562
+ {
563
+ continue;
564
+ }
565
+
566
+ // Update fixtures (for broad-phase).
567
+ b->SynchronizeFixtures();
568
+ }
569
+
570
+ // Look for new contacts.
571
+ m_contactManager.FindNewContacts();
572
+ m_profile.broadphase = timer.GetMilliseconds();
573
+ }
574
+ }
575
+
576
+ // Find TOI contacts and solve them.
577
+ void b2World::SolveTOI(const b2TimeStep& step)
578
+ {
579
+ b2Island island(2 * b2_maxTOIContacts, b2_maxTOIContacts, 0, &m_stackAllocator, m_contactManager.m_contactListener);
580
+
581
+ if (m_stepComplete)
582
+ {
583
+ for (b2Body* b = m_bodyList; b; b = b->m_next)
584
+ {
585
+ b->m_flags &= ~b2Body::e_islandFlag;
586
+ b->m_sweep.alpha0 = 0.0f;
587
+ }
588
+
589
+ for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
590
+ {
591
+ // Invalidate TOI
592
+ c->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
593
+ c->m_toiCount = 0;
594
+ c->m_toi = 1.0f;
595
+ }
596
+ }
597
+
598
+ // Find TOI events and solve them.
599
+ for (;;)
600
+ {
601
+ // Find the first TOI.
602
+ b2Contact* minContact = NULL;
603
+ float32 minAlpha = 1.0f;
604
+
605
+ for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
606
+ {
607
+ // Is this contact disabled?
608
+ if (c->IsEnabled() == false)
609
+ {
610
+ continue;
611
+ }
612
+
613
+ // Prevent excessive sub-stepping.
614
+ if (c->m_toiCount > b2_maxSubSteps)
615
+ {
616
+ continue;
617
+ }
618
+
619
+ float32 alpha = 1.0f;
620
+ if (c->m_flags & b2Contact::e_toiFlag)
621
+ {
622
+ // This contact has a valid cached TOI.
623
+ alpha = c->m_toi;
624
+ }
625
+ else
626
+ {
627
+ b2Fixture* fA = c->GetFixtureA();
628
+ b2Fixture* fB = c->GetFixtureB();
629
+
630
+ // Is there a sensor?
631
+ if (fA->IsSensor() || fB->IsSensor())
632
+ {
633
+ continue;
634
+ }
635
+
636
+ b2Body* bA = fA->GetBody();
637
+ b2Body* bB = fB->GetBody();
638
+
639
+ b2BodyType typeA = bA->m_type;
640
+ b2BodyType typeB = bB->m_type;
641
+ b2Assert(typeA == b2_dynamicBody || typeB == b2_dynamicBody);
642
+
643
+ bool activeA = bA->IsAwake() && typeA != b2_staticBody;
644
+ bool activeB = bB->IsAwake() && typeB != b2_staticBody;
645
+
646
+ // Is at least one body active (awake and dynamic or kinematic)?
647
+ if (activeA == false && activeB == false)
648
+ {
649
+ continue;
650
+ }
651
+
652
+ bool collideA = bA->IsBullet() || typeA != b2_dynamicBody;
653
+ bool collideB = bB->IsBullet() || typeB != b2_dynamicBody;
654
+
655
+ // Are these two non-bullet dynamic bodies?
656
+ if (collideA == false && collideB == false)
657
+ {
658
+ continue;
659
+ }
660
+
661
+ // Compute the TOI for this contact.
662
+ // Put the sweeps onto the same time interval.
663
+ float32 alpha0 = bA->m_sweep.alpha0;
664
+
665
+ if (bA->m_sweep.alpha0 < bB->m_sweep.alpha0)
666
+ {
667
+ alpha0 = bB->m_sweep.alpha0;
668
+ bA->m_sweep.Advance(alpha0);
669
+ }
670
+ else if (bB->m_sweep.alpha0 < bA->m_sweep.alpha0)
671
+ {
672
+ alpha0 = bA->m_sweep.alpha0;
673
+ bB->m_sweep.Advance(alpha0);
674
+ }
675
+
676
+ b2Assert(alpha0 < 1.0f);
677
+
678
+ int32 indexA = c->GetChildIndexA();
679
+ int32 indexB = c->GetChildIndexB();
680
+
681
+ // Compute the time of impact in interval [0, minTOI]
682
+ b2TOIInput input;
683
+ input.proxyA.Set(fA->GetShape(), indexA);
684
+ input.proxyB.Set(fB->GetShape(), indexB);
685
+ input.sweepA = bA->m_sweep;
686
+ input.sweepB = bB->m_sweep;
687
+ input.tMax = 1.0f;
688
+
689
+ b2TOIOutput output;
690
+ b2TimeOfImpact(&output, &input);
691
+
692
+ // Beta is the fraction of the remaining portion of the .
693
+ float32 beta = output.t;
694
+ if (output.state == b2TOIOutput::e_touching)
695
+ {
696
+ alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
697
+ }
698
+ else
699
+ {
700
+ alpha = 1.0f;
701
+ }
702
+
703
+ c->m_toi = alpha;
704
+ c->m_flags |= b2Contact::e_toiFlag;
705
+ }
706
+
707
+ if (alpha < minAlpha)
708
+ {
709
+ // This is the minimum TOI found so far.
710
+ minContact = c;
711
+ minAlpha = alpha;
712
+ }
713
+ }
714
+
715
+ if (minContact == NULL || 1.0f - 10.0f * b2_epsilon < minAlpha)
716
+ {
717
+ // No more TOI events. Done!
718
+ m_stepComplete = true;
719
+ break;
720
+ }
721
+
722
+ // Advance the bodies to the TOI.
723
+ b2Fixture* fA = minContact->GetFixtureA();
724
+ b2Fixture* fB = minContact->GetFixtureB();
725
+ b2Body* bA = fA->GetBody();
726
+ b2Body* bB = fB->GetBody();
727
+
728
+ b2Sweep backup1 = bA->m_sweep;
729
+ b2Sweep backup2 = bB->m_sweep;
730
+
731
+ bA->Advance(minAlpha);
732
+ bB->Advance(minAlpha);
733
+
734
+ // The TOI contact likely has some new contact points.
735
+ minContact->Update(m_contactManager.m_contactListener);
736
+ minContact->m_flags &= ~b2Contact::e_toiFlag;
737
+ ++minContact->m_toiCount;
738
+
739
+ // Is the contact solid?
740
+ if (minContact->IsEnabled() == false || minContact->IsTouching() == false)
741
+ {
742
+ // Restore the sweeps.
743
+ minContact->SetEnabled(false);
744
+ bA->m_sweep = backup1;
745
+ bB->m_sweep = backup2;
746
+ bA->SynchronizeTransform();
747
+ bB->SynchronizeTransform();
748
+ continue;
749
+ }
750
+
751
+ bA->SetAwake(true);
752
+ bB->SetAwake(true);
753
+
754
+ // Build the island
755
+ island.Clear();
756
+ island.Add(bA);
757
+ island.Add(bB);
758
+ island.Add(minContact);
759
+
760
+ bA->m_flags |= b2Body::e_islandFlag;
761
+ bB->m_flags |= b2Body::e_islandFlag;
762
+ minContact->m_flags |= b2Contact::e_islandFlag;
763
+
764
+ // Get contacts on bodyA and bodyB.
765
+ b2Body* bodies[2] = {bA, bB};
766
+ for (int32 i = 0; i < 2; ++i)
767
+ {
768
+ b2Body* body = bodies[i];
769
+ if (body->m_type == b2_dynamicBody)
770
+ {
771
+ for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
772
+ {
773
+ if (island.m_bodyCount == island.m_bodyCapacity)
774
+ {
775
+ break;
776
+ }
777
+
778
+ if (island.m_contactCount == island.m_contactCapacity)
779
+ {
780
+ break;
781
+ }
782
+
783
+ b2Contact* contact = ce->contact;
784
+
785
+ // Has this contact already been added to the island?
786
+ if (contact->m_flags & b2Contact::e_islandFlag)
787
+ {
788
+ continue;
789
+ }
790
+
791
+ // Only add static, kinematic, or bullet bodies.
792
+ b2Body* other = ce->other;
793
+ if (other->m_type == b2_dynamicBody &&
794
+ body->IsBullet() == false && other->IsBullet() == false)
795
+ {
796
+ continue;
797
+ }
798
+
799
+ // Skip sensors.
800
+ bool sensorA = contact->m_fixtureA->m_isSensor;
801
+ bool sensorB = contact->m_fixtureB->m_isSensor;
802
+ if (sensorA || sensorB)
803
+ {
804
+ continue;
805
+ }
806
+
807
+ // Tentatively advance the body to the TOI.
808
+ b2Sweep backup = other->m_sweep;
809
+ if ((other->m_flags & b2Body::e_islandFlag) == 0)
810
+ {
811
+ other->Advance(minAlpha);
812
+ }
813
+
814
+ // Update the contact points
815
+ contact->Update(m_contactManager.m_contactListener);
816
+
817
+ // Was the contact disabled by the user?
818
+ if (contact->IsEnabled() == false)
819
+ {
820
+ other->m_sweep = backup;
821
+ other->SynchronizeTransform();
822
+ continue;
823
+ }
824
+
825
+ // Are there contact points?
826
+ if (contact->IsTouching() == false)
827
+ {
828
+ other->m_sweep = backup;
829
+ other->SynchronizeTransform();
830
+ continue;
831
+ }
832
+
833
+ // Add the contact to the island
834
+ contact->m_flags |= b2Contact::e_islandFlag;
835
+ island.Add(contact);
836
+
837
+ // Has the other body already been added to the island?
838
+ if (other->m_flags & b2Body::e_islandFlag)
839
+ {
840
+ continue;
841
+ }
842
+
843
+ // Add the other body to the island.
844
+ other->m_flags |= b2Body::e_islandFlag;
845
+
846
+ if (other->m_type != b2_staticBody)
847
+ {
848
+ other->SetAwake(true);
849
+ }
850
+
851
+ island.Add(other);
852
+ }
853
+ }
854
+ }
855
+
856
+ b2TimeStep subStep;
857
+ subStep.dt = (1.0f - minAlpha) * step.dt;
858
+ subStep.inv_dt = 1.0f / subStep.dt;
859
+ subStep.dtRatio = 1.0f;
860
+ subStep.positionIterations = 20;
861
+ subStep.velocityIterations = step.velocityIterations;
862
+ subStep.warmStarting = false;
863
+ island.SolveTOI(subStep, bA->m_islandIndex, bB->m_islandIndex);
864
+
865
+ // Reset island flags and synchronize broad-phase proxies.
866
+ for (int32 i = 0; i < island.m_bodyCount; ++i)
867
+ {
868
+ b2Body* body = island.m_bodies[i];
869
+ body->m_flags &= ~b2Body::e_islandFlag;
870
+
871
+ if (body->m_type != b2_dynamicBody)
872
+ {
873
+ continue;
874
+ }
875
+
876
+ body->SynchronizeFixtures();
877
+
878
+ // Invalidate all contact TOIs on this displaced body.
879
+ for (b2ContactEdge* ce = body->m_contactList; ce; ce = ce->next)
880
+ {
881
+ ce->contact->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
882
+ }
883
+ }
884
+
885
+ // Commit fixture proxy movements to the broad-phase so that new contacts are created.
886
+ // Also, some contacts can be destroyed.
887
+ m_contactManager.FindNewContacts();
888
+
889
+ if (m_subStepping)
890
+ {
891
+ m_stepComplete = false;
892
+ break;
893
+ }
894
+ }
895
+ }
896
+
897
+ void b2World::Step(float32 dt, int32 velocityIterations, int32 positionIterations)
898
+ {
899
+ b2Timer stepTimer;
900
+
901
+ // If new fixtures were added, we need to find the new contacts.
902
+ if (m_flags & e_newFixture)
903
+ {
904
+ m_contactManager.FindNewContacts();
905
+ m_flags &= ~e_newFixture;
906
+ }
907
+
908
+ m_flags |= e_locked;
909
+
910
+ b2TimeStep step;
911
+ step.dt = dt;
912
+ step.velocityIterations = velocityIterations;
913
+ step.positionIterations = positionIterations;
914
+ if (dt > 0.0f)
915
+ {
916
+ step.inv_dt = 1.0f / dt;
917
+ }
918
+ else
919
+ {
920
+ step.inv_dt = 0.0f;
921
+ }
922
+
923
+ step.dtRatio = m_inv_dt0 * dt;
924
+
925
+ step.warmStarting = m_warmStarting;
926
+
927
+ // Update contacts. This is where some contacts are destroyed.
928
+ {
929
+ b2Timer timer;
930
+ m_contactManager.Collide();
931
+ m_profile.collide = timer.GetMilliseconds();
932
+ }
933
+
934
+ // Integrate velocities, solve velocity constraints, and integrate positions.
935
+ if (m_stepComplete && step.dt > 0.0f)
936
+ {
937
+ b2Timer timer;
938
+ Solve(step);
939
+ m_profile.solve = timer.GetMilliseconds();
940
+ }
941
+
942
+ // Handle TOI events.
943
+ if (m_continuousPhysics && step.dt > 0.0f)
944
+ {
945
+ b2Timer timer;
946
+ SolveTOI(step);
947
+ m_profile.solveTOI = timer.GetMilliseconds();
948
+ }
949
+
950
+ if (step.dt > 0.0f)
951
+ {
952
+ m_inv_dt0 = step.inv_dt;
953
+ }
954
+
955
+ if (m_flags & e_clearForces)
956
+ {
957
+ ClearForces();
958
+ }
959
+
960
+ m_flags &= ~e_locked;
961
+
962
+ m_profile.step = stepTimer.GetMilliseconds();
963
+ }
964
+
965
+ void b2World::ClearForces()
966
+ {
967
+ for (b2Body* body = m_bodyList; body; body = body->GetNext())
968
+ {
969
+ body->m_force.SetZero();
970
+ body->m_torque = 0.0f;
971
+ }
972
+ }
973
+
974
+ struct b2WorldQueryWrapper
975
+ {
976
+ bool QueryCallback(int32 proxyId)
977
+ {
978
+ b2FixtureProxy* proxy = (b2FixtureProxy*)broadPhase->GetUserData(proxyId);
979
+ return callback->ReportFixture(proxy->fixture);
980
+ }
981
+
982
+ const b2BroadPhase* broadPhase;
983
+ b2QueryCallback* callback;
984
+ };
985
+
986
+ void b2World::QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const
987
+ {
988
+ b2WorldQueryWrapper wrapper;
989
+ wrapper.broadPhase = &m_contactManager.m_broadPhase;
990
+ wrapper.callback = callback;
991
+ m_contactManager.m_broadPhase.Query(&wrapper, aabb);
992
+ }
993
+
994
+ struct b2WorldRayCastWrapper
995
+ {
996
+ float32 RayCastCallback(const b2RayCastInput& input, int32 proxyId)
997
+ {
998
+ void* userData = broadPhase->GetUserData(proxyId);
999
+ b2FixtureProxy* proxy = (b2FixtureProxy*)userData;
1000
+ b2Fixture* fixture = proxy->fixture;
1001
+ int32 index = proxy->childIndex;
1002
+ b2RayCastOutput output;
1003
+ bool hit = fixture->RayCast(&output, input, index);
1004
+
1005
+ if (hit)
1006
+ {
1007
+ float32 fraction = output.fraction;
1008
+ b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
1009
+ return callback->ReportFixture(fixture, point, output.normal, fraction);
1010
+ }
1011
+
1012
+ return input.maxFraction;
1013
+ }
1014
+
1015
+ const b2BroadPhase* broadPhase;
1016
+ b2RayCastCallback* callback;
1017
+ };
1018
+
1019
+ void b2World::RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const
1020
+ {
1021
+ b2WorldRayCastWrapper wrapper;
1022
+ wrapper.broadPhase = &m_contactManager.m_broadPhase;
1023
+ wrapper.callback = callback;
1024
+ b2RayCastInput input;
1025
+ input.maxFraction = 1.0f;
1026
+ input.p1 = point1;
1027
+ input.p2 = point2;
1028
+ m_contactManager.m_broadPhase.RayCast(&wrapper, input);
1029
+ }
1030
+
1031
+ void b2World::DrawShape(b2Fixture* fixture, const b2Transform& xf, const b2Color& color)
1032
+ {
1033
+ switch (fixture->GetType())
1034
+ {
1035
+ case b2Shape::e_circle:
1036
+ {
1037
+ b2CircleShape* circle = (b2CircleShape*)fixture->GetShape();
1038
+
1039
+ b2Vec2 center = b2Mul(xf, circle->m_p);
1040
+ float32 radius = circle->m_radius;
1041
+ b2Vec2 axis = b2Mul(xf.q, b2Vec2(1.0f, 0.0f));
1042
+
1043
+ g_debugDraw->DrawSolidCircle(center, radius, axis, color);
1044
+ }
1045
+ break;
1046
+
1047
+ case b2Shape::e_edge:
1048
+ {
1049
+ b2EdgeShape* edge = (b2EdgeShape*)fixture->GetShape();
1050
+ b2Vec2 v1 = b2Mul(xf, edge->m_vertex1);
1051
+ b2Vec2 v2 = b2Mul(xf, edge->m_vertex2);
1052
+ g_debugDraw->DrawSegment(v1, v2, color);
1053
+ }
1054
+ break;
1055
+
1056
+ case b2Shape::e_chain:
1057
+ {
1058
+ b2ChainShape* chain = (b2ChainShape*)fixture->GetShape();
1059
+ int32 count = chain->m_count;
1060
+ const b2Vec2* vertices = chain->m_vertices;
1061
+
1062
+ b2Vec2 v1 = b2Mul(xf, vertices[0]);
1063
+ for (int32 i = 1; i < count; ++i)
1064
+ {
1065
+ b2Vec2 v2 = b2Mul(xf, vertices[i]);
1066
+ g_debugDraw->DrawSegment(v1, v2, color);
1067
+ g_debugDraw->DrawCircle(v1, 0.05f, color);
1068
+ v1 = v2;
1069
+ }
1070
+ }
1071
+ break;
1072
+
1073
+ case b2Shape::e_polygon:
1074
+ {
1075
+ b2PolygonShape* poly = (b2PolygonShape*)fixture->GetShape();
1076
+ int32 vertexCount = poly->m_count;
1077
+ b2Assert(vertexCount <= b2_maxPolygonVertices);
1078
+ b2Vec2 vertices[b2_maxPolygonVertices];
1079
+
1080
+ for (int32 i = 0; i < vertexCount; ++i)
1081
+ {
1082
+ vertices[i] = b2Mul(xf, poly->m_vertices[i]);
1083
+ }
1084
+
1085
+ g_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
1086
+ }
1087
+ break;
1088
+
1089
+ default:
1090
+ break;
1091
+ }
1092
+ }
1093
+
1094
+ void b2World::DrawJoint(b2Joint* joint)
1095
+ {
1096
+ b2Body* bodyA = joint->GetBodyA();
1097
+ b2Body* bodyB = joint->GetBodyB();
1098
+ const b2Transform& xf1 = bodyA->GetTransform();
1099
+ const b2Transform& xf2 = bodyB->GetTransform();
1100
+ b2Vec2 x1 = xf1.p;
1101
+ b2Vec2 x2 = xf2.p;
1102
+ b2Vec2 p1 = joint->GetAnchorA();
1103
+ b2Vec2 p2 = joint->GetAnchorB();
1104
+
1105
+ b2Color color(0.5f, 0.8f, 0.8f);
1106
+
1107
+ switch (joint->GetType())
1108
+ {
1109
+ case e_distanceJoint:
1110
+ g_debugDraw->DrawSegment(p1, p2, color);
1111
+ break;
1112
+
1113
+ case e_pulleyJoint:
1114
+ {
1115
+ b2PulleyJoint* pulley = (b2PulleyJoint*)joint;
1116
+ b2Vec2 s1 = pulley->GetGroundAnchorA();
1117
+ b2Vec2 s2 = pulley->GetGroundAnchorB();
1118
+ g_debugDraw->DrawSegment(s1, p1, color);
1119
+ g_debugDraw->DrawSegment(s2, p2, color);
1120
+ g_debugDraw->DrawSegment(s1, s2, color);
1121
+ }
1122
+ break;
1123
+
1124
+ case e_mouseJoint:
1125
+ // don't draw this
1126
+ break;
1127
+
1128
+ default:
1129
+ g_debugDraw->DrawSegment(x1, p1, color);
1130
+ g_debugDraw->DrawSegment(p1, p2, color);
1131
+ g_debugDraw->DrawSegment(x2, p2, color);
1132
+ }
1133
+ }
1134
+
1135
+ void b2World::DrawDebugData()
1136
+ {
1137
+ if (g_debugDraw == NULL)
1138
+ {
1139
+ return;
1140
+ }
1141
+
1142
+ uint32 flags = g_debugDraw->GetFlags();
1143
+
1144
+ if (flags & b2Draw::e_shapeBit)
1145
+ {
1146
+ for (b2Body* b = m_bodyList; b; b = b->GetNext())
1147
+ {
1148
+ const b2Transform& xf = b->GetTransform();
1149
+ for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
1150
+ {
1151
+ if (b->IsActive() == false)
1152
+ {
1153
+ DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.3f));
1154
+ }
1155
+ else if (b->GetType() == b2_staticBody)
1156
+ {
1157
+ DrawShape(f, xf, b2Color(0.5f, 0.9f, 0.5f));
1158
+ }
1159
+ else if (b->GetType() == b2_kinematicBody)
1160
+ {
1161
+ DrawShape(f, xf, b2Color(0.5f, 0.5f, 0.9f));
1162
+ }
1163
+ else if (b->IsAwake() == false)
1164
+ {
1165
+ DrawShape(f, xf, b2Color(0.6f, 0.6f, 0.6f));
1166
+ }
1167
+ else
1168
+ {
1169
+ DrawShape(f, xf, b2Color(0.9f, 0.7f, 0.7f));
1170
+ }
1171
+ }
1172
+ }
1173
+ }
1174
+
1175
+ if (flags & b2Draw::e_jointBit)
1176
+ {
1177
+ for (b2Joint* j = m_jointList; j; j = j->GetNext())
1178
+ {
1179
+ DrawJoint(j);
1180
+ }
1181
+ }
1182
+
1183
+ if (flags & b2Draw::e_pairBit)
1184
+ {
1185
+ b2Color color(0.3f, 0.9f, 0.9f);
1186
+ for (b2Contact* c = m_contactManager.m_contactList; c; c = c->GetNext())
1187
+ {
1188
+ //b2Fixture* fixtureA = c->GetFixtureA();
1189
+ //b2Fixture* fixtureB = c->GetFixtureB();
1190
+
1191
+ //b2Vec2 cA = fixtureA->GetAABB().GetCenter();
1192
+ //b2Vec2 cB = fixtureB->GetAABB().GetCenter();
1193
+
1194
+ //g_debugDraw->DrawSegment(cA, cB, color);
1195
+ }
1196
+ }
1197
+
1198
+ if (flags & b2Draw::e_aabbBit)
1199
+ {
1200
+ b2Color color(0.9f, 0.3f, 0.9f);
1201
+ b2BroadPhase* bp = &m_contactManager.m_broadPhase;
1202
+
1203
+ for (b2Body* b = m_bodyList; b; b = b->GetNext())
1204
+ {
1205
+ if (b->IsActive() == false)
1206
+ {
1207
+ continue;
1208
+ }
1209
+
1210
+ for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
1211
+ {
1212
+ for (int32 i = 0; i < f->m_proxyCount; ++i)
1213
+ {
1214
+ b2FixtureProxy* proxy = f->m_proxies + i;
1215
+ b2AABB aabb = bp->GetFatAABB(proxy->proxyId);
1216
+ b2Vec2 vs[4];
1217
+ vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y);
1218
+ vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y);
1219
+ vs[2].Set(aabb.upperBound.x, aabb.upperBound.y);
1220
+ vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
1221
+
1222
+ g_debugDraw->DrawPolygon(vs, 4, color);
1223
+ }
1224
+ }
1225
+ }
1226
+ }
1227
+
1228
+ if (flags & b2Draw::e_centerOfMassBit)
1229
+ {
1230
+ for (b2Body* b = m_bodyList; b; b = b->GetNext())
1231
+ {
1232
+ b2Transform xf = b->GetTransform();
1233
+ xf.p = b->GetWorldCenter();
1234
+ g_debugDraw->DrawTransform(xf);
1235
+ }
1236
+ }
1237
+ }
1238
+
1239
+ int32 b2World::GetProxyCount() const
1240
+ {
1241
+ return m_contactManager.m_broadPhase.GetProxyCount();
1242
+ }
1243
+
1244
+ int32 b2World::GetTreeHeight() const
1245
+ {
1246
+ return m_contactManager.m_broadPhase.GetTreeHeight();
1247
+ }
1248
+
1249
+ int32 b2World::GetTreeBalance() const
1250
+ {
1251
+ return m_contactManager.m_broadPhase.GetTreeBalance();
1252
+ }
1253
+
1254
+ float32 b2World::GetTreeQuality() const
1255
+ {
1256
+ return m_contactManager.m_broadPhase.GetTreeQuality();
1257
+ }
1258
+
1259
+ void b2World::ShiftOrigin(const b2Vec2& newOrigin)
1260
+ {
1261
+ b2Assert((m_flags & e_locked) == 0);
1262
+ if ((m_flags & e_locked) == e_locked)
1263
+ {
1264
+ return;
1265
+ }
1266
+
1267
+ for (b2Body* b = m_bodyList; b; b = b->m_next)
1268
+ {
1269
+ b->m_xf.p -= newOrigin;
1270
+ b->m_sweep.c0 -= newOrigin;
1271
+ b->m_sweep.c -= newOrigin;
1272
+ }
1273
+
1274
+ for (b2Joint* j = m_jointList; j; j = j->m_next)
1275
+ {
1276
+ j->ShiftOrigin(newOrigin);
1277
+ }
1278
+
1279
+ m_contactManager.m_broadPhase.ShiftOrigin(newOrigin);
1280
+ }
1281
+
1282
+ void b2World::Dump()
1283
+ {
1284
+ if ((m_flags & e_locked) == e_locked)
1285
+ {
1286
+ return;
1287
+ }
1288
+
1289
+ b2Log("b2Vec2 g(%.15lef, %.15lef);\n", m_gravity.x, m_gravity.y);
1290
+ b2Log("m_world->SetGravity(g);\n");
1291
+
1292
+ b2Log("b2Body** bodies = (b2Body**)b2Alloc(%d * sizeof(b2Body*));\n", m_bodyCount);
1293
+ b2Log("b2Joint** joints = (b2Joint**)b2Alloc(%d * sizeof(b2Joint*));\n", m_jointCount);
1294
+ int32 i = 0;
1295
+ for (b2Body* b = m_bodyList; b; b = b->m_next)
1296
+ {
1297
+ b->m_islandIndex = i;
1298
+ b->Dump();
1299
+ ++i;
1300
+ }
1301
+
1302
+ i = 0;
1303
+ for (b2Joint* j = m_jointList; j; j = j->m_next)
1304
+ {
1305
+ j->m_index = i;
1306
+ ++i;
1307
+ }
1308
+
1309
+ // First pass on joints, skip gear joints.
1310
+ for (b2Joint* j = m_jointList; j; j = j->m_next)
1311
+ {
1312
+ if (j->m_type == e_gearJoint)
1313
+ {
1314
+ continue;
1315
+ }
1316
+
1317
+ b2Log("{\n");
1318
+ j->Dump();
1319
+ b2Log("}\n");
1320
+ }
1321
+
1322
+ // Second pass on joints, only gear joints.
1323
+ for (b2Joint* j = m_jointList; j; j = j->m_next)
1324
+ {
1325
+ if (j->m_type != e_gearJoint)
1326
+ {
1327
+ continue;
1328
+ }
1329
+
1330
+ b2Log("{\n");
1331
+ j->Dump();
1332
+ b2Log("}\n");
1333
+ }
1334
+
1335
+ b2Log("b2Free(joints);\n");
1336
+ b2Log("b2Free(bodies);\n");
1337
+ b2Log("joints = NULL;\n");
1338
+ b2Log("bodies = NULL;\n");
1339
+ }