reflexion 0.1.7 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
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
+ }