Browse Source

Merge branch 'master' into development

Peter Robinson 5 years ago
parent
commit
ab7a032b22
100 changed files with 22660 additions and 7976 deletions
  1. 12 4
      README.md
  2. BIN
      engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db-shm
  3. 30 1
      engine/compilers/VisualStudio 2017/Torque 2D.vcxproj
  4. 85 1
      engine/compilers/VisualStudio 2017/Torque 2D.vcxproj.filters
  5. 3 4
      engine/compilers/VisualStudio 2019/Torque 2D.rc
  6. 31 2
      engine/compilers/VisualStudio 2019/Torque 2D.vcxproj
  7. 87 1
      engine/compilers/VisualStudio 2019/Torque 2D.vcxproj.filters
  8. 2 2
      engine/compilers/VisualStudio 2019/libogg.vcxproj
  9. 2 2
      engine/compilers/VisualStudio 2019/libvorbis.vcxproj
  10. 2 2
      engine/compilers/VisualStudio 2019/ljpeg.vcxproj
  11. 2 2
      engine/compilers/VisualStudio 2019/lpng.vcxproj
  12. 2 2
      engine/compilers/VisualStudio 2019/zlib.vcxproj
  13. 384 322
      engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj
  14. 62 0
      engine/source/2d/assets/ParticleAssetEmitter.cc
  15. 57 1
      engine/source/2d/assets/ParticleAssetEmitter.h
  16. 57 0
      engine/source/2d/assets/ParticleAssetEmitter_ScriptBinding.h
  17. 5 0
      engine/source/2d/core/ParticleSystem.h
  18. 3 0
      engine/source/2d/scene/Scene.cc
  19. 1 1
      engine/source/2d/scene/Scene.h
  20. 239 0
      engine/source/2d/sceneobject/LightObject.cc
  21. 96 0
      engine/source/2d/sceneobject/LightObject.h
  22. 52 0
      engine/source/2d/sceneobject/LightObject_ScriptBinding.h
  23. 16 4
      engine/source/2d/sceneobject/ParticlePlayer.cc
  24. 285 0
      engine/source/2d/sceneobject/Path.cc
  25. 113 0
      engine/source/2d/sceneobject/Path.h
  26. 134 0
      engine/source/2d/sceneobject/Path_ScriptBinding.h
  27. 1 1
      engine/source/2d/sceneobject/SceneObject.cc
  28. 68 68
      engine/source/Box2D/Box2D.h
  29. 203 188
      engine/source/Box2D/Collision/Shapes/b2ChainShape.cpp
  30. 106 102
      engine/source/Box2D/Collision/Shapes/b2ChainShape.h
  31. 111 100
      engine/source/Box2D/Collision/Shapes/b2CircleShape.cpp
  32. 107 91
      engine/source/Box2D/Collision/Shapes/b2CircleShape.h
  33. 168 139
      engine/source/Box2D/Collision/Shapes/b2EdgeShape.cpp
  34. 94 74
      engine/source/Box2D/Collision/Shapes/b2EdgeShape.h
  35. 504 434
      engine/source/Box2D/Collision/Shapes/b2PolygonShape.cpp
  36. 134 101
      engine/source/Box2D/Collision/Shapes/b2PolygonShape.h
  37. 109 101
      engine/source/Box2D/Collision/Shapes/b2Shape.h
  38. 119 121
      engine/source/Box2D/Collision/b2BroadPhase.cpp
  39. 257 257
      engine/source/Box2D/Collision/b2BroadPhase.h
  40. 154 154
      engine/source/Box2D/Collision/b2CollideCircle.cpp
  41. 698 698
      engine/source/Box2D/Collision/b2CollideEdge.cpp
  42. 239 317
      engine/source/Box2D/Collision/b2CollidePolygon.cpp
  43. 252 249
      engine/source/Box2D/Collision/b2Collision.cpp
  44. 277 276
      engine/source/Box2D/Collision/b2Collision.h
  45. 614 603
      engine/source/Box2D/Collision/b2Distance.cpp
  46. 141 141
      engine/source/Box2D/Collision/b2Distance.h
  47. 784 781
      engine/source/Box2D/Collision/b2DynamicTree.cpp
  48. 289 289
      engine/source/Box2D/Collision/b2DynamicTree.h
  49. 487 476
      engine/source/Box2D/Collision/b2TimeOfImpact.cpp
  50. 58 58
      engine/source/Box2D/Collision/b2TimeOfImpact.h
  51. 225 217
      engine/source/Box2D/Common/b2BlockAllocator.cpp
  52. 68 62
      engine/source/Box2D/Common/b2BlockAllocator.h
  53. 44 44
      engine/source/Box2D/Common/b2Draw.cpp
  54. 92 86
      engine/source/Box2D/Common/b2Draw.h
  55. 57 0
      engine/source/Box2D/Common/b2FreeList.cpp
  56. 113 0
      engine/source/Box2D/Common/b2FreeList.h
  57. 200 0
      engine/source/Box2D/Common/b2GrowableBuffer.h
  58. 87 85
      engine/source/Box2D/Common/b2GrowableStack.h
  59. 369 0
      engine/source/Box2D/Common/b2IntrusiveList.h
  60. 94 94
      engine/source/Box2D/Common/b2Math.cpp
  61. 800 731
      engine/source/Box2D/Common/b2Math.h
  62. 136 44
      engine/source/Box2D/Common/b2Settings.cpp
  63. 267 150
      engine/source/Box2D/Common/b2Settings.h
  64. 244 0
      engine/source/Box2D/Common/b2SlabAllocator.h
  65. 120 83
      engine/source/Box2D/Common/b2StackAllocator.cpp
  66. 64 60
      engine/source/Box2D/Common/b2StackAllocator.h
  67. 67 0
      engine/source/Box2D/Common/b2Stat.cpp
  68. 57 0
      engine/source/Box2D/Common/b2Stat.h
  69. 134 100
      engine/source/Box2D/Common/b2Timer.cpp
  70. 50 50
      engine/source/Box2D/Common/b2Timer.h
  71. 111 0
      engine/source/Box2D/Common/b2TrackedBlock.cpp
  72. 92 0
      engine/source/Box2D/Common/b2TrackedBlock.h
  73. 2350 0
      engine/source/Box2D/Documentation/API-Ref/doxyfile
  74. 19 0
      engine/source/Box2D/Documentation/Building/Building.md
  75. 117 0
      engine/source/Box2D/Documentation/Building/BuildingAndroid.md
  76. 92 0
      engine/source/Box2D/Documentation/Building/BuildingJavaScript.md
  77. 79 0
      engine/source/Box2D/Documentation/Building/BuildingLinux.md
  78. 62 0
      engine/source/Box2D/Documentation/Building/BuildingOSX.md
  79. 64 0
      engine/source/Box2D/Documentation/Building/BuildingWindows.md
  80. 32 0
      engine/source/Box2D/Documentation/Building/BuildingiOS.md
  81. 40 0
      engine/source/Box2D/Documentation/Building/PortingFromBox2D.md
  82. 2357 0
      engine/source/Box2D/Documentation/Building/doxyfile
  83. 274 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter01_Introduction.md
  84. 290 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter02_Hello_Box2D.md
  85. 93 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter03_Common.md
  86. 438 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter04_Collision_Module.md
  87. 37 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter05_Dynamics_Module.md
  88. 363 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter06_Bodies.md
  89. 201 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter07_Fixtures.md
  90. 434 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter08_Joints.md
  91. 364 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter09_Contacts.md
  92. 322 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter10_World.md
  93. 729 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter11_Particles.md
  94. 178 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter12_Loose_Ends.md
  95. 28 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter13_Debug_Drawing.md
  96. 33 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter14_Limitations.md
  97. 13 0
      engine/source/Box2D/Documentation/Programmers-Guide/Chapter15_References.md
  98. 11 0
      engine/source/Box2D/Documentation/Programmers-Guide/ContentLicense.md
  99. 17 0
      engine/source/Box2D/Documentation/Programmers-Guide/Logo.md
  100. 2396 0
      engine/source/Box2D/Documentation/Programmers-Guide/doxyfile

+ 12 - 4
README.md

@@ -1,4 +1,4 @@
-![Torque Logo](http://static.garagegames.com/static/pg/logokits/Torque-Logo_H.png)
+![Torque Logo](modules/Sandbox/1/assets/t2d.png)
 ## Torque 2D 3.4
 
 MIT Licensed Open Source version of Torque 2D from GarageGames. Maintained by the T2D Steering Committee and contributions from the community.
@@ -15,7 +15,7 @@ Here is an overview of the branches found in the Torque 2D repository:
 
 ### Precompiled Version
 
-If you do not wish to compile the source code yourself, precompiled binary files for Windows and OSX are available from the [Torque 2D Release Page](https://github.com/GarageGames/Torque2D/releases).
+If you do not wish to compile the source code yourself, precompiled binary files for Windows and OSX are available from the [Torque 2D Release Page](https://github.com/TorqueGameEngines/Torque2D/releases).
 
 ### Building the Source
 
@@ -28,7 +28,7 @@ After downloading a copy of the source code, the following project files for eac
 * **Android:** Android Studio
 * **Web:** Emscripten/Cmake
 
-See the [wiki](https://github.com/GarageGames/Torque2D/wiki) for available guides on platform setup and development.
+See the [wiki](https://github.com/TorqueGameEngines/Torque2D/wiki) for available guides on platform setup and development.
 
 ### Batteries Included
 
@@ -40,7 +40,7 @@ The Sandbox is also an excellent framework for rapidly prototyping your own game
 
 ### Documentation
 
-All documentation for the open source version of Torque 2D can be found on our [Github wiki page](https://github.com/GarageGames/Torque2D/wiki). It contains many tutorials, detailed technical information on engine systems, a script reference guide automatically generated from the source code, and articles on how to contribute to our open source development.
+All documentation for the open source version of Torque 2D can be found on our [Github wiki page](https://github.com/TorqueGameEngines/Torque2D/wiki). It contains many tutorials, detailed technical information on engine systems, a script reference guide automatically generated from the source code, and articles on how to contribute to our open source development.
 
 ### Community
 
@@ -54,6 +54,14 @@ You also might be able to find useful information on the less active GarageGames
 * [Torque 2D Professional Forum](http://www.garagegames.com/community/forums/85)
 * [GarageGames Community Blogs](http://www.garagegames.com/community/blogs)
 
+### Support
+
+Torque 2D is completely free to use, but like all things, it takes time and energy to maintain and develop. You can support T2D by becoming a sponsor on Patreon. Doing so ensures that T2D will continue receiving the attention it needs to remain competitive.
+
+[Become a Patron](https://www.patreon.com/bePatron?u=15485520)
+
+You can also support development directly by submitting pull requests or joining the steering committee! See the wiki for details.
+
 # License
 Copyright (c) 2012 GarageGames, LLC
 

BIN
engine/compilers/VisualStudio 2017/.vs/Torque 2D/v15/Solution.VC.db-shm


+ 30 - 1
engine/compilers/VisualStudio 2017/Torque 2D.vcxproj

@@ -272,10 +272,12 @@
     <ClCompile Include="..\..\source\2d\gui\SceneWindow.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\CompositeSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ParticlePlayer.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\Path.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectSet.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Scroller.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\LightObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ShapeVector.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
@@ -316,10 +318,13 @@
     <ClCompile Include="..\..\source\Box2D\Collision\Shapes\b2PolygonShape.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2BlockAllocator.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Draw.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2FreeList.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Math.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Settings.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2StackAllocator.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2Stat.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Timer.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2TrackedBlock.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Body.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2ContactManager.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Fixture.cpp" />
@@ -347,6 +352,11 @@
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2RopeJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WheelJoint.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2Particle.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleAssembly.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleGroup.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleSystem.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.cpp" />
     <ClCompile Include="..\..\source\Box2D\Rope\b2Rope.cpp" />
     <ClCompile Include="..\..\source\collection\bitTables.cc" />
     <ClCompile Include="..\..\source\collection\hashTable.cc" />
@@ -694,6 +704,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\Path.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\Path_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectList.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectMoveToEvent.h" />
@@ -703,6 +715,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ShapeVector.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ShapeVector_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject.h" />
@@ -768,11 +782,17 @@
     <ClInclude Include="..\..\source\Box2D\Collision\Shapes\b2Shape.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2BlockAllocator.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Draw.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2FreeList.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2GrowableBuffer.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2GrowableStack.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2IntrusiveList.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Math.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Settings.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2SlabAllocator.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2StackAllocator.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2Stat.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Timer.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2TrackedBlock.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2Body.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2ContactManager.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2Fixture.h" />
@@ -801,6 +821,12 @@
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2RopeJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WheelJoint.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2Particle.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleAssembly.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleGroup.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleSystem.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2StackQueue.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.h" />
     <ClInclude Include="..\..\source\Box2D\Rope\b2Rope.h" />
     <ClInclude Include="..\..\source\collection\bitMatrix.h" />
     <ClInclude Include="..\..\source\collection\bitSet.h" />
@@ -1286,7 +1312,10 @@
   <ItemGroup>
     <Image Include="Torque 2D.ico" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\source\Box2D\Particle\b2ParticleAssembly.neon.s" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 85 - 1
engine/compilers/VisualStudio 2017/Torque 2D.vcxproj.filters

@@ -199,6 +199,9 @@
     <Filter Include="bitmapFont">
       <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Box2D\Particle">
+      <UniqueIdentifier>{b2903a96-6c49-4961-82a8-f1832989d4a4}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1383,6 +1386,35 @@
     </ClCompile>
     <ClCompile Include="..\..\source\gui\guiTextCtrl.cc">
       <Filter>gui</Filter>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2Particle.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleAssembly.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleGroup.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleSystem.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Common\b2FreeList.cpp">
+      <Filter>Box2D\Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Common\b2Stat.cpp">
+      <Filter>Box2D\Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Common\b2TrackedBlock.cpp">
+      <Filter>Box2D\Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\LightObject.cc">
+      <Filter>2d\sceneobject</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\Path.cc">
+      <Filter>2d\sceneobject</Filter>
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
@@ -3102,6 +3134,53 @@
     </ClInclude>
     <ClInclude Include="..\..\source\gui\guiTextCtrl.h">
       <Filter>gui</Filter>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2Particle.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleAssembly.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleGroup.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleSystem.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2StackQueue.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2FreeList.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2GrowableBuffer.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2IntrusiveList.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2SlabAllocator.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2Stat.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2TrackedBlock.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\Path.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\Path_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
     </ClInclude>
   </ItemGroup>
   <ItemGroup>
@@ -3124,4 +3203,9 @@
   <ItemGroup>
     <Image Include="Torque 2D.ico" />
   </ItemGroup>
-</Project>
+  <ItemGroup>
+    <None Include="..\..\source\Box2D\Particle\b2ParticleAssembly.neon.s">
+      <Filter>Box2D\Particle</Filter>
+    </None>
+  </ItemGroup>
+</Project>

+ 3 - 4
engine/compilers/VisualStudio 2019/Torque 2D.rc

@@ -36,18 +36,18 @@ IDI_TORQUE2D               ICON    DISCARDABLE     "Torque 2D.ico"
 // TEXTINCLUDE
 //
 
-1 TEXTINCLUDE DISCARDABLE 
+1 TEXTINCLUDE DISCARDABLE
 BEGIN
     "resource.h\0"
 END
 
-2 TEXTINCLUDE DISCARDABLE 
+2 TEXTINCLUDE DISCARDABLE
 BEGIN
     "#include ""afxres.h""\r\n"
     "\0"
 END
 
-3 TEXTINCLUDE DISCARDABLE 
+3 TEXTINCLUDE DISCARDABLE
 BEGIN
     "\r\n"
     "\0"
@@ -107,4 +107,3 @@ END
 
 /////////////////////////////////////////////////////////////////////////////
 #endif    // not APSTUDIO_INVOKED
-

+ 31 - 2
engine/compilers/VisualStudio 2019/Torque 2D.vcxproj

@@ -18,7 +18,7 @@
     <ProjectGuid>{1564A07D-230E-4C90-AEE6-52AC9A58D6C9}</ProjectGuid>
     <RootNamespace>TorqueGame</RootNamespace>
     <ProjectName>Torque2D</ProjectName>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -272,10 +272,12 @@
     <ClCompile Include="..\..\source\2d\gui\SceneWindow.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\CompositeSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ParticlePlayer.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\Path.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectSet.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Scroller.cc" />
+    <ClCompile Include="..\..\source\2d\sceneobject\LightObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ShapeVector.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
@@ -316,10 +318,13 @@
     <ClCompile Include="..\..\source\Box2D\Collision\Shapes\b2PolygonShape.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2BlockAllocator.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Draw.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2FreeList.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Math.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Settings.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2StackAllocator.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2Stat.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Timer.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2TrackedBlock.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Body.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2ContactManager.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Fixture.cpp" />
@@ -347,6 +352,11 @@
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2RopeJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WheelJoint.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2Particle.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleAssembly.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleGroup.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleSystem.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.cpp" />
     <ClCompile Include="..\..\source\Box2D\Rope\b2Rope.cpp" />
     <ClCompile Include="..\..\source\collection\bitTables.cc" />
     <ClCompile Include="..\..\source\collection\hashTable.cc" />
@@ -704,6 +714,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\Path.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\Path_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectList.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectMoveToEvent.h" />
@@ -713,6 +725,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject.h" />
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ShapeVector.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ShapeVector_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject.h" />
@@ -778,11 +792,17 @@
     <ClInclude Include="..\..\source\Box2D\Collision\Shapes\b2Shape.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2BlockAllocator.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Draw.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2FreeList.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2GrowableBuffer.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2GrowableStack.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2IntrusiveList.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Math.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Settings.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2SlabAllocator.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2StackAllocator.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2Stat.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Timer.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2TrackedBlock.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2Body.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2ContactManager.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2Fixture.h" />
@@ -811,6 +831,12 @@
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2RopeJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WheelJoint.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2Particle.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleAssembly.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleGroup.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleSystem.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2StackQueue.h" />
+    <ClInclude Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.h" />
     <ClInclude Include="..\..\source\Box2D\Rope\b2Rope.h" />
     <ClInclude Include="..\..\source\collection\bitMatrix.h" />
     <ClInclude Include="..\..\source\collection\bitSet.h" />
@@ -1300,7 +1326,10 @@
       <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\source\Box2D\Particle\b2ParticleAssembly.neon.s" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 87 - 1
engine/compilers/VisualStudio 2019/Torque 2D.vcxproj.filters

@@ -199,6 +199,9 @@
     <Filter Include="bitmapFont">
       <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Box2D\Particle">
+      <UniqueIdentifier>{b2903a96-6c49-4961-82a8-f1832989d4a4}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1414,6 +1417,36 @@
     <ClCompile Include="..\..\source\platform\platformNet.cpp" />
     <ClCompile Include="..\..\source\platform\platformNetAsync.cpp" />
     <ClCompile Include="..\..\source\platform\platformNet_ScriptBinding.cc" />
+    <ClCompile Include="..\..\source\Box2D\Particle\b2Particle.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleAssembly.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleGroup.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2ParticleSystem.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.cpp">
+      <Filter>Box2D\Particle</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Common\b2FreeList.cpp">
+      <Filter>Box2D\Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Common\b2Stat.cpp">
+      <Filter>Box2D\Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\Box2D\Common\b2TrackedBlock.cpp">
+      <Filter>Box2D\Common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\LightObject.cc">
+      <Filter>2d\sceneobject</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\sceneobject\Path.cc">
+      <Filter>2d\sceneobject</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\source\audio\audio.h">
@@ -3156,6 +3189,54 @@
     <ClInclude Include="..\..\source\gui\containers\guiScrollCtrl_ScriptBinding.h">
       <Filter>gui\containers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2VoronoiDiagram.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2Particle.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleAssembly.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleGroup.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2ParticleSystem.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Particle\b2StackQueue.h">
+      <Filter>Box2D\Particle</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2FreeList.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2GrowableBuffer.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2IntrusiveList.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2SlabAllocator.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2Stat.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\Box2D\Common\b2TrackedBlock.h">
+      <Filter>Box2D\Common</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\Path.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\Path_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\sceneobject\LightObject_ScriptBinding.h">
+      <Filter>2d\sceneobject</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">
@@ -3174,4 +3255,9 @@
   <ItemGroup>
     <ResourceCompile Include="Torque 2D.rc" />
   </ItemGroup>
-</Project>
+  <ItemGroup>
+    <None Include="..\..\source\Box2D\Particle\b2ParticleAssembly.neon.s">
+      <Filter>Box2D\Particle</Filter>
+    </None>
+  </ItemGroup>
+</Project>

+ 2 - 2
engine/compilers/VisualStudio 2019/libogg.vcxproj

@@ -30,7 +30,7 @@
     <ProjectGuid>{15CBFEFF-7965-41F5-B4E2-21E8795C9159}</ProjectGuid>
     <RootNamespace>libogg</RootNamespace>
     <Keyword>Win32Proj</Keyword>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -179,4 +179,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 2 - 2
engine/compilers/VisualStudio 2019/libvorbis.vcxproj

@@ -22,7 +22,7 @@
     <ProjectGuid>{3A214E06-B95E-4D61-A291-1F8DF2EC10FD}</ProjectGuid>
     <RootNamespace>libvorbis</RootNamespace>
     <Keyword>Win32Proj</Keyword>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -241,4 +241,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 2 - 2
engine/compilers/VisualStudio 2019/ljpeg.vcxproj

@@ -16,7 +16,7 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{0B07BA94-AA53-4FD4-ADB4-79EC2DA53B36}</ProjectGuid>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
@@ -628,4 +628,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 2 - 2
engine/compilers/VisualStudio 2019/lpng.vcxproj

@@ -16,7 +16,7 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{AF1179E3-A838-46A3-A427-1E62AA4C52F4}</ProjectGuid>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -184,4 +184,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

+ 2 - 2
engine/compilers/VisualStudio 2019/zlib.vcxproj

@@ -46,7 +46,7 @@
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{86CB2525-0CF3-40D3-BF42-A0A95035EE8C}</ProjectGuid>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -182,4 +182,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

File diff suppressed because it is too large
+ 384 - 322
engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj


+ 62 - 0
engine/source/2d/assets/ParticleAssetEmitter.cc

@@ -81,6 +81,56 @@ const char* ParticleAssetEmitter::getEmitterTypeDescription( const EmitterType e
     return StringTable->EmptyString;
 }
 
+//-----------------------------------------------------------------------------
+
+static EnumTable::Enums physicsParticleType[] =
+{
+   {b2ParticleFlag::b2_barrierParticle,            "BarrierPartice"},
+   {b2ParticleFlag::b2_colorMixingParticle,        "ColorMixingParticle"},
+   {b2ParticleFlag::b2_destructionListenerParticle,"DesctructionListenerParticle"},
+   {b2ParticleFlag::b2_elasticParticle,            "ElasticParticle"},
+   {b2ParticleFlag::b2_powderParticle,             "PowderParticle"},
+   {b2ParticleFlag::b2_reactiveParticle,           "ReactiveParticle"},
+   {b2ParticleFlag::b2_repulsiveParticle,          "RepulsiveParticle"},
+   {b2ParticleFlag::b2_springParticle,             "SpringParticle"},
+   {b2ParticleFlag::b2_staticPressureParticle,     "StaticPressureParticle"},
+   {b2ParticleFlag::b2_tensileParticle,            "TensileParticle"},
+   {b2ParticleFlag::b2_viscousParticle,            "ViscousParticle"},
+   {b2ParticleFlag::b2_wallParticle,               "WallParticle"},
+   {b2ParticleFlag::b2_waterParticle,              "WaterParticle"},
+   {b2ParticleFlag::b2_zombieParticle,             "ZombieParticle"}
+};
+
+
+static EnumTable  PhysicsParticleTypeTable(sizeof(physicsParticleType) / sizeof(EnumTable::Enums), &physicsParticleType[0]);
+
+ParticleAssetEmitter::PhysicsParticleType ParticleAssetEmitter::getPhysicsParticleTypeEnum(const char* label)
+{
+   for (U32 i = 0; i < (sizeof(physicsParticleType) / sizeof(EnumTable::Enums)); i++)
+      if (dStricmp(physicsParticleType[i].label, label) == 0)
+         return((ParticleAssetEmitter::PhysicsParticleType)physicsParticleType[i].index);
+
+   // Warn.
+   Con::warnf("ParticleAssetEmitter::getPhysicsParticleType() - Invalid physics particle type '%s'.", label);
+
+   return ParticleAssetEmitter::INVALID_PHYSICS_PARTICLE_TYPE;
+}
+
+const char* ParticleAssetEmitter::getPhysicsParticleTypeDescription(const PhysicsParticleType particleType)
+{
+   // Search for Mnemonic.
+   for (U32 i = 0; i < (sizeof(physicsParticleType) / sizeof(EnumTable::Enums)); i++)
+   {
+      if (physicsParticleType[i].index == (S32)particleType)
+         return physicsParticleType[i].label;
+   }
+
+   // Warn.
+   Con::warnf("ParticleAssetEmitter::getPhysicsParticleTypeDescription() - Invalid physics particle-type");
+
+   return StringTable->EmptyString;
+}
+
 //------------------------------------------------------------------------------
 
 static EnumTable::Enums particleOrientationTypeLookup[] =
@@ -132,7 +182,11 @@ ParticleAssetEmitter::ParticleAssetEmitter() :
                             mEmitterName( StringTable->EmptyString ),
                             mOwner( NULL ),
                             mEmitterType( POINT_EMITTER ),
+                            mPhysicsParticleType(b2_waterParticle),
+                            mPhysicsParticles(false),
                             mEmitterOffset( 0.0f, 0.0f),
+                            mTargetParticle(false),
+                            mTargetPosition(0.0f, 0.0f),
                             mEmitterAngle( 0.0f ),
                             mEmitterSize( 10.0f, 10.0f ),
                             mFixedAspect( true ),
@@ -224,6 +278,14 @@ void ParticleAssetEmitter::initPersistFields()
     addProtectedField("EmitterName", TypeString, Offset(mEmitterName, ParticleAssetEmitter), &setEmitterName, &defaultProtectedGetFn, &defaultProtectedWriteFn, "");
     addProtectedField("EmitterType", TypeEnum, Offset(mEmitterType, ParticleAssetEmitter), &setEmitterType, &defaultProtectedGetFn, &writeEmitterType, 1, &EmitterTypeTable);
     addProtectedField("EmitterOffset", TypeVector2, Offset(mEmitterOffset, ParticleAssetEmitter), &setEmitterOffset, &defaultProtectedGetFn, &writeEmitterOffset, "");
+    addProtectedField("IsTargeting", TypeBool, Offset(mTargetParticle, ParticleAssetEmitter), &setIsTargeting, &defaultProtectedGetFn, &writeTargetParticle, "");
+    addProtectedField("TargetPosition", TypeVector2, Offset(mTargetPosition, ParticleAssetEmitter), &setTargetPosition, &defaultProtectedGetFn, &writeTargetPosition, "");
+
+    //Physics Particles
+    addProtectedField("PhysicsParticle", TypeBool, Offset(mPhysicsParticles, ParticleAssetEmitter), &setPhysicsParticles, &defaultProtectedGetFn, &writePhysicsParticles, "");
+    addProtectedField("PhysicsParticleType", TypeEnum, Offset(mPhysicsParticleType, ParticleAssetEmitter), &setPhysicsParticleType, &defaultProtectedGetFn, &writePhysicsParticleType, 1, &PhysicsParticleTypeTable);
+    //Physics Particles end---
+
     addProtectedField("EmitterAngle", TypeF32, Offset(mEmitterAngle, ParticleAssetEmitter), &setEmitterAngle, &defaultProtectedGetFn, &writeEmitterAngle, "");
     addProtectedField("EmitterSize", TypeVector2, Offset(mEmitterSize, ParticleAssetEmitter), &setEmitterSize, &defaultProtectedGetFn, &writeEmitterSize, "");
     addProtectedField("FixedAspect", TypeBool, Offset(mFixedAspect, ParticleAssetEmitter), &setFixedAspect, &defaultProtectedGetFn, &writeFixedAspect, "");

+ 57 - 1
engine/source/2d/assets/ParticleAssetEmitter.h

@@ -71,6 +71,26 @@ public:
         TORUS_EMITTER,
     };
 
+    enum PhysicsParticleType
+    {
+       INVALID_PHYSICS_PARTICLE_TYPE,
+
+       b2_barrierParticle,
+       b2_colorMixingParticle,
+       b2_destructionListenerParticle,
+       b2_elasticParticle,
+       b2_powderParticle,
+       b2_reactiveParticle,
+       b2_repulsiveParticle,
+       b2_springParticle,
+       b2_staticPressureParticle,
+       b2_tensileParticle,
+       b2_viscousParticle,
+       b2_wallParticle,
+       b2_waterParticle,
+       b2_zombieParticle
+    };
+
 private:
     typedef SimObject Parent;
 
@@ -91,7 +111,14 @@ private:
     F32                                     mRandomArc;
     F32                                     mFixedAngleOffset;
     Vector2                                 mPivotPoint;
-
+    //Physics Particles
+    PhysicsParticleType                     mPhysicsParticleType;
+    bool                                    mPhysicsParticles;
+    //Physics Particles end---
+    //Particle Target
+    bool                                    mTargetParticle;
+    Vector2                                 mTargetPosition;
+    //Particle Target end---
     bool                                    mLinkEmissionRotation;
     bool                                    mIntenseParticles;
     bool                                    mSingleParticle;
@@ -157,6 +184,18 @@ public:
     inline const Vector2& getFixedForceDirection( void ) const { return mFixedForceDirection; }
     inline void setOrientationType( const ParticleOrientationType particleOrientationType ) { mOrientationType = particleOrientationType; refreshAsset(); }
     inline ParticleOrientationType getOrientationType( void ) const { return mOrientationType; }
+    //Physics particles
+    inline void setPhysicsParticleType(const PhysicsParticleType physicsParticleType) { mPhysicsParticleType = physicsParticleType; refreshAsset(); }
+    inline PhysicsParticleType getPhysicsParticleType(void) const { return mPhysicsParticleType; }
+    inline void setPhysicsParticles(const bool physicsPaticle) { mPhysicsParticles = physicsPaticle; refreshAsset(); }
+    inline bool getPhysicsParticles(void) const { return mPhysicsParticles; }
+    //Phyiscs particles end---
+    //Particle Target
+    inline void setTargetPosition(const Vector2& targetPos) { mTargetPosition = targetPos; }
+    inline const Vector2& getTargetPosition(void) const { return mTargetPosition; }
+    inline void setIsTargeting(const bool targetParticle) { mTargetParticle = targetParticle; refreshAsset(); }
+    inline bool getIsTargeting(void) const { return mTargetParticle; }
+    //Particle Target end---
     inline void setKeepAligned( const bool keepAligned ) { mKeepAligned = keepAligned; refreshAsset(); }
     inline bool getKeepAligned( void ) const { return mKeepAligned; }
     inline void setAlignedAngleOffset( const F32 angleOffset ) { mAlignedAngleOffset = angleOffset; refreshAsset(); }
@@ -250,6 +289,10 @@ public:
 
     static EmitterType getEmitterTypeEnum(const char* label);
     static const char* getEmitterTypeDescription( const EmitterType emitterType );
+    //phyiscs particles
+    static PhysicsParticleType getPhysicsParticleTypeEnum(const char * label);
+    static const char* getPhysicsParticleTypeDescription(const PhysicsParticleType particleType);
+    //physics particles end----
     static ParticleOrientationType getOrientationTypeEnum(const char* label);
     static const char* getOrientationTypeDescription( const ParticleOrientationType orientationType );
 
@@ -270,6 +313,12 @@ protected:
     static bool     writeEmitterType( void* obj, StringTableEntry pFieldName )          { return static_cast<ParticleAssetEmitter*>(obj)->getEmitterType() != POINT_EMITTER; }
     static bool     setEmitterOffset(void* obj, const char* data)                       { static_cast<ParticleAssetEmitter*>(obj)->setEmitterOffset(Vector2(data)); return false; }
     static bool     writeEmitterOffset( void* obj, StringTableEntry pFieldName )        { return static_cast<ParticleAssetEmitter*>(obj)->getEmitterOffset().notZero(); }
+
+    static bool     setIsTargeting(void* obj, const char* data)                      { static_cast<ParticleAssetEmitter*>(obj)->setIsTargeting(dAtob(data)); return false; }
+    static bool     writeTargetParticle(void* obj, StringTableEntry pFieldName)         { return static_cast<ParticleAssetEmitter*>(obj)->getIsTargeting() == false; }
+    static bool     setTargetPosition(void* obj, const char* data)                      { static_cast<ParticleAssetEmitter*>(obj)->setTargetPosition(Vector2(data)); return false; }
+    static bool     writeTargetPosition(void* obj, StringTableEntry pFieldName)         { return static_cast<ParticleAssetEmitter*>(obj)->getTargetPosition().notZero(); }
+
     static bool     setEmitterAngle(void* obj, const char* data)                        { static_cast<ParticleAssetEmitter*>(obj)->setEmitterAngle(dAtof(data)); return false; }
     static bool     writeEmitterAngle( void* obj, StringTableEntry pFieldName )         { return mNotZero(static_cast<ParticleAssetEmitter*>(obj)->getEmitterAngle()); }
     static bool     setEmitterSize(void* obj, const char* data)                         { static_cast<ParticleAssetEmitter*>(obj)->setEmitterSize(Vector2(data)); return false; }
@@ -278,6 +327,13 @@ protected:
     static bool     writeFixedAspect( void* obj, StringTableEntry pFieldName )          { return static_cast<ParticleAssetEmitter*>(obj)->getFixedAspect() == false; }
     static bool     setFixedForceAngle(void* obj, const char* data)                     { static_cast<ParticleAssetEmitter*>(obj)->setFixedForceAngle(dAtof(data)); return false; }
     static bool     writeFixedForceAngle( void* obj, StringTableEntry pFieldName )      { return mNotZero(static_cast<ParticleAssetEmitter*>(obj)->getFixedForceAngle() ); }
+    //Physics Particles
+    static bool     setPhysicsParticleType(void* obj, const char* data)                { static_cast<ParticleAssetEmitter*>(obj)->setPhysicsParticleType(getPhysicsParticleTypeEnum(data)); return false; }
+    static bool     writePhysicsParticleType(void* obj, StringTableEntry pFieldName)   { return static_cast<ParticleAssetEmitter*>(obj)->getPhysicsParticleType() != b2_zombieParticle; }
+    static bool     setPhysicsParticles(void* obj, const char* data)                    { static_cast<ParticleAssetEmitter*>(obj)->setPhysicsParticles(dAtob(data)); return false; }
+    static bool     writePhysicsParticles(void* obj, StringTableEntry pFieldName)       { return static_cast<ParticleAssetEmitter*>(obj)->getPhysicsParticles() == false; }
+    //Physics Particles end---
+
     static bool     setOrientationType(void* obj, const char* data)                     { static_cast<ParticleAssetEmitter*>(obj)->setOrientationType( getOrientationTypeEnum(data) ); return false; }
     static bool     writeOrientationType( void* obj, StringTableEntry pFieldName )      { return static_cast<ParticleAssetEmitter*>(obj)->getOrientationType() != FIXED_ORIENTATION; }
     static bool     setKeepAligned(void* obj, const char* data)                         { static_cast<ParticleAssetEmitter*>(obj)->setKeepAligned(dAtob(data)); return false; }

+ 57 - 0
engine/source/2d/assets/ParticleAssetEmitter_ScriptBinding.h

@@ -123,6 +123,63 @@ ConsoleMethodWithDocs(ParticleAssetEmitter, getEmitterOffset, ConsoleString, 2,
     return object->getEmitterOffset().scriptThis();
 }
 
+/*! Sets if the emitter targets a point.
+    @param target The point that the emitter's particles will be drawn to.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, setIsTargeting, ConsoleVoid, 3, 3, (target))
+{
+   object->setIsTargeting(dAtob(argv[2]));
+}
+
+//-----------------------------------------------------------------------------
+
+/*! Gets whether the emitter targets a point.
+    @return True if the emitter uses a target for particles.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, getIsTargeting, ConsoleBool, 2, 2, ())
+{
+   return object->getIsTargeting();
+}
+
+/* Sets the world point that the emitter will target. Targeting must be turned on with setIsTargeting().
+    @param Position The world point that will be the target.
+    @return No return value.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, setTargetPosition, ConsoleVoid, 3, 4, (float X / float Y))
+{
+   // Grab the element count.
+   U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+
+   // ("positionX positionY")
+   if ((elementCount == 2) && (argc < 4))
+   {
+      object->setTargetPosition(Vector2(argv[2]));
+      return;
+   }
+
+   // (positionX, positionY)
+   if ((elementCount == 1) && (argc > 3))
+   {
+      object->setTargetPosition(Vector2(dAtof(argv[2]), dAtof(argv[3])));
+      return;
+   }
+
+   // Warn.
+   Con::warnf("ParticleAssetEmitter::setTargetPosition() - Invalid number of parameters!");
+}
+
+//------------------------------------------------------------------------------
+
+/*! Gets the emitter target position.
+    @return (float x/float y) The position of the target of the emitter.
+*/
+ConsoleMethodWithDocs(ParticleAssetEmitter, getTargetPosition, ConsoleString, 2, 2, ())
+{
+   return object->getTargetPosition().scriptThis();
+}
+
+
 //------------------------------------------------------------------------------
 
 /*! Sets the emitter size.

+ 5 - 0
engine/source/2d/core/ParticleSystem.h

@@ -67,6 +67,11 @@ public:
         F32                     mRandomMotion;
         ColorF                  mColor;    
 
+        /// Physics particles
+        bool                    mPhysicsParticles;
+        b2ParticleGroupDef      mParticleGroup;
+        b2ParticleSystem*       mParticleSystem;
+
         /// Interpolated Tick Position.
         Vector2                 mPreTickPosition;
         Vector2                 mPostTickPosition;

+ 3 - 0
engine/source/2d/scene/Scene.cc

@@ -222,6 +222,9 @@ bool Scene::onAdd()
     // Set contact filter.
     mpWorld->SetContactFilter( &mContactFilter );
 
+    const b2ParticleSystemDef particleSystemDef;
+    mParticleSystem = mpWorld->CreateParticleSystem(&particleSystemDef);
+
     // Set contact listener.
     mpWorld->SetContactListener( this );
 

+ 1 - 1
engine/source/2d/scene/Scene.h

@@ -678,7 +678,7 @@ public:
     static const char* getPickModeDescription( PickMode pickMode );
     static DebugOption getDebugOptionEnum(const char* label);
     static const char* getDebugOptionDescription( DebugOption debugOption );
-
+    b2ParticleSystem*			mParticleSystem;
     /// Declare Console Object.
     DECLARE_CONOBJECT(Scene);
 

+ 239 - 0
engine/source/2d/sceneobject/LightObject.cc

@@ -0,0 +1,239 @@
+#include "graphics/dgl.h"
+#include "console/consoleTypes.h"
+#include "2d/core/Utility.h"
+#include "2d/sceneobject/LightObject.h"
+
+// Script bindings.
+#include "LightObject_ScriptBinding.h"
+
+IMPLEMENT_CONOBJECT(LightObject);
+
+LightObject::LightObject():
+   mLightRadius(10.0f),
+   mLightSegments(15)
+{
+   mSrcBlendFactor = GL_SRC_ALPHA;
+   mDstBlendFactor = GL_ONE;
+   // Use a static body by default.
+   mBodyDefinition.type = b2_staticBody;
+}
+
+LightObject::~LightObject()
+{
+
+}
+
+bool LightObject::onAdd()
+{
+   // Call Parent.
+   if (!Parent::onAdd())
+      return false;
+
+   // Return Okay.
+   return true;
+}
+
+//----------------------------------------------------------------------------
+
+void LightObject::onRemove()
+{
+   // Call Parent.
+   Parent::onRemove();
+}
+
+void LightObject::initPersistFields()
+{
+   Parent::initPersistFields();
+
+   /// Light settings.
+   addProtectedField("LightRadius", TypeF32, Offset(mLightRadius, LightObject), &setLightRadius, &defaultProtectedGetFn, &writeLightRadius, "");
+   addProtectedField("LightSegments", TypeS32, Offset(mLightSegments, LightObject), &setLightSegments, &defaultProtectedGetFn, &writeLightSegments, "");
+
+}
+
+void LightObject::safeDelete(void)
+{
+   Parent::safeDelete();
+}
+
+void LightObject::sceneRender(const SceneRenderState * sceneRenderState, const SceneRenderRequest * sceneRenderRequest, BatchRender * batchRender)
+{
+   Vector2 worldPos = getPosition();
+   Vector<Vector2> verts;
+   Vector<RayList> bList;
+   S32 mSrcLightBlend = getSrcBlendFactor();
+   S32 mDstLightBlend = getDstBlendFactor();
+   ColorF mLightColor = getBlendColor();
+
+   F32 radius = getLightRadius();
+   Scene* scene = getScene();
+   b2World* mWorld = scene->getWorld();
+
+
+   
+
+   glEnable(GL_BLEND);
+   glDisable(GL_TEXTURE_2D);
+   glPushMatrix();
+ 
+   glTranslatef(worldPos.x, worldPos.y, 0);
+   glPolygonMode(GL_FRONT, GL_FILL);
+
+   //additive blending
+   //glBlendFunc(GL_ONE,GL_ONE);
+   
+   glBlendFunc(mSrcLightBlend, mDstLightBlend);
+   // Creates the fading dark region.
+   glBegin(GL_TRIANGLE_FAN);
+   glColor4f(mLightColor.red,mLightColor.green,mLightColor.blue,mLightColor.alpha);
+   glVertex2f(0, 0);
+   //check scene objects
+   U32 objCount = scene->getSceneObjectCount();
+   for (U32 i = 0; i < objCount; i++)
+   {
+      SceneObject *tObj = scene->getSceneObject(i);
+      Vector2 dist = worldPos - tObj->getPosition();
+      const F32 distSqr = dist.LengthSquared();
+      const F32 radSqr = radius * radius;
+      //within radius?
+      if (distSqr < radSqr || distSqr == radSqr)
+      {
+         U32 shapeCount = tObj->getCollisionShapeCount();
+         for (U32 j = 0; j < shapeCount; j++)
+         {
+            //All vertices from polygon collision shape
+            if (tObj->getCollisionShapeType(j) == b2Shape::e_polygon)
+            {
+               U32 pCount = tObj->getPolygonCollisionShapePointCount(j);
+
+               for (U32 k = 0; k < pCount; k++)
+               {
+                  Vector2 locPoint = tObj->getPolygonCollisionShapeLocalPoint(j, k);
+                  Vector2 wPoint = tObj->getWorldPoint(locPoint);
+                  verts.push_back(wPoint);
+               }
+            }
+         }
+      }
+   }
+   ///  \ | /
+   /// -  +  -
+   ///  / | \
+
+   U32 lightSeg = getLightSegments();
+   F32 segAng = 360.0f / lightSeg;
+
+   for (U32 i = 0; i <= lightSeg; i++)
+   {
+      b2Vec2 segStrt = worldPos;
+      b2Vec2 segEnd = segStrt + radius * b2Vec2(mCos(mDegToRad((F32)segAng * i)), mSin(mDegToRad((F32)segAng * i)));
+      verts.push_back(segEnd);
+   }
+
+   //cast ray to vertices
+   for (S32 l = 0; l < verts.size(); l++)
+   {
+      F32 rayLength = radius;
+      Vector2 p1 = worldPos;
+      Vector2 p2 = verts[l];
+      F32 baseAng = mAtan(p2.x, p2.y);
+      F32 cAng = 0;
+      for (int m = 0; m < 2; m++)
+      {
+         if (m == 0)cAng = baseAng - 0.0001f;
+         //if (m == 1)cAng = baseAng;
+         if (m == 1)cAng = baseAng + 0.0001f;
+
+         p2.x = rayLength * mCos(cAng);
+         p2.y = rayLength * mSin(cAng);
+
+         RaysCastCallback callback;
+         mWorld->RayCast(&callback, p1, p2);
+         if (callback.m_fixture)
+         {
+
+            F32 ang = mAtan(callback.m_point.x - p1.x, callback.m_point.y - p1.y);
+            Vector2 intersection = p1 + callback.m_fraction * (p2 - p1);
+            
+            RayList intersectionPoint;
+            intersectionPoint.ang = ang;
+            intersectionPoint.x = intersection.x;
+            intersectionPoint.y = intersection.y;
+            intersectionPoint.l = callback.m_fraction;
+
+
+            bList.push_back_unique(intersectionPoint);
+
+         }
+         else
+         {
+            F32 ang = mAtan(p2.x - p1.x, p2.y - p1.y);
+
+            RayList intersectionPoint;
+            intersectionPoint.ang = ang;
+            intersectionPoint.x = p2.x;
+            intersectionPoint.y = p2.y;
+            intersectionPoint.l = 1.0;
+
+            bList.push_back_unique(intersectionPoint);
+         }
+      }
+   }
+
+   //Con::printf("Rays cast: %i", bList.size());
+   //sort the list
+   if (bList.size() > 1)
+   {
+      dQsort(bList.address(), bList.size(), sizeof(RayList), sortRays);
+   }
+
+   
+
+   //triangle fan
+   for (S32 m = 0; m < bList.size(); m++)
+   {
+      glColor4f(mLightColor.red - (mLightColor.red * bList[m].l), mLightColor.green - (mLightColor.green * bList[m].l), mLightColor.blue - (mLightColor.blue * bList[m].l), mLightColor.alpha - (mLightColor.alpha * bList[m].l));
+      glVertex2f(bList[m].x, bList[m].y);
+
+   }
+   //close off the circle
+   glColor4f(mLightColor.red - (mLightColor.red * bList[0].l), mLightColor.green - (mLightColor.green * bList[0].l), mLightColor.blue - (mLightColor.blue * bList[0].l), mLightColor.alpha - (mLightColor.alpha * bList[0].l));
+   glVertex2f(bList[0].x, bList[0].y);
+
+   glDisable(GL_BLEND);
+
+   glEnd();
+
+   glPopMatrix();
+}
+
+void LightObject::OnRegisterScene(Scene* mScene)
+{
+   Parent::OnRegisterScene(mScene);
+   mScene->getWorldQuery()->addAlwaysInScope(this);
+
+}
+
+void LightObject::OnUnregisterScene(Scene* mScene)
+{
+   mScene->getWorldQuery()->removeAlwaysInScope(this);
+   Parent::OnUnregisterScene(mScene);
+}
+
+S32 QSORT_CALLBACK sortRays(const void* a, const void* b)
+{
+   RayList* ray_a = (RayList*) a;
+   RayList* ray_b = (RayList*) b;
+
+   if (ray_a->ang < ray_b->ang)
+   {
+      return -1;
+   }
+   else if (ray_a->ang > ray_b->ang)
+   {
+      return 1;
+   }
+  
+   return 0;
+
+}

+ 96 - 0
engine/source/2d/sceneobject/LightObject.h

@@ -0,0 +1,96 @@
+#ifndef _LIGHTOBJECT_H_
+#define _LIGHTOBJECT_H_
+
+#ifndef _SCENE_OBJECT_H_
+#include "2d/sceneobject/SceneObject.h"
+#endif
+
+class RayList
+{
+public:
+
+   F32 x;
+   F32 y;
+   F32 l;
+   F32 ang;
+   bool operator == (const RayList& t) const { return ((mFabs(t.x - x) < 0.01) && (mFabs(t.y - y) < 0.01)); }
+
+};
+
+class RaysCastCallback : public b2RayCastCallback
+{
+public:
+
+   RaysCastCallback() : m_fixture(NULL) {}
+
+   float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point, const b2Vec2& normal, float32 fraction) {
+      m_fixture = fixture;
+      m_point = point;
+      m_normal = normal;
+      m_fraction = fraction;
+      return fraction;
+   }
+
+   b2Fixture* m_fixture;
+   b2Vec2 m_point;
+   b2Vec2 m_normal;
+   float32 m_fraction;
+
+};
+
+class LightObject : public SceneObject
+
+{
+   typedef SceneObject Parent;
+
+protected:
+
+   F32                     mLightRadius;
+   U32                     mLightSegments;
+
+public:
+
+   LightObject();
+   ~LightObject();
+
+   static void initPersistFields();
+
+   
+
+   virtual bool onAdd();
+   virtual void onRemove();
+
+   virtual void safeDelete(void);
+   virtual void sceneRender(const SceneRenderState* sceneRenderState, const SceneRenderRequest* sceneRenderRequest, BatchRender* batchRender);
+   //virtual bool validRender(void) const {}
+   virtual bool shouldRender(void) const { return true; }
+
+   /// Light segments.
+   inline void setLightSegments(const U32 lightSegments) { mLightSegments = lightSegments; };
+   inline U32 getLightSegments(void) const { return mLightSegments; }
+
+   /// Light Radius.
+   inline void setLightRadius(const F32 lightRadius) { mLightRadius = lightRadius; }
+   inline F32 getLightRadius(void) const { return mLightRadius; }
+
+   DECLARE_CONOBJECT(LightObject);
+
+
+protected:
+
+   virtual void OnRegisterScene(Scene* mScene);
+   virtual void OnUnregisterScene(Scene* mScene);
+
+protected:
+
+   static bool setLightRadius(void* obj, const char* data) { static_cast<LightObject*>(obj)->setLightRadius(dAtof(data)); return false; }
+   static bool writeLightRadius(void* obj, StringTableEntry pFieldName) { return static_cast<LightObject*>(obj)->getLightRadius() > 0.0f; }
+
+   static bool setLightSegments(void* obj, const char* data) { static_cast<LightObject*>(obj)->setLightSegments(dAtoi(data)); return false; }
+   static bool writeLightSegments(void* obj, StringTableEntry pFieldName) { return static_cast<LightObject*>(obj)->getLightSegments() > 0; }
+
+};
+
+#endif //_LIGHTOBJECT_H_
+
+S32 QSORT_CALLBACK sortRays(const void * a, const void * b);

+ 52 - 0
engine/source/2d/sceneobject/LightObject_ScriptBinding.h

@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+ConsoleMethodGroupBeginWithDocs(LightObject, SceneObject)
+
+/*! Add the object to a scene.
+    @param scene the scene you wish to add this object to.
+    @return No return value.
+*/
+
+ConsoleMethodWithDocs(LightObject, setLightRadius, ConsoleVoid, 3, 3, (float radius))
+{
+   // Set Lifetime.
+   object->setLightRadius(dAtof(argv[2]));
+}
+
+ConsoleMethodWithDocs(LightObject, getLightRadius, ConsoleFloat, 2, 2, ())
+{
+   // Return Lifetime.
+   return object->getLightRadius();
+}
+
+
+ConsoleMethodWithDocs(LightObject, setLightSegments, ConsoleVoid, 3, 3, (integer lightSegments))
+{
+   // Set Layer.
+   object->setLightSegments(dAtoi(argv[2]));
+}
+
+ConsoleMethodWithDocs(LightObject, getLightSegments, ConsoleInt, 2, 2, ())
+{
+   // Return Layer.
+   return object->getLightSegments();
+}

+ 16 - 4
engine/source/2d/sceneobject/ParticlePlayer.cc

@@ -1147,11 +1147,23 @@ void ParticlePlayer::configureParticle( EmitterNode* pEmitterNode, ParticleSyste
                                                                 pParticleAssetEmitter->getEmissionForceVariationField(),
                                                                 particlePlayerAge) * getForceScale();
 
-        // Calculate Emission Angle.
-        emissionAngle = ParticleAssetField::calculateFieldBV(   pParticleAssetEmitter->getEmissionAngleBaseField(),
-                                                                pParticleAssetEmitter->getEmissionAngleVariationField(),
-                                                                particlePlayerAge );
+        if (pParticleAssetEmitter->getIsTargeting())
+        {
+           Vector2 tPos = pParticleAssetEmitter->getTargetPosition();
+           Vector2 pPos = pParticleNode->mPosition;
+           Vector2 subVec = tPos - pPos;
+           F32 vecN = mAtan(subVec.x, subVec.y);
+           F32 vecDeg = mRadToDeg(vecN);
+           emissionAngle = vecDeg;
+        }
+        else
+        {
 
+           // Calculate Emission Angle.
+           emissionAngle = ParticleAssetField::calculateFieldBV(  pParticleAssetEmitter->getEmissionAngleBaseField(),
+                                                                  pParticleAssetEmitter->getEmissionAngleVariationField(),
+                                                                  particlePlayerAge);
+        }
         // Calculate Emission Arc.
         // NOTE:-   We're actually interested in half the emission arc!
         emissionArc = ParticleAssetField::calculateFieldBV( pParticleAssetEmitter->getEmissionArcBaseField(),

+ 285 - 0
engine/source/2d/sceneobject/Path.cc

@@ -0,0 +1,285 @@
+#include "graphics/dgl.h"
+#include "2d/sceneobject/Path.h"
+
+#include "2d/sceneobject/Path_ScriptBinding.h"
+
+IMPLEMENT_CONOBJECT(Path);
+
+PathObject::PathObject():
+   mObj(NULL),
+   mPath(NULL)
+{
+   mCurrNode = 0;
+   mPrevNode = 0;
+
+   mMaxSpeed = 1.0f;
+   mMaxForce = 3.0f;
+   mOrient = false;
+   mAngOff = 0.0f;
+   mSnapToNode = false;
+   mLoop = true;
+   mMaxLoop = -1;
+   mLoopCount = 0;
+}
+
+void PathObject::setCurrNode(S32 node)
+{
+}
+
+void PathObject::setNextNode(S32 node)
+{
+}
+
+void PathObject::setPrevNode(S32 node)
+{
+}
+
+
+Path::Path()
+{
+
+   // Use a static body by default.
+   mBodyDefinition.type = b2_staticBody;
+
+   VECTOR_SET_ASSOCIATION(mObjs);
+   VECTOR_SET_ASSOCIATION(mNodes);
+}
+
+Path::~Path()
+{
+
+}
+
+void Path::initPersistFields()
+{
+   Parent::initPersistFields();
+}
+
+void Path::preIntegrate(const F32 totalTime, const F32 elapsedTime, DebugStats * pDebugStats)
+{
+   Parent::preIntegrate(totalTime, elapsedTime, pDebugStats);
+
+   Vector<PathObject*>::iterator i;
+   for (i = mObjs.begin(); i != mObjs.end(); i++)
+   {
+      bool stop = false;
+      PathObject &pObj = *(*i);
+
+      Vector2 cPos = pObj.mObj->getPosition();
+      Node &cNode = mNodes[pObj.mCurrNode];
+      Vector2 cDst = mNodes[pObj.mCurrNode].position;
+      F32 distance = (cDst - cPos).Length();
+
+      if (distance < (pObj.mMaxSpeed * elapsedTime) || distance < cNode.distance )
+      {
+         S32 nCount = mNodes.size();
+         S32 end = nCount - 1;
+         if (pObj.mCurrNode == end)
+         {
+            if (pObj.mLoop)
+            {
+               pObj.mLoopCount++;
+               if ((pObj.mMaxLoop > 0) && (pObj.mLoopCount >= pObj.mMaxLoop))
+               {
+                  stop = true;
+               }
+               else
+               {
+                  pObj.mPrevNode = pObj.mCurrNode;
+                  pObj.mCurrNode = 0;
+                  pObj.mNextNode = pObj.mCurrNode;
+               }
+            }
+            else
+            {
+               stop = true;
+            }
+         }
+         else
+         {
+            pObj.mPrevNode = pObj.mCurrNode;
+            pObj.mCurrNode = pObj.mCurrNode + 1;
+            pObj.mNextNode = pObj.mCurrNode;
+         }
+
+         if (pObj.mCurrNode >= nCount)
+         {
+            pObj.mCurrNode = 0;
+            pObj.mNextNode = pObj.mCurrNode;
+         }
+         else if (pObj.mCurrNode < 0)
+         {
+            pObj.mCurrNode = 0;
+            pObj.mNextNode = pObj.mCurrNode;
+         }
+
+      }
+
+      if (!stop)
+      {
+         moveObject(pObj);
+      }
+
+      else
+      {
+         pObj.mObj->setLinearVelocity(Vector2(0.0f, 0.0f));
+      }
+
+   }
+
+}
+
+void Path::integrateObject(const F32 totalTime, const F32 elapsedTime, DebugStats * pDebugStats)
+{
+   Parent::integrateObject(totalTime, elapsedTime, pDebugStats);
+}
+
+S32 Path::addNode(Vector2 pos, F32 distance, F32 weight)
+{
+   S32 nodeCount = mNodes.size();
+
+   mNodes.push_back(Node(pos, distance, weight));
+
+   return nodeCount;
+}
+
+void Path::attachObject(SceneObject * object, F32 speed, F32 force, bool orientToPath, F32 angleOff, bool snapToNode, S32 startNode, bool loop, S32 maxLoop)
+{
+   if (snapToNode)
+   {
+      if ((startNode >= 0) && (startNode < mNodes.size()))
+         object->setPosition(mNodes[startNode].position);
+   }
+
+   object->setLinearVelocity(Vector2::getZero());
+
+   deleteNotify(object);
+
+   PathObject *pObj  = new PathObject();
+   pObj->mPath       = this;
+   pObj->mObj        = object;
+   pObj->mMaxForce   = force;
+   pObj->mObjId      = object->getId();
+   pObj->mOrient     = orientToPath;
+   pObj->mAngOff     = angleOff;
+   pObj->mLoop       = loop;
+   pObj->mMaxLoop    = maxLoop;
+   pObj->mMaxSpeed   = speed;
+   pObj->mCurrNode   = startNode;
+   pObj->mNextNode   = startNode;
+   
+
+   mObjs.push_back(pObj);
+}
+
+void Path::detachObject(SceneObject * object)
+{
+   if (!object)
+      return;
+
+   Vector<PathObject*>::iterator i;
+
+   for (i = mObjs.begin(); i != mObjs.end(); i++)
+   {
+      PathObject *pObj = (*i);
+      if(object == pObj->mObj)
+      {
+         if (!pObj->mObj.isNull())
+         {
+            pObj->mObj->setLinearVelocity(Vector2(0, 0));
+            clearNotify(pObj->mObj);
+         }
+
+         delete pObj;
+
+         mObjs.erase_fast(i);
+         
+         break;
+      }
+   }
+}
+
+void Path::moveObject(PathObject& obj)
+{
+   Vector2 cDest = mNodes[obj.mNextNode].position;
+   F32 slowRad = mNodes[obj.mNextNode].distance;
+   Vector2 oPos = obj.mObj->getPosition();
+   Vector2 dir = cDest - oPos;
+   Vector2 currVel = obj.mObj->getLinearVelocity();
+   dir.Normalize();
+
+   F32 maxSpeed = obj.mMaxSpeed;
+   F32 maxForce = obj.mMaxForce;
+
+   Vector2 steer = seek(cDest, oPos, maxSpeed, currVel, slowRad);
+   steer = truncate(steer, maxForce);
+   steer = steer.scale(0.5f);
+   currVel = currVel.add(steer);
+   currVel = truncate(currVel.add(steer), maxSpeed);
+   Vector2 pos = oPos.add(currVel);
+
+   //Steering Behavior
+   obj.mObj->applyForce(pos, obj.mObj->getWorldCenter());
+
+   //Simple direct move.
+   //obj.mObj->setLinearVelocity(dir * obj.mMaxSpeed);
+
+   if (obj.mOrient)
+   {
+      F32 rot = mRadToDeg(mAtan(dir.x, dir.y));
+      rot = rot - obj.mAngOff;
+      F32 ang = mDegToRad(rot);
+      F32 speed = obj.mMaxSpeed;
+      obj.mObj->rotateTo(ang, speed);
+   }
+
+}
+
+Vector2 Path::truncate(Vector2 vec, F32 max)
+{
+   F32 i = max;
+   i = i < 1.0f ? 1.0f : i;
+   vec = vec.scale(max);
+   return vec;
+}
+
+Vector2 Path::seek(Vector2 target, Vector2 objPos, F32 max, Vector2 curr, F32 slowRad)
+{
+   Vector2 des = target.sub(objPos);
+   F32 dist = des.Length();
+   des.Normalize();
+
+   if (dist < slowRad)
+   {
+      des = des.scale(max * dist / slowRad);
+   }
+   else
+   {
+      des = des.scale(max);
+   }
+
+   Vector2 force = des.sub(curr);
+
+   return force;
+}
+
+
+
+void Path::onDeleteNotify(SimObject* object)
+{
+   Vector<PathObject*>::iterator i;
+
+   SimObjectId objId = object->getId();
+
+   for (i = mObjs.begin(); i != mObjs.end(); i++)
+   {
+      if ((*i)->mObjId == objId)
+      {
+         delete (*i);
+
+         mObjs.erase_fast(i);
+
+         break;
+      }
+   }
+}

+ 113 - 0
engine/source/2d/sceneobject/Path.h

@@ -0,0 +1,113 @@
+#ifndef _PATH_H_
+#define _PATH_H_
+
+#include "2d/sceneobject/SceneObject.h"
+
+class Path;
+
+class PathObject
+{
+private:
+   friend class Path;
+   void setCurrNode(S32 node);
+   void setNextNode(S32 node);
+   void setPrevNode(S32 node);
+
+   Path* mPath;
+   SimObjectPtr<SceneObject> mObj;
+   SimObjectId mObjId;
+   F32 mMaxSpeed;
+   bool mOrient;
+   F32 mMaxForce;
+   F32 mAngOff;
+   
+   S32 mCurrNode;
+   S32 mPrevNode;
+   S32 mNextNode;
+   bool mLoop; 
+   
+   bool mSnapToNode;
+   S32 mLoopCount;
+   S32 mMaxLoop;
+
+public:
+   PathObject();
+   ~PathObject() {};
+
+};
+
+class Path : public SceneObject
+{
+   typedef SceneObject Parent;
+
+public:
+   struct Node
+   {
+      Node(Vector2 pos, F32 dst, F32 wght)
+      {
+         position = pos;
+         distance = dst;
+         weight = wght;
+      };
+
+      Vector2 position;
+      F32 distance;
+      F32 weight;
+   };
+
+   Path();
+   ~Path();
+   virtual void onDeleteNotify(SimObject* object);
+   static void initPersistFields();
+
+   virtual void preIntegrate(const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats);
+   virtual void integrateObject(const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats);
+
+   S32 addNode(Vector2 pos, F32 distance, F32 weight);
+
+   S32 getNodeCount() const { return mNodes.size(); }
+
+   inline Node& getNode(S32 index)
+   {
+      if (isValidNode(index)) return mNodes[index];
+      return mNodes[0];
+   }
+
+   inline bool isValidNode(S32 index)
+   {
+      if (mNodes.empty()) return false;
+      if((index >= 0) && (index < mNodes.size())) return true;
+   }
+
+   void attachObject(SceneObject* object, F32 speed, F32 force, bool orientToPath, F32 angleOff, bool snapToNode, S32 startNode, bool loop, S32 maxLoop);
+
+   void detachObject(SceneObject* object);
+
+   S32 getAttachedObjectCount() { return mObjs.size(); }
+
+   SceneObject* getPathObject(U32 index) { if (index < mObjs.size()) return mObjs[index]->mObj; return NULL; }
+   
+   inline PathObject* getAttachedObject(const SceneObject* obj)
+   {
+      if (obj == NULL)
+         return NULL;
+
+      Vector<PathObject*>::iterator i;
+      for (i = mObjs.begin(); i != mObjs.end(); i++)
+         if ((*i)->mObj == obj) return *i;
+   }
+
+   DECLARE_CONOBJECT(Path);
+
+private:
+
+   void moveObject(PathObject& obj);
+   Vector2 truncate(Vector2 vec, F32 max);
+   Vector2 seek(Vector2 target, Vector2 objPos, F32 max, Vector2 curr, F32 slowRad);
+
+   Vector<PathObject*> mObjs;
+   Vector<Node> mNodes;
+
+};
+
+#endif

+ 134 - 0
engine/source/2d/sceneobject/Path_ScriptBinding.h

@@ -0,0 +1,134 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+/*! Attaches a sceneObject to the path.
+@param SceneObject The object that will be attached to the path.
+@param speed The rate that the sceneObject will follow the path.
+@param orient If true, the object will automatically rate to face the direction that it is moving.
+@param angOff The offset that will be applied to the rotation if orient is true.
+@param snapToNode If true, the object will have to get close to a node instead of reaching it exactly. The distance is based on the distance given a node when it is created.
+@param startNode A zero-based integer that represents the node that the object should start at.
+@param loop If true, the object will start the path again when it reaches the last node. The object will travel from the last node to the first.
+@param maxLoop An integer value describing the number of times the object will travel the path if looping is turned on.
+@return No return value.
+*/
+ConsoleMethodWithDocs(Path, attachObject, ConsoleVoid, 4, 11, (sceneObject, float speed,[float force], [bool orient], [float angOff], [bool snapToNode],[integer startNode],[bool loop],[integer maxLoop]))
+{
+   // Set Group.
+   SceneObject* pSceneObject = dynamic_cast<SceneObject*>(Sim::findObject(argv[2]));
+   // Did we find the object?
+   if (!pSceneObject)
+   {
+      // No, so warn.
+      Con::warnf("Path::attachObject() - Could not find the specified object '%s'.", argv[2]);
+      return;
+   }
+
+   F32 speed = dAtof(argv[3]);
+
+   F32 force = 3.0f;
+
+   if (argc > 4)
+   {
+      force = dAtof(argv[4]);
+   }
+
+   bool orient = false;
+   if (argc > 5)
+   {
+      orient = dAtob(argv[5]);
+   }
+
+   F32 angleOff = 0.0f;
+   if (argc > 6)
+   {
+      angleOff = dAtof(argv[6]);
+   }
+
+   bool snapToNode = false;
+   if (argc > 7)
+   {
+      snapToNode = dAtob(argv[7]);
+   }
+
+   S32 startNode = 0;
+   if (argc > 8)
+   {
+      startNode = dAtoi(argv[8]);
+   }
+
+   bool loop = true;
+   if (argc > 9)
+   {
+      loop = dAtob(argv[9]);
+   }
+
+   S32 maxLoop = 0;
+   if (argc > 10)
+   {
+      maxLoop = dAtoi(argv[10]);
+   }
+
+   object->attachObject(pSceneObject, speed, force, orient, angleOff, snapToNode, startNode, loop, maxLoop);
+
+}
+
+/*! Removes a sceneObject from a path.
+@param SceneObject The object that will be detached from the path.
+@return No return value.
+*/
+ConsoleMethodWithDocs(Path, detachObject, ConsoleVoid, 3, 3, (sceneObject))
+{
+   // Set Group.
+   SceneObject* pSceneObject = dynamic_cast<SceneObject*>(Sim::findObject(argv[2]));
+
+   if (pSceneObject)
+      object->detachObject(pSceneObject);
+   else
+      Con::warnf("Path::detachObject() - Could not find the specified object '%s'.", argv[2]);
+}
+
+/*! Adds a node to a path.
+@param x The horizontal position of the node in world units.
+@param y The vertical position of the node in world units.
+@param distance The distance a from a node that it object must reach before it is considered to have reached the node, if snapToNode is set true for the object.
+@return No return value.
+*/
+ConsoleMethodWithDocs(Path, addNode, ConsoleVoid, 3, 6, (float x, float y, [float distance], [float weight]))
+{
+   Vector2 position;
+   position.Set(dAtof(argv[2]), dAtof(argv[3]));
+
+   F32 distance = 0.0f;
+   if (argc > 4)
+   {
+      distance = dAtof(argv[4]);
+   }
+
+   F32 weight = 0.0f;
+   if(argc > 5)
+   {
+      weight = dAtof(argv[5]);
+   }
+
+   object->addNode(position, distance, weight);
+}

+ 1 - 1
engine/source/2d/sceneobject/SceneObject.cc

@@ -581,7 +581,7 @@ void SceneObject::preIntegrate( const F32 totalTime, const F32 elapsedTime, Debu
    // Finish if nothing is dirty.
     if ( !mSpatialDirty )
         return;
-
+    
     // Reset spatial changed.
     mSpatialDirty = false;
 

+ 68 - 68
engine/source/Box2D/Box2D.h

@@ -1,68 +1,68 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef BOX2D_H
-#define BOX2D_H
-
-/**
-\mainpage Box2D API Documentation
-
-\section intro_sec Getting Started
-
-For documentation please see http://box2d.org/documentation.html
-
-For discussion please visit http://box2d.org/forum
-*/
-
-// These include files constitute the main Box2D API
-
-#include <Box2D/Common/b2Settings.h>
-#include <Box2D/Common/b2Draw.h>
-#include <Box2D/Common/b2Timer.h>
-
-#include <Box2D/Collision/Shapes/b2CircleShape.h>
-#include <Box2D/Collision/Shapes/b2EdgeShape.h>
-#include <Box2D/Collision/Shapes/b2ChainShape.h>
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-
-#include <Box2D/Collision/b2BroadPhase.h>
-#include <Box2D/Collision/b2Distance.h>
-#include <Box2D/Collision/b2DynamicTree.h>
-#include <Box2D/Collision/b2TimeOfImpact.h>
-
-#include <Box2D/Dynamics/b2Body.h>
-#include <Box2D/Dynamics/b2Fixture.h>
-#include <Box2D/Dynamics/b2WorldCallbacks.h>
-#include <Box2D/Dynamics/b2TimeStep.h>
-#include <Box2D/Dynamics/b2World.h>
-
-#include <Box2D/Dynamics/Contacts/b2Contact.h>
-
-#include <Box2D/Dynamics/Joints/b2DistanceJoint.h>
-#include <Box2D/Dynamics/Joints/b2FrictionJoint.h>
-#include <Box2D/Dynamics/Joints/b2GearJoint.h>
-#include <Box2D/Dynamics/Joints/b2MotorJoint.h>
-#include <Box2D/Dynamics/Joints/b2MouseJoint.h>
-#include <Box2D/Dynamics/Joints/b2PrismaticJoint.h>
-#include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
-#include <Box2D/Dynamics/Joints/b2RevoluteJoint.h>
-#include <Box2D/Dynamics/Joints/b2RopeJoint.h>
-#include <Box2D/Dynamics/Joints/b2WeldJoint.h>
-#include <Box2D/Dynamics/Joints/b2WheelJoint.h>
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BOX2D_H
+#define BOX2D_H
+
+/**
+\mainpage LiquidFun API Documentation
+
+*/
+
+// These include files constitute the main Box2D API
+
+#include <Box2D/Common/b2Settings.h>
+#include <Box2D/Common/b2Draw.h>
+#include <Box2D/Common/b2Stat.h>
+#include <Box2D/Common/b2Timer.h>
+
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+#include <Box2D/Collision/b2BroadPhase.h>
+#include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/b2DynamicTree.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2WorldCallbacks.h>
+#include <Box2D/Dynamics/b2TimeStep.h>
+#include <Box2D/Dynamics/b2World.h>
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+#include <Box2D/Dynamics/Joints/b2DistanceJoint.h>
+#include <Box2D/Dynamics/Joints/b2FrictionJoint.h>
+#include <Box2D/Dynamics/Joints/b2GearJoint.h>
+#include <Box2D/Dynamics/Joints/b2MotorJoint.h>
+#include <Box2D/Dynamics/Joints/b2MouseJoint.h>
+#include <Box2D/Dynamics/Joints/b2PrismaticJoint.h>
+#include <Box2D/Dynamics/Joints/b2PulleyJoint.h>
+#include <Box2D/Dynamics/Joints/b2RevoluteJoint.h>
+#include <Box2D/Dynamics/Joints/b2RopeJoint.h>
+#include <Box2D/Dynamics/Joints/b2WeldJoint.h>
+#include <Box2D/Dynamics/Joints/b2WheelJoint.h>
+
+#include <Box2D/Particle/b2Particle.h>
+#include <Box2D/Particle/b2ParticleGroup.h>
+
+#endif

+ 203 - 188
engine/source/Box2D/Collision/Shapes/b2ChainShape.cpp

@@ -1,188 +1,203 @@
-/*
-* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/Shapes/b2ChainShape.h>
-#include <Box2D/Collision/Shapes/b2EdgeShape.h>
-#include <new>
-#include <cstring>
-using namespace std;
-
-b2ChainShape::~b2ChainShape()
-{
-	b2Free(m_vertices);
-	m_vertices = NULL;
-	m_count = 0;
-}
-
-void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count)
-{
-	b2Assert(m_vertices == NULL && m_count == 0);
-	b2Assert(count >= 3);
-	for (int32 i = 1; i < count; ++i)
-	{
-		b2Vec2 v1 = vertices[i-1];
-		b2Vec2 v2 = vertices[i];
-		// If the code crashes here, it means your vertices are too close together.
-		b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop);
-	}
-
-	m_count = count + 1;
-	m_vertices = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2));
-	memcpy(m_vertices, vertices, count * sizeof(b2Vec2));
-	m_vertices[count] = m_vertices[0];
-	m_prevVertex = m_vertices[m_count - 2];
-	m_nextVertex = m_vertices[1];
-	m_hasPrevVertex = true;
-	m_hasNextVertex = true;
-}
-
-void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 count)
-{
-	b2Assert(m_vertices == NULL && m_count == 0);
-	b2Assert(count >= 2);
-	for (int32 i = 1; i < count; ++i)
-	{
-		b2Vec2 v1 = vertices[i-1];
-		b2Vec2 v2 = vertices[i];
-		// If the code crashes here, it means your vertices are too close together.
-		b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop);
-	}
-
-	m_count = count;
-	m_vertices = (b2Vec2*)b2Alloc(count * sizeof(b2Vec2));
-	memcpy(m_vertices, vertices, m_count * sizeof(b2Vec2));
-
-	m_hasPrevVertex = false;
-	m_hasNextVertex = false;
-}
-
-void b2ChainShape::SetPrevVertex(const b2Vec2& prevVertex)
-{
-	m_prevVertex = prevVertex;
-	m_hasPrevVertex = true;
-}
-
-void b2ChainShape::SetNextVertex(const b2Vec2& nextVertex)
-{
-	m_nextVertex = nextVertex;
-	m_hasNextVertex = true;
-}
-
-b2Shape* b2ChainShape::Clone(b2BlockAllocator* allocator) const
-{
-	void* mem = allocator->Allocate(sizeof(b2ChainShape));
-	b2ChainShape* clone = new (mem) b2ChainShape;
-	clone->CreateChain(m_vertices, m_count);
-	clone->m_prevVertex = m_prevVertex;
-	clone->m_nextVertex = m_nextVertex;
-	clone->m_hasPrevVertex = m_hasPrevVertex;
-	clone->m_hasNextVertex = m_hasNextVertex;
-	return clone;
-}
-
-int32 b2ChainShape::GetChildCount() const
-{
-	// edge count = vertex count - 1
-	return m_count - 1;
-}
-
-void b2ChainShape::GetChildEdge(b2EdgeShape* edge, int32 index) const
-{
-	b2Assert(0 <= index && index < m_count - 1);
-	edge->m_type = b2Shape::e_edge;
-	edge->m_radius = m_radius;
-
-	edge->m_vertex1 = m_vertices[index + 0];
-	edge->m_vertex2 = m_vertices[index + 1];
-
-	if (index > 0)
-	{
-		edge->m_vertex0 = m_vertices[index - 1];
-		edge->m_hasVertex0 = true;
-	}
-	else
-	{
-		edge->m_vertex0 = m_prevVertex;
-		edge->m_hasVertex0 = m_hasPrevVertex;
-	}
-
-	if (index < m_count - 2)
-	{
-		edge->m_vertex3 = m_vertices[index + 2];
-		edge->m_hasVertex3 = true;
-	}
-	else
-	{
-		edge->m_vertex3 = m_nextVertex;
-		edge->m_hasVertex3 = m_hasNextVertex;
-	}
-}
-
-bool b2ChainShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
-{
-	B2_NOT_USED(xf);
-	B2_NOT_USED(p);
-	return false;
-}
-
-bool b2ChainShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-							const b2Transform& xf, int32 childIndex) const
-{
-	b2Assert(childIndex < m_count);
-
-	b2EdgeShape edgeShape;
-
-	int32 i1 = childIndex;
-	int32 i2 = childIndex + 1;
-	if (i2 == m_count)
-	{
-		i2 = 0;
-	}
-
-	edgeShape.m_vertex1 = m_vertices[i1];
-	edgeShape.m_vertex2 = m_vertices[i2];
-
-	return edgeShape.RayCast(output, input, xf, 0);
-}
-
-void b2ChainShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
-{
-	b2Assert(childIndex < m_count);
-
-	int32 i1 = childIndex;
-	int32 i2 = childIndex + 1;
-	if (i2 == m_count)
-	{
-		i2 = 0;
-	}
-
-	b2Vec2 v1 = b2Mul(xf, m_vertices[i1]);
-	b2Vec2 v2 = b2Mul(xf, m_vertices[i2]);
-
-	aabb->lowerBound = b2Min(v1, v2);
-	aabb->upperBound = b2Max(v1, v2);
-}
-
-void b2ChainShape::ComputeMass(b2MassData* massData, float32 density) const
-{
-	B2_NOT_USED(density);
-
-	massData->mass = 0.0f;
-	massData->center.SetZero();
-	massData->I = 0.0f;
-}
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <new>
+#include <memory.h>
+#include <string.h>
+
+b2ChainShape::~b2ChainShape()
+{
+	b2Free(m_vertices);
+	m_vertices = NULL;
+	m_count = 0;
+}
+
+void b2ChainShape::CreateLoop(const b2Vec2* vertices, int32 count)
+{
+	b2Assert(m_vertices == NULL && m_count == 0);
+	b2Assert(count >= 3);
+	for (int32 i = 1; i < count; ++i)
+	{
+#if B2_ASSERT_ENABLED
+		b2Vec2 v1 = vertices[i-1];
+		b2Vec2 v2 = vertices[i];
+		// If the code crashes here, it means your vertices are too close together.
+		b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop);
+#endif // B2_ASSERT_ENABLED
+	}
+
+	m_count = count + 1;
+	m_vertices = (b2Vec2*)b2Alloc(m_count * sizeof(b2Vec2));
+	memcpy(m_vertices, vertices, count * sizeof(b2Vec2));
+	m_vertices[count] = m_vertices[0];
+	m_prevVertex = m_vertices[m_count - 2];
+	m_nextVertex = m_vertices[1];
+	m_hasPrevVertex = true;
+	m_hasNextVertex = true;
+}
+
+void b2ChainShape::CreateChain(const b2Vec2* vertices, int32 count)
+{
+	b2Assert(m_vertices == NULL && m_count == 0);
+	b2Assert(count >= 2);
+	for (int32 i = 1; i < count; ++i)
+	{
+#if B2_ASSERT_ENABLED
+		b2Vec2 v1 = vertices[i-1];
+		b2Vec2 v2 = vertices[i];
+		// If the code crashes here, it means your vertices are too close together.
+		b2Assert(b2DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop);
+#endif // B2_ASSERT_ENABLED
+	}
+
+	m_count = count;
+	m_vertices = (b2Vec2*)b2Alloc(count * sizeof(b2Vec2));
+	memcpy(m_vertices, vertices, m_count * sizeof(b2Vec2));
+
+	m_hasPrevVertex = false;
+	m_hasNextVertex = false;
+
+	m_prevVertex.SetZero();
+	m_nextVertex.SetZero();
+}
+
+void b2ChainShape::SetPrevVertex(const b2Vec2& prevVertex)
+{
+	m_prevVertex = prevVertex;
+	m_hasPrevVertex = true;
+}
+
+void b2ChainShape::SetNextVertex(const b2Vec2& nextVertex)
+{
+	m_nextVertex = nextVertex;
+	m_hasNextVertex = true;
+}
+
+b2Shape* b2ChainShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2ChainShape));
+	b2ChainShape* clone = new (mem) b2ChainShape;
+	clone->CreateChain(m_vertices, m_count);
+	clone->m_prevVertex = m_prevVertex;
+	clone->m_nextVertex = m_nextVertex;
+	clone->m_hasPrevVertex = m_hasPrevVertex;
+	clone->m_hasNextVertex = m_hasNextVertex;
+	return clone;
+}
+
+int32 b2ChainShape::GetChildCount() const
+{
+	// edge count = vertex count - 1
+	return m_count - 1;
+}
+
+void b2ChainShape::GetChildEdge(b2EdgeShape* edge, int32 index) const
+{
+	b2Assert(0 <= index && index < m_count - 1);
+	edge->m_type = b2Shape::e_edge;
+	edge->m_radius = m_radius;
+
+	edge->m_vertex1 = m_vertices[index + 0];
+	edge->m_vertex2 = m_vertices[index + 1];
+
+	if (index > 0)
+	{
+		edge->m_vertex0 = m_vertices[index - 1];
+		edge->m_hasVertex0 = true;
+	}
+	else
+	{
+		edge->m_vertex0 = m_prevVertex;
+		edge->m_hasVertex0 = m_hasPrevVertex;
+	}
+
+	if (index < m_count - 2)
+	{
+		edge->m_vertex3 = m_vertices[index + 2];
+		edge->m_hasVertex3 = true;
+	}
+	else
+	{
+		edge->m_vertex3 = m_nextVertex;
+		edge->m_hasVertex3 = m_hasNextVertex;
+	}
+}
+
+void b2ChainShape::ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const
+{
+	b2EdgeShape edge;
+	GetChildEdge(&edge, childIndex);
+	edge.ComputeDistance(xf, p, distance, normal, 0);
+}
+
+bool b2ChainShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
+{
+	B2_NOT_USED(xf);
+	B2_NOT_USED(p);
+	return false;
+}
+
+bool b2ChainShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+							const b2Transform& xf, int32 childIndex) const
+{
+	b2Assert(childIndex < m_count);
+
+	b2EdgeShape edgeShape;
+
+	int32 i1 = childIndex;
+	int32 i2 = childIndex + 1;
+	if (i2 == m_count)
+	{
+		i2 = 0;
+	}
+
+	edgeShape.m_vertex1 = m_vertices[i1];
+	edgeShape.m_vertex2 = m_vertices[i2];
+
+	return edgeShape.RayCast(output, input, xf, 0);
+}
+
+void b2ChainShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
+{
+	b2Assert(childIndex < m_count);
+
+	int32 i1 = childIndex;
+	int32 i2 = childIndex + 1;
+	if (i2 == m_count)
+	{
+		i2 = 0;
+	}
+
+	b2Vec2 v1 = b2Mul(xf, m_vertices[i1]);
+	b2Vec2 v2 = b2Mul(xf, m_vertices[i2]);
+
+	aabb->lowerBound = b2Min(v1, v2);
+	aabb->upperBound = b2Max(v1, v2);
+}
+
+void b2ChainShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	B2_NOT_USED(density);
+
+	massData->mass = 0.0f;
+	massData->center.SetZero();
+	massData->I = 0.0f;
+}

+ 106 - 102
engine/source/Box2D/Collision/Shapes/b2ChainShape.h

@@ -1,102 +1,106 @@
-/*
-* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_CHAIN_SHAPE_H
-#define B2_CHAIN_SHAPE_H
-
-#include <Box2D/Collision/Shapes/b2Shape.h>
-
-class b2EdgeShape;
-
-/// A chain shape is a free form sequence of line segments.
-/// The chain has two-sided collision, so you can use inside and outside collision.
-/// Therefore, you may use any winding order.
-/// Since there may be many vertices, they are allocated using b2Alloc.
-/// Connectivity information is used to create smooth collisions.
-/// WARNING: The chain will not collide properly if there are self-intersections.
-class b2ChainShape : public b2Shape
-{
-public:
-	b2ChainShape();
-
-	/// The destructor frees the vertices using b2Free.
-	~b2ChainShape();
-
-	/// Create a loop. This automatically adjusts connectivity.
-	/// @param vertices an array of vertices, these are copied
-	/// @param count the vertex count
-	void CreateLoop(const b2Vec2* vertices, int32 count);
-
-	/// Create a chain with isolated end vertices.
-	/// @param vertices an array of vertices, these are copied
-	/// @param count the vertex count
-	void CreateChain(const b2Vec2* vertices, int32 count);
-
-	/// Establish connectivity to a vertex that precedes the first vertex.
-	/// Don't call this for loops.
-	void SetPrevVertex(const b2Vec2& prevVertex);
-
-	/// Establish connectivity to a vertex that follows the last vertex.
-	/// Don't call this for loops.
-	void SetNextVertex(const b2Vec2& nextVertex);
-
-	/// Implement b2Shape. Vertices are cloned using b2Alloc.
-	b2Shape* Clone(b2BlockAllocator* allocator) const;
-
-	/// @see b2Shape::GetChildCount
-	int32 GetChildCount() const;
-
-	/// Get a child edge.
-	void GetChildEdge(b2EdgeShape* edge, int32 index) const;
-
-	/// This always return false.
-	/// @see b2Shape::TestPoint
-	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
-
-	/// Implement b2Shape.
-	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-					const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeAABB
-	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
-
-	/// Chains have zero mass.
-	/// @see b2Shape::ComputeMass
-	void ComputeMass(b2MassData* massData, float32 density) const;
-
-	/// The vertices. Owned by this class.
-	b2Vec2* m_vertices;
-
-	/// The vertex count.
-	int32 m_count;
-
-	b2Vec2 m_prevVertex, m_nextVertex;
-	bool m_hasPrevVertex, m_hasNextVertex;
-};
-
-inline b2ChainShape::b2ChainShape()
-{
-	m_type = e_chain;
-	m_radius = b2_polygonRadius;
-	m_vertices = NULL;
-	m_count = 0;
-	m_hasPrevVertex = false;
-	m_hasNextVertex = false;
-}
-
-#endif
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CHAIN_SHAPE_H
+#define B2_CHAIN_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+class b2EdgeShape;
+
+/// A chain shape is a free form sequence of line segments.
+/// The chain has two-sided collision, so you can use inside and outside collision.
+/// Therefore, you may use any winding order.
+/// Since there may be many vertices, they are allocated using b2Alloc.
+/// Connectivity information is used to create smooth collisions.
+/// WARNING: The chain will not collide properly if there are self-intersections.
+class b2ChainShape : public b2Shape
+{
+public:
+	b2ChainShape();
+
+	/// The destructor frees the vertices using b2Free.
+	~b2ChainShape();
+
+	/// Create a loop. This automatically adjusts connectivity.
+	/// @param vertices an array of vertices, these are copied
+	/// @param count the vertex count
+	void CreateLoop(const b2Vec2* vertices, int32 count);
+
+	/// Create a chain with isolated end vertices.
+	/// @param vertices an array of vertices, these are copied
+	/// @param count the vertex count
+	void CreateChain(const b2Vec2* vertices, int32 count);
+
+	/// Establish connectivity to a vertex that precedes the first vertex.
+	/// Don't call this for loops.
+	void SetPrevVertex(const b2Vec2& prevVertex);
+
+	/// Establish connectivity to a vertex that follows the last vertex.
+	/// Don't call this for loops.
+	void SetNextVertex(const b2Vec2& nextVertex);
+
+	/// Implement b2Shape. Vertices are cloned using b2Alloc.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// Get a child edge.
+	void GetChildEdge(b2EdgeShape* edge, int32 index) const;
+
+	/// This always return false.
+	/// @see b2Shape::TestPoint
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	// @see b2Shape::ComputeDistance
+	void ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+					const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// Chains have zero mass.
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// The vertices. Owned by this class.
+	b2Vec2* m_vertices;
+
+	/// The vertex count.
+	int32 m_count;
+
+	b2Vec2 m_prevVertex, m_nextVertex;
+	bool m_hasPrevVertex, m_hasNextVertex;
+};
+
+inline b2ChainShape::b2ChainShape()
+{
+	m_type = e_chain;
+	m_radius = b2_polygonRadius;
+	m_vertices = NULL;
+	m_count = 0;
+	m_hasPrevVertex = false;
+	m_hasNextVertex = false;
+}
+
+#endif

+ 111 - 100
engine/source/Box2D/Collision/Shapes/b2CircleShape.cpp

@@ -1,100 +1,111 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/Shapes/b2CircleShape.h>
-#include <new>
-using namespace std;
-
-b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const
-{
-	void* mem = allocator->Allocate(sizeof(b2CircleShape));
-	b2CircleShape* clone = new (mem) b2CircleShape;
-	*clone = *this;
-	return clone;
-}
-
-int32 b2CircleShape::GetChildCount() const
-{
-	return 1;
-}
-
-bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const
-{
-	b2Vec2 center = transform.p + b2Mul(transform.q, m_p);
-	b2Vec2 d = p - center;
-	return b2Dot(d, d) <= m_radius * m_radius;
-}
-
-// Collision Detection in Interactive 3D Environments by Gino van den Bergen
-// From Section 3.1.2
-// x = s + a * r
-// norm(x) = radius
-bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-							const b2Transform& transform, int32 childIndex) const
-{
-	B2_NOT_USED(childIndex);
-
-	b2Vec2 position = transform.p + b2Mul(transform.q, m_p);
-	b2Vec2 s = input.p1 - position;
-	float32 b = b2Dot(s, s) - m_radius * m_radius;
-
-	// Solve quadratic equation.
-	b2Vec2 r = input.p2 - input.p1;
-	float32 c =  b2Dot(s, r);
-	float32 rr = b2Dot(r, r);
-	float32 sigma = c * c - rr * b;
-
-	// Check for negative discriminant and short segment.
-	if (sigma < 0.0f || rr < b2_epsilon)
-	{
-		return false;
-	}
-
-	// Find the point of intersection of the line with the circle.
-	float32 a = -(c + b2Sqrt(sigma));
-
-	// Is the intersection point on the segment?
-	if (0.0f <= a && a <= input.maxFraction * rr)
-	{
-		a /= rr;
-		output->fraction = a;
-		output->normal = s + a * r;
-		output->normal.Normalize();
-		return true;
-	}
-
-	return false;
-}
-
-void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const
-{
-	B2_NOT_USED(childIndex);
-
-	b2Vec2 p = transform.p + b2Mul(transform.q, m_p);
-	aabb->lowerBound.Set(p.x - m_radius, p.y - m_radius);
-	aabb->upperBound.Set(p.x + m_radius, p.y + m_radius);
-}
-
-void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const
-{
-	massData->mass = density * b2_pi * m_radius * m_radius;
-	massData->center = m_p;
-
-	// inertia about the local origin
-	massData->I = massData->mass * (0.5f * m_radius * m_radius + b2Dot(m_p, m_p));
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <new>
+
+b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2CircleShape));
+	b2CircleShape* clone = new (mem) b2CircleShape;
+	*clone = *this;
+	return clone;
+}
+
+int32 b2CircleShape::GetChildCount() const
+{
+	return 1;
+}
+
+bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const
+{
+	b2Vec2 center = transform.p + b2Mul(transform.q, m_p);
+	b2Vec2 d = p - center;
+	return b2Dot(d, d) <= m_radius * m_radius;
+}
+
+void b2CircleShape::ComputeDistance(const b2Transform& transform, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 center = transform.p + b2Mul(transform.q, m_p);
+	b2Vec2 d = p - center;
+	float32 d1 = d.Length();
+	*distance = d1 - m_radius;
+	*normal = 1 / d1 * d;
+}
+
+// Collision Detection in Interactive 3D Environments by Gino van den Bergen
+// From Section 3.1.2
+// x = s + a * r
+// norm(x) = radius
+bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+							const b2Transform& transform, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 position = transform.p + b2Mul(transform.q, m_p);
+	b2Vec2 s = input.p1 - position;
+	float32 b = b2Dot(s, s) - m_radius * m_radius;
+
+	// Solve quadratic equation.
+	b2Vec2 r = input.p2 - input.p1;
+	float32 c =  b2Dot(s, r);
+	float32 rr = b2Dot(r, r);
+	float32 sigma = c * c - rr * b;
+
+	// Check for negative discriminant and short segment.
+	if (sigma < 0.0f || rr < b2_epsilon)
+	{
+		return false;
+	}
+
+	// Find the point of intersection of the line with the circle.
+	float32 a = -(c + b2Sqrt(sigma));
+
+	// Is the intersection point on the segment?
+	if (0.0f <= a && a <= input.maxFraction * rr)
+	{
+		a /= rr;
+		output->fraction = a;
+		output->normal = s + a * r;
+		output->normal.Normalize();
+		return true;
+	}
+
+	return false;
+}
+
+void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 p = transform.p + b2Mul(transform.q, m_p);
+	aabb->lowerBound.Set(p.x - m_radius, p.y - m_radius);
+	aabb->upperBound.Set(p.x + m_radius, p.y + m_radius);
+}
+
+void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	massData->mass = density * b2_pi * m_radius * m_radius;
+	massData->center = m_p;
+
+	// inertia about the local origin
+	massData->I = massData->mass * (0.5f * m_radius * m_radius + b2Dot(m_p, m_p));
+}

+ 107 - 91
engine/source/Box2D/Collision/Shapes/b2CircleShape.h

@@ -1,91 +1,107 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_CIRCLE_SHAPE_H
-#define B2_CIRCLE_SHAPE_H
-
-#include <Box2D/Collision/Shapes/b2Shape.h>
-
-/// A circle shape.
-class b2CircleShape : public b2Shape
-{
-public:
-	b2CircleShape();
-
-	/// Implement b2Shape.
-	b2Shape* Clone(b2BlockAllocator* allocator) const;
-
-	/// @see b2Shape::GetChildCount
-	int32 GetChildCount() const;
-
-	/// Implement b2Shape.
-	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
-
-	/// Implement b2Shape.
-	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-				const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeAABB
-	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeMass
-	void ComputeMass(b2MassData* massData, float32 density) const;
-
-	/// Get the supporting vertex index in the given direction.
-	int32 GetSupport(const b2Vec2& d) const;
-
-	/// Get the supporting vertex in the given direction.
-	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
-
-	/// Get the vertex count.
-	int32 GetVertexCount() const { return 1; }
-
-	/// Get a vertex by index. Used by b2Distance.
-	const b2Vec2& GetVertex(int32 index) const;
-
-	/// Position
-	b2Vec2 m_p;
-};
-
-inline b2CircleShape::b2CircleShape()
-{
-	m_type = e_circle;
-	m_radius = 0.0f;
-	m_p.SetZero();
-}
-
-inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const
-{
-	B2_NOT_USED(d);
-	return 0;
-}
-
-inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const
-{
-	B2_NOT_USED(d);
-	return m_p;
-}
-
-inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const
-{
-	B2_NOT_USED(index);
-	b2Assert(index == 0);
-	return m_p;
-}
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CIRCLE_SHAPE_H
+#define B2_CIRCLE_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A circle shape.
+class b2CircleShape : public b2Shape
+{
+public:
+	b2CircleShape();
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// Implement b2Shape.
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	// @see b2Shape::ComputeDistance
+	void ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+				const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// Get the supporting vertex index in the given direction.
+	int32 GetSupport(const b2Vec2& d) const;
+
+	/// Get the supporting vertex in the given direction.
+	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const { return 1; }
+
+	/// Get a vertex by index. Used by b2Distance.
+	const b2Vec2& GetVertex(int32 index) const;
+
+#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
+public:
+	/// Set position with direct floats.
+	void SetPosition(float32 x, float32 y) { m_p.Set(x, y); }
+
+	/// Get x-coordinate of position.
+	float32 GetPositionX() const { return m_p.x; }
+
+	/// Get y-coordinate of position.
+	float32 GetPositionY() const { return m_p.y; }
+#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
+
+	/// Position
+	b2Vec2 m_p;
+};
+
+inline b2CircleShape::b2CircleShape()
+{
+	m_type = e_circle;
+	m_radius = 0.0f;
+	m_p.SetZero();
+}
+
+inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const
+{
+	B2_NOT_USED(d);
+	return 0;
+}
+
+inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const
+{
+	B2_NOT_USED(d);
+	return m_p;
+}
+
+inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const
+{
+	B2_NOT_USED(index);
+	b2Assert(index == 0);
+	return m_p;
+}
+
+#endif

+ 168 - 139
engine/source/Box2D/Collision/Shapes/b2EdgeShape.cpp

@@ -1,139 +1,168 @@
-/*
-* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/Shapes/b2EdgeShape.h>
-#include <new>
-using namespace std;
-
-void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2)
-{
-	m_vertex1 = v1;
-	m_vertex2 = v2;
-	m_hasVertex0 = false;
-	m_hasVertex3 = false;
-}
-
-b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const
-{
-	void* mem = allocator->Allocate(sizeof(b2EdgeShape));
-	b2EdgeShape* clone = new (mem) b2EdgeShape;
-	*clone = *this;
-	return clone;
-}
-
-int32 b2EdgeShape::GetChildCount() const
-{
-	return 1;
-}
-
-bool b2EdgeShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
-{
-	B2_NOT_USED(xf);
-	B2_NOT_USED(p);
-	return false;
-}
-
-// p = p1 + t * d
-// v = v1 + s * e
-// p1 + t * d = v1 + s * e
-// s * e - t * d = p1 - v1
-bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-							const b2Transform& xf, int32 childIndex) const
-{
-	B2_NOT_USED(childIndex);
-
-	// Put the ray into the edge's frame of reference.
-	b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
-	b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
-	b2Vec2 d = p2 - p1;
-
-	b2Vec2 v1 = m_vertex1;
-	b2Vec2 v2 = m_vertex2;
-	b2Vec2 e = v2 - v1;
-	b2Vec2 normal(e.y, -e.x);
-	normal.Normalize();
-
-	// q = p1 + t * d
-	// dot(normal, q - v1) = 0
-	// dot(normal, p1 - v1) + t * dot(normal, d) = 0
-	float32 numerator = b2Dot(normal, v1 - p1);
-	float32 denominator = b2Dot(normal, d);
-
-	if (denominator == 0.0f)
-	{
-		return false;
-	}
-
-	float32 t = numerator / denominator;
-	if (t < 0.0f || input.maxFraction < t)
-	{
-		return false;
-	}
-
-	b2Vec2 q = p1 + t * d;
-
-	// q = v1 + s * r
-	// s = dot(q - v1, r) / dot(r, r)
-	b2Vec2 r = v2 - v1;
-	float32 rr = b2Dot(r, r);
-	if (rr == 0.0f)
-	{
-		return false;
-	}
-
-	float32 s = b2Dot(q - v1, r) / rr;
-	if (s < 0.0f || 1.0f < s)
-	{
-		return false;
-	}
-
-	output->fraction = t;
-	if (numerator > 0.0f)
-	{
-		output->normal = -normal;
-	}
-	else
-	{
-		output->normal = normal;
-	}
-	return true;
-}
-
-void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
-{
-	B2_NOT_USED(childIndex);
-
-	b2Vec2 v1 = b2Mul(xf, m_vertex1);
-	b2Vec2 v2 = b2Mul(xf, m_vertex2);
-
-	b2Vec2 lower = b2Min(v1, v2);
-	b2Vec2 upper = b2Max(v1, v2);
-
-	b2Vec2 r(m_radius, m_radius);
-	aabb->lowerBound = lower - r;
-	aabb->upperBound = upper + r;
-}
-
-void b2EdgeShape::ComputeMass(b2MassData* massData, float32 density) const
-{
-	B2_NOT_USED(density);
-
-	massData->mass = 0.0f;
-	massData->center = 0.5f * (m_vertex1 + m_vertex2);
-	massData->I = 0.0f;
-}
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <new>
+
+void b2EdgeShape::Set(const b2Vec2& v1, const b2Vec2& v2)
+{
+	m_vertex1 = v1;
+	m_vertex2 = v2;
+	m_hasVertex0 = false;
+	m_hasVertex3 = false;
+}
+
+b2Shape* b2EdgeShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2EdgeShape));
+	b2EdgeShape* clone = new (mem) b2EdgeShape;
+	*clone = *this;
+	return clone;
+}
+
+int32 b2EdgeShape::GetChildCount() const
+{
+	return 1;
+}
+
+bool b2EdgeShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
+{
+	B2_NOT_USED(xf);
+	B2_NOT_USED(p);
+	return false;
+}
+
+void b2EdgeShape::ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 v1 = b2Mul(xf, m_vertex1);
+	b2Vec2 v2 = b2Mul(xf, m_vertex2);
+
+	b2Vec2 d = p - v1;
+	b2Vec2 s = v2 - v1;
+	float32 ds = b2Dot(d, s);
+	if (ds > 0)
+	{
+		float32 s2 = b2Dot(s, s);
+		if (ds > s2)
+		{
+			d = p - v2;
+		}
+		else
+		{
+			d -= ds / s2 * s;
+		}
+	}
+
+	float32 d1 = d.Length();
+	*distance = d1;
+	*normal = d1 > 0 ? 1 / d1 * d : b2Vec2_zero;
+
+}
+
+// p = p1 + t * d
+// v = v1 + s * e
+// p1 + t * d = v1 + s * e
+// s * e - t * d = p1 - v1
+bool b2EdgeShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+							const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	// Put the ray into the edge's frame of reference.
+	b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
+	b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
+	b2Vec2 d = p2 - p1;
+
+	b2Vec2 v1 = m_vertex1;
+	b2Vec2 v2 = m_vertex2;
+	b2Vec2 e = v2 - v1;
+	b2Vec2 normal(e.y, -e.x);
+	normal.Normalize();
+
+	// q = p1 + t * d
+	// dot(normal, q - v1) = 0
+	// dot(normal, p1 - v1) + t * dot(normal, d) = 0
+	float32 numerator = b2Dot(normal, v1 - p1);
+	float32 denominator = b2Dot(normal, d);
+
+	if (denominator == 0.0f)
+	{
+		return false;
+	}
+
+	float32 t = numerator / denominator;
+	if (t < 0.0f || input.maxFraction < t)
+	{
+		return false;
+	}
+
+	b2Vec2 q = p1 + t * d;
+
+	// q = v1 + s * r
+	// s = dot(q - v1, r) / dot(r, r)
+	b2Vec2 r = v2 - v1;
+	float32 rr = b2Dot(r, r);
+	if (rr == 0.0f)
+	{
+		return false;
+	}
+
+	float32 s = b2Dot(q - v1, r) / rr;
+	if (s < 0.0f || 1.0f < s)
+	{
+		return false;
+	}
+
+	output->fraction = t;
+	if (numerator > 0.0f)
+	{
+		output->normal = -b2Mul(xf.q, normal);
+	}
+	else
+	{
+		output->normal = b2Mul(xf.q, normal);
+	}
+	return true;
+}
+
+void b2EdgeShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 v1 = b2Mul(xf, m_vertex1);
+	b2Vec2 v2 = b2Mul(xf, m_vertex2);
+
+	b2Vec2 lower = b2Min(v1, v2);
+	b2Vec2 upper = b2Max(v1, v2);
+
+	b2Vec2 r(m_radius, m_radius);
+	aabb->lowerBound = lower - r;
+	aabb->upperBound = upper + r;
+}
+
+void b2EdgeShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	B2_NOT_USED(density);
+
+	massData->mass = 0.0f;
+	massData->center = 0.5f * (m_vertex1 + m_vertex2);
+	massData->I = 0.0f;
+}

+ 94 - 74
engine/source/Box2D/Collision/Shapes/b2EdgeShape.h

@@ -1,74 +1,94 @@
-/*
-* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_EDGE_SHAPE_H
-#define B2_EDGE_SHAPE_H
-
-#include <Box2D/Collision/Shapes/b2Shape.h>
-
-/// A line segment (edge) shape. These can be connected in chains or loops
-/// to other edge shapes. The connectivity information is used to ensure
-/// correct contact normals.
-class b2EdgeShape : public b2Shape
-{
-public:
-	b2EdgeShape();
-
-	/// Set this as an isolated edge.
-	void Set(const b2Vec2& v1, const b2Vec2& v2);
-
-	/// Implement b2Shape.
-	b2Shape* Clone(b2BlockAllocator* allocator) const;
-
-	/// @see b2Shape::GetChildCount
-	int32 GetChildCount() const;
-
-	/// @see b2Shape::TestPoint
-	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
-
-	/// Implement b2Shape.
-	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-				const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeAABB
-	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeMass
-	void ComputeMass(b2MassData* massData, float32 density) const;
-	
-	/// These are the edge vertices
-	b2Vec2 m_vertex1, m_vertex2;
-
-	/// Optional adjacent vertices. These are used for smooth collision.
-	b2Vec2 m_vertex0, m_vertex3;
-	bool m_hasVertex0, m_hasVertex3;
-};
-
-inline b2EdgeShape::b2EdgeShape()
-{
-	m_type = e_edge;
-	m_radius = b2_polygonRadius;
-	m_vertex0.x = 0.0f;
-	m_vertex0.y = 0.0f;
-	m_vertex3.x = 0.0f;
-	m_vertex3.y = 0.0f;
-	m_hasVertex0 = false;
-	m_hasVertex3 = false;
-}
-
-#endif
+/*
+* Copyright (c) 2006-2010 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_EDGE_SHAPE_H
+#define B2_EDGE_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A line segment (edge) shape. These can be connected in chains or loops
+/// to other edge shapes. The connectivity information is used to ensure
+/// correct contact normals.
+class b2EdgeShape : public b2Shape
+{
+public:
+	b2EdgeShape();
+
+	/// Set this as an isolated edge.
+	void Set(const b2Vec2& v1, const b2Vec2& v2);
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// @see b2Shape::TestPoint
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	// @see b2Shape::ComputeDistance
+	void ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+				const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
+public:
+	/// Set this as an isolated edge, with direct floats.
+	void Set(float32 vx1, float32 vy1, float32 vx2, float32 vy2);
+#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
+
+	/// These are the edge vertices
+	b2Vec2 m_vertex1, m_vertex2;
+
+	/// Optional adjacent vertices. These are used for smooth collision.
+	b2Vec2 m_vertex0, m_vertex3;
+	bool m_hasVertex0, m_hasVertex3;
+};
+
+inline b2EdgeShape::b2EdgeShape()
+{
+	m_type = e_edge;
+	m_radius = b2_polygonRadius;
+	m_vertex0.x = 0.0f;
+	m_vertex0.y = 0.0f;
+	m_vertex3.x = 0.0f;
+	m_vertex3.y = 0.0f;
+	m_hasVertex0 = false;
+	m_hasVertex3 = false;
+}
+
+#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
+inline void b2EdgeShape::Set(float32 vx1,
+														 float32 vy1,
+														 float32 vx2,
+														 float32 vy2) {
+	Set(b2Vec2(vx1, vy1), b2Vec2(vx2, vy2));
+}
+#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
+
+
+#endif

+ 504 - 434
engine/source/Box2D/Collision/Shapes/b2PolygonShape.cpp

@@ -1,434 +1,504 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-#include <new>
-
-b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const
-{
-	void* mem = allocator->Allocate(sizeof(b2PolygonShape));
-	b2PolygonShape* clone = new (mem) b2PolygonShape;
-	*clone = *this;
-	return clone;
-}
-
-void b2PolygonShape::SetAsBox(float32 hx, float32 hy)
-{
-	m_count = 4;
-	m_vertices[0].Set(-hx, -hy);
-	m_vertices[1].Set( hx, -hy);
-	m_vertices[2].Set( hx,  hy);
-	m_vertices[3].Set(-hx,  hy);
-	m_normals[0].Set(0.0f, -1.0f);
-	m_normals[1].Set(1.0f, 0.0f);
-	m_normals[2].Set(0.0f, 1.0f);
-	m_normals[3].Set(-1.0f, 0.0f);
-	m_centroid.SetZero();
-}
-
-void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle)
-{
-	m_count = 4;
-	m_vertices[0].Set(-hx, -hy);
-	m_vertices[1].Set( hx, -hy);
-	m_vertices[2].Set( hx,  hy);
-	m_vertices[3].Set(-hx,  hy);
-	m_normals[0].Set(0.0f, -1.0f);
-	m_normals[1].Set(1.0f, 0.0f);
-	m_normals[2].Set(0.0f, 1.0f);
-	m_normals[3].Set(-1.0f, 0.0f);
-	m_centroid = center;
-
-	b2Transform xf;
-	xf.p = center;
-	xf.q.Set(angle);
-
-	// Transform vertices and normals.
-	for (int32 i = 0; i < m_count; ++i)
-	{
-		m_vertices[i] = b2Mul(xf, m_vertices[i]);
-		m_normals[i] = b2Mul(xf.q, m_normals[i]);
-	}
-}
-
-int32 b2PolygonShape::GetChildCount() const
-{
-	return 1;
-}
-
-static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count)
-{
-	b2Assert(count >= 3);
-
-	b2Vec2 c; c.Set(0.0f, 0.0f);
-	float32 area = 0.0f;
-
-	// pRef is the reference point for forming triangles.
-	// It's location doesn't change the result (except for rounding error).
-	b2Vec2 pRef(0.0f, 0.0f);
-#if 0
-	// This code would put the reference point inside the polygon.
-	for (int32 i = 0; i < count; ++i)
-	{
-		pRef += vs[i];
-	}
-	pRef *= 1.0f / count;
-#endif
-
-	const float32 inv3 = 1.0f / 3.0f;
-
-	for (int32 i = 0; i < count; ++i)
-	{
-		// Triangle vertices.
-		b2Vec2 p1 = pRef;
-		b2Vec2 p2 = vs[i];
-		b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0];
-
-		b2Vec2 e1 = p2 - p1;
-		b2Vec2 e2 = p3 - p1;
-
-		float32 D = b2Cross(e1, e2);
-
-		float32 triangleArea = 0.5f * D;
-		area += triangleArea;
-
-		// Area weighted centroid
-		c += triangleArea * inv3 * (p1 + p2 + p3);
-	}
-
-	// Centroid
-	b2Assert(area > b2_epsilon);
-	c *= 1.0f / area;
-	return c;
-}
-
-void b2PolygonShape::Set(const b2Vec2* vertices, int32 count)
-{
-	b2Assert(3 <= count && count <= b2_maxPolygonVertices);
-	if (count < 3)
-	{
-		SetAsBox(1.0f, 1.0f);
-		return;
-	}
-	
-	int32 n = b2Min(count, b2_maxPolygonVertices);
-
-	// Copy vertices into local buffer
-	b2Vec2 ps[b2_maxPolygonVertices];
-	for (int32 i = 0; i < n; ++i)
-	{
-		ps[i] = vertices[i];
-	}
-
-	// Create the convex hull using the Gift wrapping algorithm
-	// http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
-
-	// Find the right most point on the hull
-	int32 i0 = 0;
-	float32 x0 = ps[0].x;
-	for (int32 i = 1; i < count; ++i)
-	{
-		float32 x = ps[i].x;
-		if (x > x0 || (x == x0 && ps[i].y < ps[i0].y))
-		{
-			i0 = i;
-			x0 = x;
-		}
-	}
-
-	int32 hull[b2_maxPolygonVertices];
-	int32 m = 0;
-	int32 ih = i0;
-
-	for (;;)
-	{
-		hull[m] = ih;
-
-		int32 ie = 0;
-		for (int32 j = 1; j < n; ++j)
-		{
-			if (ie == ih)
-			{
-				ie = j;
-				continue;
-			}
-
-			b2Vec2 r = ps[ie] - ps[hull[m]];
-			b2Vec2 v = ps[j] - ps[hull[m]];
-			float32 c = b2Cross(r, v);
-			if (c < 0.0f)
-			{
-				ie = j;
-			}
-
-			// Collinearity check
-			if (c == 0.0f && v.LengthSquared() > r.LengthSquared())
-			{
-				ie = j;
-			}
-		}
-
-		++m;
-		ih = ie;
-
-		if (ie == i0)
-		{
-			break;
-		}
-	}
-	
-	m_count = m;
-
-	// Copy vertices.
-	for (int32 i = 0; i < m; ++i)
-	{
-		m_vertices[i] = ps[hull[i]];
-	}
-
-	// Compute normals. Ensure the edges have non-zero length.
-	for (int32 i = 0; i < m; ++i)
-	{
-		int32 i1 = i;
-		int32 i2 = i + 1 < m ? i + 1 : 0;
-		b2Vec2 edge = m_vertices[i2] - m_vertices[i1];
-		b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon);
-		m_normals[i] = b2Cross(edge, 1.0f);
-		m_normals[i].Normalize();
-	}
-
-	// Compute the polygon centroid.
-	m_centroid = ComputeCentroid(m_vertices, m);
-}
-
-bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
-{
-	b2Vec2 pLocal = b2MulT(xf.q, p - xf.p);
-
-	for (int32 i = 0; i < m_count; ++i)
-	{
-		float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
-		if (dot > 0.0f)
-		{
-			return false;
-		}
-	}
-
-	return true;
-}
-
-bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-								const b2Transform& xf, int32 childIndex) const
-{
-	B2_NOT_USED(childIndex);
-
-	// Put the ray into the polygon's frame of reference.
-	b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
-	b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
-	b2Vec2 d = p2 - p1;
-
-	float32 lower = 0.0f, upper = input.maxFraction;
-
-	int32 index = -1;
-
-	for (int32 i = 0; i < m_count; ++i)
-	{
-		// p = p1 + a * d
-		// dot(normal, p - v) = 0
-		// dot(normal, p1 - v) + a * dot(normal, d) = 0
-		float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1);
-		float32 denominator = b2Dot(m_normals[i], d);
-
-		if (denominator == 0.0f)
-		{	
-			if (numerator < 0.0f)
-			{
-				return false;
-			}
-		}
-		else
-		{
-			// Note: we want this predicate without division:
-			// lower < numerator / denominator, where denominator < 0
-			// Since denominator < 0, we have to flip the inequality:
-			// lower < numerator / denominator <==> denominator * lower > numerator.
-			if (denominator < 0.0f && numerator < lower * denominator)
-			{
-				// Increase lower.
-				// The segment enters this half-space.
-				lower = numerator / denominator;
-				index = i;
-			}
-			else if (denominator > 0.0f && numerator < upper * denominator)
-			{
-				// Decrease upper.
-				// The segment exits this half-space.
-				upper = numerator / denominator;
-			}
-		}
-
-		// The use of epsilon here causes the assert on lower to trip
-		// in some cases. Apparently the use of epsilon was to make edge
-		// shapes work, but now those are handled separately.
-		//if (upper < lower - b2_epsilon)
-		if (upper < lower)
-		{
-			return false;
-		}
-	}
-
-	b2Assert(0.0f <= lower && lower <= input.maxFraction);
-
-	if (index >= 0)
-	{
-		output->fraction = lower;
-		output->normal = b2Mul(xf.q, m_normals[index]);
-		return true;
-	}
-
-	return false;
-}
-
-void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
-{
-	B2_NOT_USED(childIndex);
-
-	b2Vec2 lower = b2Mul(xf, m_vertices[0]);
-	b2Vec2 upper = lower;
-
-	for (int32 i = 1; i < m_count; ++i)
-	{
-		b2Vec2 v = b2Mul(xf, m_vertices[i]);
-		lower = b2Min(lower, v);
-		upper = b2Max(upper, v);
-	}
-
-	b2Vec2 r(m_radius, m_radius);
-	aabb->lowerBound = lower - r;
-	aabb->upperBound = upper + r;
-}
-
-void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const
-{
-	// Polygon mass, centroid, and inertia.
-	// Let rho be the polygon density in mass per unit area.
-	// Then:
-	// mass = rho * int(dA)
-	// centroid.x = (1/mass) * rho * int(x * dA)
-	// centroid.y = (1/mass) * rho * int(y * dA)
-	// I = rho * int((x*x + y*y) * dA)
-	//
-	// We can compute these integrals by summing all the integrals
-	// for each triangle of the polygon. To evaluate the integral
-	// for a single triangle, we make a change of variables to
-	// the (u,v) coordinates of the triangle:
-	// x = x0 + e1x * u + e2x * v
-	// y = y0 + e1y * u + e2y * v
-	// where 0 <= u && 0 <= v && u + v <= 1.
-	//
-	// We integrate u from [0,1-v] and then v from [0,1].
-	// We also need to use the Jacobian of the transformation:
-	// D = cross(e1, e2)
-	//
-	// Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
-	//
-	// The rest of the derivation is handled by computer algebra.
-
-	b2Assert(m_count >= 3);
-
-	b2Vec2 center; center.Set(0.0f, 0.0f);
-	float32 area = 0.0f;
-	float32 I = 0.0f;
-
-	// s is the reference point for forming triangles.
-	// It's location doesn't change the result (except for rounding error).
-	b2Vec2 s(0.0f, 0.0f);
-
-	// This code would put the reference point inside the polygon.
-	for (int32 i = 0; i < m_count; ++i)
-	{
-		s += m_vertices[i];
-	}
-	s *= 1.0f / m_count;
-
-	const float32 k_inv3 = 1.0f / 3.0f;
-
-	for (int32 i = 0; i < m_count; ++i)
-	{
-		// Triangle vertices.
-		b2Vec2 e1 = m_vertices[i] - s;
-		b2Vec2 e2 = i + 1 < m_count ? m_vertices[i+1] - s : m_vertices[0] - s;
-
-		float32 D = b2Cross(e1, e2);
-
-		float32 triangleArea = 0.5f * D;
-		area += triangleArea;
-
-		// Area weighted centroid
-		center += triangleArea * k_inv3 * (e1 + e2);
-
-		float32 ex1 = e1.x, ey1 = e1.y;
-		float32 ex2 = e2.x, ey2 = e2.y;
-
-		float32 intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2;
-		float32 inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2;
-
-		I += (0.25f * k_inv3 * D) * (intx2 + inty2);
-	}
-
-	// Total mass
-	massData->mass = density * area;
-
-	// Center of mass
-	b2Assert(area > b2_epsilon);
-	center *= 1.0f / area;
-	massData->center = center + s;
-
-	// Inertia tensor relative to the local origin (point s).
-	massData->I = density * I;
-	
-	// Shift to center of mass then to original body origin.
-	massData->I += massData->mass * (b2Dot(massData->center, massData->center) - b2Dot(center, center));
-}
-
-bool b2PolygonShape::Validate() const
-{
-	for (int32 i = 0; i < m_count; ++i)
-	{
-		int32 i1 = i;
-		int32 i2 = i < m_count - 1 ? i1 + 1 : 0;
-		b2Vec2 p = m_vertices[i1];
-		b2Vec2 e = m_vertices[i2] - p;
-
-		for (int32 j = 0; j < m_count; ++j)
-		{
-			if (j == i1 || j == i2)
-			{
-				continue;
-			}
-
-			b2Vec2 v = m_vertices[j] - p;
-			float32 c = b2Cross(e, v);
-			if (c < 0.0f)
-			{
-				return false;
-			}
-		}
-	}
-
-	return true;
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+#include <new>
+
+b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2PolygonShape));
+	b2PolygonShape* clone = new (mem) b2PolygonShape;
+	*clone = *this;
+	return clone;
+}
+
+void b2PolygonShape::SetAsBox(float32 hx, float32 hy)
+{
+	m_count = 4;
+	m_vertices[0].Set(-hx, -hy);
+	m_vertices[1].Set( hx, -hy);
+	m_vertices[2].Set( hx,  hy);
+	m_vertices[3].Set(-hx,  hy);
+	m_normals[0].Set(0.0f, -1.0f);
+	m_normals[1].Set(1.0f, 0.0f);
+	m_normals[2].Set(0.0f, 1.0f);
+	m_normals[3].Set(-1.0f, 0.0f);
+	m_centroid.SetZero();
+}
+
+void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle)
+{
+	m_count = 4;
+	m_vertices[0].Set(-hx, -hy);
+	m_vertices[1].Set( hx, -hy);
+	m_vertices[2].Set( hx,  hy);
+	m_vertices[3].Set(-hx,  hy);
+	m_normals[0].Set(0.0f, -1.0f);
+	m_normals[1].Set(1.0f, 0.0f);
+	m_normals[2].Set(0.0f, 1.0f);
+	m_normals[3].Set(-1.0f, 0.0f);
+	m_centroid = center;
+
+	b2Transform xf;
+	xf.p = center;
+	xf.q.Set(angle);
+
+	// Transform vertices and normals.
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		m_vertices[i] = b2Mul(xf, m_vertices[i]);
+		m_normals[i] = b2Mul(xf.q, m_normals[i]);
+	}
+}
+
+int32 b2PolygonShape::GetChildCount() const
+{
+	return 1;
+}
+
+static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count)
+{
+	b2Assert(count >= 3);
+
+	b2Vec2 c; c.Set(0.0f, 0.0f);
+	float32 area = 0.0f;
+
+	// pRef is the reference point for forming triangles.
+	// It's location doesn't change the result (except for rounding error).
+	b2Vec2 pRef(0.0f, 0.0f);
+#if 0
+	// This code would put the reference point inside the polygon.
+	for (int32 i = 0; i < count; ++i)
+	{
+		pRef += vs[i];
+	}
+	pRef *= 1.0f / count;
+#endif
+
+	const float32 inv3 = 1.0f / 3.0f;
+
+	for (int32 i = 0; i < count; ++i)
+	{
+		// Triangle vertices.
+		b2Vec2 p1 = pRef;
+		b2Vec2 p2 = vs[i];
+		b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0];
+
+		b2Vec2 e1 = p2 - p1;
+		b2Vec2 e2 = p3 - p1;
+
+		float32 D = b2Cross(e1, e2);
+
+		float32 triangleArea = 0.5f * D;
+		area += triangleArea;
+
+		// Area weighted centroid
+		c += triangleArea * inv3 * (p1 + p2 + p3);
+	}
+
+	// Centroid
+	b2Assert(area > b2_epsilon);
+	c *= 1.0f / area;
+	return c;
+}
+
+void b2PolygonShape::Set(const b2Vec2* vertices, int32 count)
+{
+	b2Assert(3 <= count && count <= b2_maxPolygonVertices);
+	if (count < 3)
+	{
+		SetAsBox(1.0f, 1.0f);
+		return;
+	}
+	
+	int32 n = b2Min(count, b2_maxPolygonVertices);
+
+	// Perform welding and copy vertices into local buffer.
+	b2Vec2 ps[b2_maxPolygonVertices];
+	int32 tempCount = 0;
+	for (int32 i = 0; i < n; ++i)
+	{
+		b2Vec2 v = vertices[i];
+
+		bool unique = true;
+		for (int32 j = 0; j < tempCount; ++j)
+		{
+			if (b2DistanceSquared(v, ps[j]) < 0.5f * b2_linearSlop)
+			{
+				unique = false;
+				break;
+			}
+		}
+
+		if (unique)
+		{
+			ps[tempCount++] = v;
+		}
+	}
+
+	n = tempCount;
+	if (n < 3)
+	{
+		// Polygon is degenerate.
+		b2Assert(false);
+		SetAsBox(1.0f, 1.0f);
+		return;
+	}
+
+	// Create the convex hull using the Gift wrapping algorithm
+	// http://en.wikipedia.org/wiki/Gift_wrapping_algorithm
+
+	// Find the right most point on the hull
+	int32 i0 = 0;
+	float32 x0 = ps[0].x;
+	for (int32 i = 1; i < n; ++i)
+	{
+		float32 x = ps[i].x;
+		if (x > x0 || (x == x0 && ps[i].y < ps[i0].y))
+		{
+			i0 = i;
+			x0 = x;
+		}
+	}
+
+	int32 hull[b2_maxPolygonVertices];
+	int32 m = 0;
+	int32 ih = i0;
+
+	for (;;)
+	{
+		hull[m] = ih;
+
+		int32 ie = 0;
+		for (int32 j = 1; j < n; ++j)
+		{
+			if (ie == ih)
+			{
+				ie = j;
+				continue;
+			}
+
+			b2Vec2 r = ps[ie] - ps[hull[m]];
+			b2Vec2 v = ps[j] - ps[hull[m]];
+			float32 c = b2Cross(r, v);
+			if (c < 0.0f)
+			{
+				ie = j;
+			}
+
+			// Collinearity check
+			if (c == 0.0f && v.LengthSquared() > r.LengthSquared())
+			{
+				ie = j;
+			}
+		}
+
+		++m;
+		ih = ie;
+
+		if (ie == i0)
+		{
+			break;
+		}
+	}
+	
+	m_count = m;
+
+	// Copy vertices.
+	for (int32 i = 0; i < m; ++i)
+	{
+		m_vertices[i] = ps[hull[i]];
+	}
+
+	// Compute normals. Ensure the edges have non-zero length.
+	for (int32 i = 0; i < m; ++i)
+	{
+		int32 i1 = i;
+		int32 i2 = i + 1 < m ? i + 1 : 0;
+		b2Vec2 edge = m_vertices[i2] - m_vertices[i1];
+		b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon);
+		m_normals[i] = b2Cross(edge, 1.0f);
+		m_normals[i].Normalize();
+	}
+
+	// Compute the polygon centroid.
+	m_centroid = ComputeCentroid(m_vertices, m);
+}
+
+bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const
+{
+	b2Vec2 pLocal = b2MulT(xf.q, p - xf.p);
+
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
+		if (dot > 0.0f)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+void b2PolygonShape::ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 pLocal = b2MulT(xf.q, p - xf.p);
+	float32 maxDistance = -FLT_MAX;
+	b2Vec2 normalForMaxDistance = pLocal;
+
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);
+		if (dot > maxDistance)
+		{
+			maxDistance = dot;
+			normalForMaxDistance = m_normals[i];
+		}
+	}
+
+	if (maxDistance > 0)
+	{
+		b2Vec2 minDistance = normalForMaxDistance;
+		float32 minDistance2 = maxDistance * maxDistance;
+		for (int32 i = 0; i < m_count; ++i)
+		{
+			b2Vec2 distance = pLocal - m_vertices[i];
+			float32 distance2 = distance.LengthSquared();
+			if (minDistance2 > distance2)
+			{
+				minDistance = distance;
+				minDistance2 = distance2;
+			}
+		}
+
+		*distance = b2Sqrt(minDistance2);
+		*normal = b2Mul(xf.q, minDistance);
+		normal->Normalize();
+	}
+	else
+	{
+		*distance = maxDistance;
+		*normal = b2Mul(xf.q, normalForMaxDistance);
+	}
+}
+
+bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+								const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	// Put the ray into the polygon's frame of reference.
+	b2Vec2 p1 = b2MulT(xf.q, input.p1 - xf.p);
+	b2Vec2 p2 = b2MulT(xf.q, input.p2 - xf.p);
+	b2Vec2 d = p2 - p1;
+
+	float32 lower = 0.0f, upper = input.maxFraction;
+
+	int32 index = -1;
+
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		// p = p1 + a * d
+		// dot(normal, p - v) = 0
+		// dot(normal, p1 - v) + a * dot(normal, d) = 0
+		float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1);
+		float32 denominator = b2Dot(m_normals[i], d);
+
+		if (denominator == 0.0f)
+		{	
+			if (numerator < 0.0f)
+			{
+				return false;
+			}
+		}
+		else
+		{
+			// Note: we want this predicate without division:
+			// lower < numerator / denominator, where denominator < 0
+			// Since denominator < 0, we have to flip the inequality:
+			// lower < numerator / denominator <==> denominator * lower > numerator.
+			if (denominator < 0.0f && numerator < lower * denominator)
+			{
+				// Increase lower.
+				// The segment enters this half-space.
+				lower = numerator / denominator;
+				index = i;
+			}
+			else if (denominator > 0.0f && numerator < upper * denominator)
+			{
+				// Decrease upper.
+				// The segment exits this half-space.
+				upper = numerator / denominator;
+			}
+		}
+
+		// The use of epsilon here causes the assert on lower to trip
+		// in some cases. Apparently the use of epsilon was to make edge
+		// shapes work, but now those are handled separately.
+		//if (upper < lower - b2_epsilon)
+		if (upper < lower)
+		{
+			return false;
+		}
+	}
+
+	b2Assert(0.0f <= lower && lower <= input.maxFraction);
+
+	if (index >= 0)
+	{
+		output->fraction = lower;
+		output->normal = b2Mul(xf.q, m_normals[index]);
+		return true;
+	}
+
+	return false;
+}
+
+void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const
+{
+	B2_NOT_USED(childIndex);
+
+	b2Vec2 lower = b2Mul(xf, m_vertices[0]);
+	b2Vec2 upper = lower;
+
+	for (int32 i = 1; i < m_count; ++i)
+	{
+		b2Vec2 v = b2Mul(xf, m_vertices[i]);
+		lower = b2Min(lower, v);
+		upper = b2Max(upper, v);
+	}
+
+	b2Vec2 r(m_radius, m_radius);
+	aabb->lowerBound = lower - r;
+	aabb->upperBound = upper + r;
+}
+
+void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+	// Polygon mass, centroid, and inertia.
+	// Let rho be the polygon density in mass per unit area.
+	// Then:
+	// mass = rho * int(dA)
+	// centroid.x = (1/mass) * rho * int(x * dA)
+	// centroid.y = (1/mass) * rho * int(y * dA)
+	// I = rho * int((x*x + y*y) * dA)
+	//
+	// We can compute these integrals by summing all the integrals
+	// for each triangle of the polygon. To evaluate the integral
+	// for a single triangle, we make a change of variables to
+	// the (u,v) coordinates of the triangle:
+	// x = x0 + e1x * u + e2x * v
+	// y = y0 + e1y * u + e2y * v
+	// where 0 <= u && 0 <= v && u + v <= 1.
+	//
+	// We integrate u from [0,1-v] and then v from [0,1].
+	// We also need to use the Jacobian of the transformation:
+	// D = cross(e1, e2)
+	//
+	// Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
+	//
+	// The rest of the derivation is handled by computer algebra.
+
+	b2Assert(m_count >= 3);
+
+	b2Vec2 center; center.Set(0.0f, 0.0f);
+	float32 area = 0.0f;
+	float32 I = 0.0f;
+
+	// s is the reference point for forming triangles.
+	// It's location doesn't change the result (except for rounding error).
+	b2Vec2 s(0.0f, 0.0f);
+
+	// This code would put the reference point inside the polygon.
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		s += m_vertices[i];
+	}
+	s *= 1.0f / m_count;
+
+	const float32 k_inv3 = 1.0f / 3.0f;
+
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		// Triangle vertices.
+		b2Vec2 e1 = m_vertices[i] - s;
+		b2Vec2 e2 = i + 1 < m_count ? m_vertices[i+1] - s : m_vertices[0] - s;
+
+		float32 D = b2Cross(e1, e2);
+
+		float32 triangleArea = 0.5f * D;
+		area += triangleArea;
+
+		// Area weighted centroid
+		center += triangleArea * k_inv3 * (e1 + e2);
+
+		float32 ex1 = e1.x, ey1 = e1.y;
+		float32 ex2 = e2.x, ey2 = e2.y;
+
+		float32 intx2 = ex1*ex1 + ex2*ex1 + ex2*ex2;
+		float32 inty2 = ey1*ey1 + ey2*ey1 + ey2*ey2;
+
+		I += (0.25f * k_inv3 * D) * (intx2 + inty2);
+	}
+
+	// Total mass
+	massData->mass = density * area;
+
+	// Center of mass
+	b2Assert(area > b2_epsilon);
+	center *= 1.0f / area;
+	massData->center = center + s;
+
+	// Inertia tensor relative to the local origin (point s).
+	massData->I = density * I;
+	
+	// Shift to center of mass then to original body origin.
+	massData->I += massData->mass * (b2Dot(massData->center, massData->center) - b2Dot(center, center));
+}
+
+bool b2PolygonShape::Validate() const
+{
+	for (int32 i = 0; i < m_count; ++i)
+	{
+		int32 i1 = i;
+		int32 i2 = i < m_count - 1 ? i1 + 1 : 0;
+		b2Vec2 p = m_vertices[i1];
+		b2Vec2 e = m_vertices[i2] - p;
+
+		for (int32 j = 0; j < m_count; ++j)
+		{
+			if (j == i1 || j == i2)
+			{
+				continue;
+			}
+
+			b2Vec2 v = m_vertices[j] - p;
+			float32 c = b2Cross(e, v);
+			if (c < 0.0f)
+			{
+				return false;
+			}
+		}
+	}
+
+	return true;
+}

+ 134 - 101
engine/source/Box2D/Collision/Shapes/b2PolygonShape.h

@@ -1,101 +1,134 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_POLYGON_SHAPE_H
-#define B2_POLYGON_SHAPE_H
-
-#include <Box2D/Collision/Shapes/b2Shape.h>
-
-/// A convex polygon. It is assumed that the interior of the polygon is to
-/// the left of each edge.
-/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
-/// In most cases you should not need many vertices for a convex polygon.
-class b2PolygonShape : public b2Shape
-{
-public:
-	b2PolygonShape();
-
-	/// Implement b2Shape.
-	b2Shape* Clone(b2BlockAllocator* allocator) const;
-
-	/// @see b2Shape::GetChildCount
-	int32 GetChildCount() const;
-
-	/// Create a convex hull from the given array of local points.
-	/// The count must be in the range [3, b2_maxPolygonVertices].
-	/// @warning the points may be re-ordered, even if they form a convex polygon
-	/// @warning collinear points are handled but not removed. Collinear points
-	/// may lead to poor stacking behavior.
-	void Set(const b2Vec2* points, int32 count);
-
-	/// Build vertices to represent an axis-aligned box centered on the local origin.
-	/// @param hx the half-width.
-	/// @param hy the half-height.
-	void SetAsBox(float32 hx, float32 hy);
-
-	/// Build vertices to represent an oriented box.
-	/// @param hx the half-width.
-	/// @param hy the half-height.
-	/// @param center the center of the box in local coordinates.
-	/// @param angle the rotation of the box in local coordinates.
-	void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
-
-	/// @see b2Shape::TestPoint
-	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
-
-	/// Implement b2Shape.
-	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-					const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeAABB
-	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
-
-	/// @see b2Shape::ComputeMass
-	void ComputeMass(b2MassData* massData, float32 density) const;
-
-	/// Get the vertex count.
-	int32 GetVertexCount() const { return m_count; }
-
-	/// Get a vertex by index.
-	const b2Vec2& GetVertex(int32 index) const;
-
-	/// Validate convexity. This is a very time consuming operation.
-	/// @returns true if valid
-	bool Validate() const;
-
-	b2Vec2 m_centroid;
-	b2Vec2 m_vertices[b2_maxPolygonVertices];
-	b2Vec2 m_normals[b2_maxPolygonVertices];
-	int32 m_count;
-};
-
-inline b2PolygonShape::b2PolygonShape()
-{
-	m_type = e_polygon;
-	m_radius = b2_polygonRadius;
-	m_count = 0;
-	m_centroid.SetZero();
-}
-
-inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const
-{
-	b2Assert(0 <= index && index < m_count);
-	return m_vertices[index];
-}
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_POLYGON_SHAPE_H
+#define B2_POLYGON_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A convex polygon. It is assumed that the interior of the polygon is to
+/// the left of each edge.
+/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
+/// In most cases you should not need many vertices for a convex polygon.
+class b2PolygonShape : public b2Shape
+{
+public:
+	b2PolygonShape();
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// @see b2Shape::GetChildCount
+	int32 GetChildCount() const;
+
+	/// Create a convex hull from the given array of local points.
+	/// The count must be in the range [3, b2_maxPolygonVertices].
+	/// @warning the points may be re-ordered, even if they form a convex polygon
+	/// @warning collinear points are handled but not removed. Collinear points
+	/// may lead to poor stacking behavior.
+	void Set(const b2Vec2* points, int32 count);
+
+	/// Build vertices to represent an axis-aligned box centered on the local origin.
+	/// @param hx the half-width.
+	/// @param hy the half-height.
+	void SetAsBox(float32 hx, float32 hy);
+
+	/// Build vertices to represent an oriented box.
+	/// @param hx the half-width.
+	/// @param hy the half-height.
+	/// @param center the center of the box in local coordinates.
+	/// @param angle the rotation of the box in local coordinates.
+	void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
+
+	/// @see b2Shape::TestPoint
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	// @see b2Shape::ComputeDistance
+	void ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+					const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform, int32 childIndex) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const { return m_count; }
+
+	/// Get a vertex by index.
+	const b2Vec2& GetVertex(int32 index) const;
+
+	/// Validate convexity. This is a very time consuming operation.
+	/// @returns true if valid
+	bool Validate() const;
+
+#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
+public:
+	/// Set centroid with direct floats.
+	void SetCentroid(float32 x, float32 y);
+
+	/// SetAsBox with direct floats for center.
+	/// @see b2Shape::SetAsBox
+	void SetAsBox(float32 hx,
+								float32 hy,
+								float32 centerX,
+								float32 centerY,
+								float32 angle);
+#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
+
+	b2Vec2 m_centroid;
+	b2Vec2 m_vertices[b2_maxPolygonVertices];
+	b2Vec2 m_normals[b2_maxPolygonVertices];
+	int32 m_count;
+};
+
+inline b2PolygonShape::b2PolygonShape()
+{
+	m_type = e_polygon;
+	m_radius = b2_polygonRadius;
+	m_count = 0;
+	m_centroid.SetZero();
+}
+
+inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const
+{
+	b2Assert(0 <= index && index < m_count);
+	return m_vertices[index];
+}
+
+#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
+inline void b2PolygonShape::SetCentroid(float32 x, float32 y)
+{
+	m_centroid.Set(x, y);
+}
+
+inline void b2PolygonShape::SetAsBox(float32 hx,
+										 float32 hy,
+										 float32 centerX,
+										 float32 centerY,
+										 float32 angle) {
+	SetAsBox(hx, hy, b2Vec2(centerX, centerY), angle);
+}
+#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
+
+#endif

+ 109 - 101
engine/source/Box2D/Collision/Shapes/b2Shape.h

@@ -1,101 +1,109 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_SHAPE_H
-#define B2_SHAPE_H
-
-#include <Box2D/Common/b2BlockAllocator.h>
-#include <Box2D/Common/b2Math.h>
-#include <Box2D/Collision/b2Collision.h>
-
-/// This holds the mass data computed for a shape.
-struct b2MassData
-{
-	/// The mass of the shape, usually in kilograms.
-	float32 mass;
-
-	/// The position of the shape's centroid relative to the shape's origin.
-	b2Vec2 center;
-
-	/// The rotational inertia of the shape about the local origin.
-	float32 I;
-};
-
-/// A shape is used for collision detection. You can create a shape however you like.
-/// Shapes used for simulation in b2World are created automatically when a b2Fixture
-/// is created. Shapes may encapsulate a one or more child shapes.
-class b2Shape
-{
-public:
-	
-	enum Type
-	{
-		e_circle = 0,
-		e_edge = 1,
-		e_polygon = 2,
-		e_chain = 3,
-		e_typeCount = 4
-	};
-
-	virtual ~b2Shape() {}
-
-	/// Clone the concrete shape using the provided allocator.
-	virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
-
-	/// Get the type of this shape. You can use this to down cast to the concrete shape.
-	/// @return the shape type.
-	Type GetType() const;
-
-	/// Get the number of child primitives.
-	virtual int32 GetChildCount() const = 0;
-
-	/// Test a point for containment in this shape. This only works for convex shapes.
-	/// @param xf the shape world transform.
-	/// @param p a point in world coordinates.
-	virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0;
-
-	/// Cast a ray against a child shape.
-	/// @param output the ray-cast results.
-	/// @param input the ray-cast input parameters.
-	/// @param transform the transform to be applied to the shape.
-	/// @param childIndex the child shape index
-	virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
-						const b2Transform& transform, int32 childIndex) const = 0;
-
-	/// Given a transform, compute the associated axis aligned bounding box for a child shape.
-	/// @param aabb returns the axis aligned box.
-	/// @param xf the world transform of the shape.
-	/// @param childIndex the child shape
-	virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const = 0;
-
-	/// Compute the mass properties of this shape using its dimensions and density.
-	/// The inertia tensor is computed about the local origin.
-	/// @param massData returns the mass data for this shape.
-	/// @param density the density in kilograms per meter squared.
-	virtual void ComputeMass(b2MassData* massData, float32 density) const = 0;
-
-	Type m_type;
-	float32 m_radius;
-};
-
-inline b2Shape::Type b2Shape::GetType() const
-{
-	return m_type;
-}
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_SHAPE_H
+#define B2_SHAPE_H
+
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Common/b2Math.h>
+#include <Box2D/Collision/b2Collision.h>
+
+/// This holds the mass data computed for a shape.
+struct b2MassData
+{
+	/// The mass of the shape, usually in kilograms.
+	float32 mass;
+
+	/// The position of the shape's centroid relative to the shape's origin.
+	b2Vec2 center;
+
+	/// The rotational inertia of the shape about the local origin.
+	float32 I;
+};
+
+/// A shape is used for collision detection. You can create a shape however you like.
+/// Shapes used for simulation in b2World are created automatically when a b2Fixture
+/// is created. Shapes may encapsulate a one or more child shapes.
+class b2Shape
+{
+public:
+	
+	enum Type
+	{
+		e_circle = 0,
+		e_edge = 1,
+		e_polygon = 2,
+		e_chain = 3,
+		e_typeCount = 4
+	};
+
+	virtual ~b2Shape() {}
+
+	/// Clone the concrete shape using the provided allocator.
+	virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
+
+	/// Get the type of this shape. You can use this to down cast to the concrete shape.
+	/// @return the shape type.
+	Type GetType() const;
+
+	/// Get the number of child primitives.
+	virtual int32 GetChildCount() const = 0;
+
+	/// Test a point for containment in this shape. This only works for convex shapes.
+	/// @param xf the shape world transform.
+	/// @param p a point in world coordinates.
+	virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0;
+
+	/// Compute the distance from the current shape to the specified point. This only works for convex shapes.
+	/// @param xf the shape world transform.
+	/// @param p a point in world coordinates.
+	/// @param distance returns the distance from the current shape.
+	/// @param normal returns the direction in which the distance increases.
+	virtual void ComputeDistance(const b2Transform& xf, const b2Vec2& p, float32* distance, b2Vec2* normal, int32 childIndex) const= 0;
+
+	/// Cast a ray against a child shape.
+	/// @param output the ray-cast results.
+	/// @param input the ray-cast input parameters.
+	/// @param transform the transform to be applied to the shape.
+	/// @param childIndex the child shape index
+	virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input,
+						const b2Transform& transform, int32 childIndex) const = 0;
+
+	/// Given a transform, compute the associated axis aligned bounding box for a child shape.
+	/// @param aabb returns the axis aligned box.
+	/// @param xf the world transform of the shape.
+	/// @param childIndex the child shape
+	virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf, int32 childIndex) const = 0;
+
+	/// Compute the mass properties of this shape using its dimensions and density.
+	/// The inertia tensor is computed about the local origin.
+	/// @param massData returns the mass data for this shape.
+	/// @param density the density in kilograms per meter squared.
+	virtual void ComputeMass(b2MassData* massData, float32 density) const = 0;
+
+	Type m_type;
+	float32 m_radius;
+};
+
+inline b2Shape::Type b2Shape::GetType() const
+{
+	return m_type;
+}
+
+#endif

+ 119 - 121
engine/source/Box2D/Collision/b2BroadPhase.cpp

@@ -1,121 +1,119 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2BroadPhase.h>
-#include <cstring>
-using namespace std;
-
-b2BroadPhase::b2BroadPhase()
-{
-	m_proxyCount = 0;
-
-	m_pairCapacity = 16;
-	m_pairCount = 0;
-	m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));
-
-	m_moveCapacity = 16;
-	m_moveCount = 0;
-	m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));
-}
-
-b2BroadPhase::~b2BroadPhase()
-{
-	b2Free(m_moveBuffer);
-	b2Free(m_pairBuffer);
-}
-
-int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData)
-{
-	int32 proxyId = m_tree.CreateProxy(aabb, userData);
-	++m_proxyCount;
-	BufferMove(proxyId);
-	return proxyId;
-}
-
-void b2BroadPhase::DestroyProxy(int32 proxyId)
-{
-	UnBufferMove(proxyId);
-	--m_proxyCount;
-	m_tree.DestroyProxy(proxyId);
-}
-
-void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
-{
-	bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement);
-	if (buffer)
-	{
-		BufferMove(proxyId);
-	}
-}
-
-void b2BroadPhase::TouchProxy(int32 proxyId)
-{
-	BufferMove(proxyId);
-}
-
-void b2BroadPhase::BufferMove(int32 proxyId)
-{
-	if (m_moveCount == m_moveCapacity)
-	{
-		int32* oldBuffer = m_moveBuffer;
-		m_moveCapacity *= 2;
-		m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));
-		memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32));
-		b2Free(oldBuffer);
-	}
-
-	m_moveBuffer[m_moveCount] = proxyId;
-	++m_moveCount;
-}
-
-void b2BroadPhase::UnBufferMove(int32 proxyId)
-{
-	for (int32 i = 0; i < m_moveCount; ++i)
-	{
-		if (m_moveBuffer[i] == proxyId)
-		{
-			m_moveBuffer[i] = e_nullProxy;
-		}
-	}
-}
-
-// This is called from b2DynamicTree::Query when we are gathering pairs.
-bool b2BroadPhase::QueryCallback(int32 proxyId)
-{
-	// A proxy cannot form a pair with itself.
-	if (proxyId == m_queryProxyId)
-	{
-		return true;
-	}
-
-	// Grow the pair buffer as needed.
-	if (m_pairCount == m_pairCapacity)
-	{
-		b2Pair* oldBuffer = m_pairBuffer;
-		m_pairCapacity *= 2;
-		m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));
-		memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair));
-		b2Free(oldBuffer);
-	}
-
-	m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId);
-	m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId);
-	++m_pairCount;
-
-	return true;
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2BroadPhase.h>
+
+b2BroadPhase::b2BroadPhase()
+{
+	m_proxyCount = 0;
+
+	m_pairCapacity = 16;
+	m_pairCount = 0;
+	m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));
+
+	m_moveCapacity = 16;
+	m_moveCount = 0;
+	m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));
+}
+
+b2BroadPhase::~b2BroadPhase()
+{
+	b2Free(m_moveBuffer);
+	b2Free(m_pairBuffer);
+}
+
+int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData)
+{
+	int32 proxyId = m_tree.CreateProxy(aabb, userData);
+	++m_proxyCount;
+	BufferMove(proxyId);
+	return proxyId;
+}
+
+void b2BroadPhase::DestroyProxy(int32 proxyId)
+{
+	UnBufferMove(proxyId);
+	--m_proxyCount;
+	m_tree.DestroyProxy(proxyId);
+}
+
+void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
+{
+	bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement);
+	if (buffer)
+	{
+		BufferMove(proxyId);
+	}
+}
+
+void b2BroadPhase::TouchProxy(int32 proxyId)
+{
+	BufferMove(proxyId);
+}
+
+void b2BroadPhase::BufferMove(int32 proxyId)
+{
+	if (m_moveCount == m_moveCapacity)
+	{
+		int32* oldBuffer = m_moveBuffer;
+		m_moveCapacity *= 2;
+		m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));
+		memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32));
+		b2Free(oldBuffer);
+	}
+
+	m_moveBuffer[m_moveCount] = proxyId;
+	++m_moveCount;
+}
+
+void b2BroadPhase::UnBufferMove(int32 proxyId)
+{
+	for (int32 i = 0; i < m_moveCount; ++i)
+	{
+		if (m_moveBuffer[i] == proxyId)
+		{
+			m_moveBuffer[i] = e_nullProxy;
+		}
+	}
+}
+
+// This is called from b2DynamicTree::Query when we are gathering pairs.
+bool b2BroadPhase::QueryCallback(int32 proxyId)
+{
+	// A proxy cannot form a pair with itself.
+	if (proxyId == m_queryProxyId)
+	{
+		return true;
+	}
+
+	// Grow the pair buffer as needed.
+	if (m_pairCount == m_pairCapacity)
+	{
+		b2Pair* oldBuffer = m_pairBuffer;
+		m_pairCapacity *= 2;
+		m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));
+		memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair));
+		b2Free(oldBuffer);
+	}
+
+	m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId);
+	m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId);
+	++m_pairCount;
+
+	return true;
+}

+ 257 - 257
engine/source/Box2D/Collision/b2BroadPhase.h

@@ -1,257 +1,257 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_BROAD_PHASE_H
-#define B2_BROAD_PHASE_H
-
-#include <Box2D/Common/b2Settings.h>
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Collision/b2DynamicTree.h>
-#include <algorithm>
-
-struct b2Pair
-{
-	int32 proxyIdA;
-	int32 proxyIdB;
-};
-
-/// The broad-phase is used for computing pairs and performing volume queries and ray casts.
-/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
-/// It is up to the client to consume the new pairs and to track subsequent overlap.
-class b2BroadPhase
-{
-public:
-
-	enum
-	{
-		e_nullProxy = -1
-	};
-
-	b2BroadPhase();
-	~b2BroadPhase();
-
-	/// Create a proxy with an initial AABB. Pairs are not reported until
-	/// UpdatePairs is called.
-	int32 CreateProxy(const b2AABB& aabb, void* userData);
-
-	/// Destroy a proxy. It is up to the client to remove any pairs.
-	void DestroyProxy(int32 proxyId);
-
-	/// Call MoveProxy as many times as you like, then when you are done
-	/// call UpdatePairs to finalized the proxy pairs (for your time step).
-	void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);
-
-	/// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
-	void TouchProxy(int32 proxyId);
-
-	/// Get the fat AABB for a proxy.
-	const b2AABB& GetFatAABB(int32 proxyId) const;
-
-	/// Get user data from a proxy. Returns NULL if the id is invalid.
-	void* GetUserData(int32 proxyId) const;
-
-	/// Test overlap of fat AABBs.
-	bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;
-
-	/// Get the number of proxies.
-	int32 GetProxyCount() const;
-
-	/// Update the pairs. This results in pair callbacks. This can only add pairs.
-	template <typename T>
-	void UpdatePairs(T* callback);
-
-	/// Query an AABB for overlapping proxies. The callback class
-	/// is called for each proxy that overlaps the supplied AABB.
-	template <typename T>
-	void Query(T* callback, const b2AABB& aabb) const;
-
-	/// Ray-cast against the proxies in the tree. This relies on the callback
-	/// to perform a exact ray-cast in the case were the proxy contains a shape.
-	/// The callback also performs the any collision filtering. This has performance
-	/// roughly equal to k * log(n), where k is the number of collisions and n is the
-	/// number of proxies in the tree.
-	/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
-	/// @param callback a callback class that is called for each proxy that is hit by the ray.
-	template <typename T>
-	void RayCast(T* callback, const b2RayCastInput& input) const;
-
-	/// Get the height of the embedded tree.
-	int32 GetTreeHeight() const;
-
-	/// Get the balance of the embedded tree.
-	int32 GetTreeBalance() const;
-
-	/// Get the quality metric of the embedded tree.
-	float32 GetTreeQuality() const;
-
-	/// Shift the world origin. Useful for large worlds.
-	/// The shift formula is: position -= newOrigin
-	/// @param newOrigin the new origin with respect to the old origin
-	void ShiftOrigin(const b2Vec2& newOrigin);
-
-private:
-
-	friend class b2DynamicTree;
-
-	void BufferMove(int32 proxyId);
-	void UnBufferMove(int32 proxyId);
-
-	bool QueryCallback(int32 proxyId);
-
-	b2DynamicTree m_tree;
-
-	int32 m_proxyCount;
-
-	int32* m_moveBuffer;
-	int32 m_moveCapacity;
-	int32 m_moveCount;
-
-	b2Pair* m_pairBuffer;
-	int32 m_pairCapacity;
-	int32 m_pairCount;
-
-	int32 m_queryProxyId;
-};
-
-/// This is used to sort pairs.
-inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)
-{
-	if (pair1.proxyIdA < pair2.proxyIdA)
-	{
-		return true;
-	}
-
-	if (pair1.proxyIdA == pair2.proxyIdA)
-	{
-		return pair1.proxyIdB < pair2.proxyIdB;
-	}
-
-	return false;
-}
-
-inline void* b2BroadPhase::GetUserData(int32 proxyId) const
-{
-	return m_tree.GetUserData(proxyId);
-}
-
-inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const
-{
-	const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);
-	const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);
-	return b2TestOverlap(aabbA, aabbB);
-}
-
-inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const
-{
-	return m_tree.GetFatAABB(proxyId);
-}
-
-inline int32 b2BroadPhase::GetProxyCount() const
-{
-	return m_proxyCount;
-}
-
-inline int32 b2BroadPhase::GetTreeHeight() const
-{
-	return m_tree.GetHeight();
-}
-
-inline int32 b2BroadPhase::GetTreeBalance() const
-{
-	return m_tree.GetMaxBalance();
-}
-
-inline float32 b2BroadPhase::GetTreeQuality() const
-{
-	return m_tree.GetAreaRatio();
-}
-
-template <typename T>
-void b2BroadPhase::UpdatePairs(T* callback)
-{
-	// Reset pair buffer
-	m_pairCount = 0;
-
-	// Perform tree queries for all moving proxies.
-	for (int32 i = 0; i < m_moveCount; ++i)
-	{
-		m_queryProxyId = m_moveBuffer[i];
-		if (m_queryProxyId == e_nullProxy)
-		{
-			continue;
-		}
-
-		// We have to query the tree with the fat AABB so that
-		// we don't fail to create a pair that may touch later.
-		const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
-
-		// Query tree, create pairs and add them pair buffer.
-		m_tree.Query(this, fatAABB);
-	}
-
-	// Reset move buffer
-	m_moveCount = 0;
-
-	// Sort the pair buffer to expose duplicates.
-	std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
-
-	// Send the pairs back to the client.
-	int32 i = 0;
-	while (i < m_pairCount)
-	{
-		b2Pair* primaryPair = m_pairBuffer + i;
-		void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);
-		void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);
-
-		callback->AddPair(userDataA, userDataB);
-		++i;
-
-		// Skip any duplicate pairs.
-		while (i < m_pairCount)
-		{
-			b2Pair* pair = m_pairBuffer + i;
-			if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)
-			{
-				break;
-			}
-			++i;
-		}
-	}
-
-	// Try to keep the tree balanced.
-	//m_tree.Rebalance(4);
-}
-
-template <typename T>
-inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const
-{
-	m_tree.Query(callback, aabb);
-}
-
-template <typename T>
-inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const
-{
-	m_tree.RayCast(callback, input);
-}
-
-inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin)
-{
-	m_tree.ShiftOrigin(newOrigin);
-}
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_BROAD_PHASE_H
+#define B2_BROAD_PHASE_H
+
+#include <Box2D/Common/b2Settings.h>
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2DynamicTree.h>
+#include <algorithm>
+
+struct b2Pair
+{
+	int32 proxyIdA;
+	int32 proxyIdB;
+};
+
+/// The broad-phase is used for computing pairs and performing volume queries and ray casts.
+/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
+/// It is up to the client to consume the new pairs and to track subsequent overlap.
+class b2BroadPhase
+{
+public:
+
+	enum
+	{
+		e_nullProxy = -1
+	};
+
+	b2BroadPhase();
+	~b2BroadPhase();
+
+	/// Create a proxy with an initial AABB. Pairs are not reported until
+	/// UpdatePairs is called.
+	int32 CreateProxy(const b2AABB& aabb, void* userData);
+
+	/// Destroy a proxy. It is up to the client to remove any pairs.
+	void DestroyProxy(int32 proxyId);
+
+	/// Call MoveProxy as many times as you like, then when you are done
+	/// call UpdatePairs to finalized the proxy pairs (for your time step).
+	void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);
+
+	/// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
+	void TouchProxy(int32 proxyId);
+
+	/// Get the fat AABB for a proxy.
+	const b2AABB& GetFatAABB(int32 proxyId) const;
+
+	/// Get user data from a proxy. Returns NULL if the id is invalid.
+	void* GetUserData(int32 proxyId) const;
+
+	/// Test overlap of fat AABBs.
+	bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;
+
+	/// Get the number of proxies.
+	int32 GetProxyCount() const;
+
+	/// Update the pairs. This results in pair callbacks. This can only add pairs.
+	template <typename T>
+	void UpdatePairs(T* callback);
+
+	/// Query an AABB for overlapping proxies. The callback class
+	/// is called for each proxy that overlaps the supplied AABB.
+	template <typename T>
+	void Query(T* callback, const b2AABB& aabb) const;
+
+	/// Ray-cast against the proxies in the tree. This relies on the callback
+	/// to perform a exact ray-cast in the case were the proxy contains a shape.
+	/// The callback also performs the any collision filtering. This has performance
+	/// roughly equal to k * log(n), where k is the number of collisions and n is the
+	/// number of proxies in the tree.
+	/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
+	/// @param callback a callback class that is called for each proxy that is hit by the ray.
+	template <typename T>
+	void RayCast(T* callback, const b2RayCastInput& input) const;
+
+	/// Get the height of the embedded tree.
+	int32 GetTreeHeight() const;
+
+	/// Get the balance of the embedded tree.
+	int32 GetTreeBalance() const;
+
+	/// Get the quality metric of the embedded tree.
+	float32 GetTreeQuality() const;
+
+	/// Shift the world origin. Useful for large worlds.
+	/// The shift formula is: position -= newOrigin
+	/// @param newOrigin the new origin with respect to the old origin
+	void ShiftOrigin(const b2Vec2& newOrigin);
+
+private:
+
+	friend class b2DynamicTree;
+
+	void BufferMove(int32 proxyId);
+	void UnBufferMove(int32 proxyId);
+
+	bool QueryCallback(int32 proxyId);
+
+	b2DynamicTree m_tree;
+
+	int32 m_proxyCount;
+
+	int32* m_moveBuffer;
+	int32 m_moveCapacity;
+	int32 m_moveCount;
+
+	b2Pair* m_pairBuffer;
+	int32 m_pairCapacity;
+	int32 m_pairCount;
+
+	int32 m_queryProxyId;
+};
+
+/// This is used to sort pairs.
+inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)
+{
+	if (pair1.proxyIdA < pair2.proxyIdA)
+	{
+		return true;
+	}
+
+	if (pair1.proxyIdA == pair2.proxyIdA)
+	{
+		return pair1.proxyIdB < pair2.proxyIdB;
+	}
+
+	return false;
+}
+
+inline void* b2BroadPhase::GetUserData(int32 proxyId) const
+{
+	return m_tree.GetUserData(proxyId);
+}
+
+inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const
+{
+	const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);
+	const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);
+	return b2TestOverlap(aabbA, aabbB);
+}
+
+inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const
+{
+	return m_tree.GetFatAABB(proxyId);
+}
+
+inline int32 b2BroadPhase::GetProxyCount() const
+{
+	return m_proxyCount;
+}
+
+inline int32 b2BroadPhase::GetTreeHeight() const
+{
+	return m_tree.GetHeight();
+}
+
+inline int32 b2BroadPhase::GetTreeBalance() const
+{
+	return m_tree.GetMaxBalance();
+}
+
+inline float32 b2BroadPhase::GetTreeQuality() const
+{
+	return m_tree.GetAreaRatio();
+}
+
+template <typename T>
+void b2BroadPhase::UpdatePairs(T* callback)
+{
+	// Reset pair buffer
+	m_pairCount = 0;
+
+	// Perform tree queries for all moving proxies.
+	for (int32 i = 0; i < m_moveCount; ++i)
+	{
+		m_queryProxyId = m_moveBuffer[i];
+		if (m_queryProxyId == e_nullProxy)
+		{
+			continue;
+		}
+
+		// We have to query the tree with the fat AABB so that
+		// we don't fail to create a pair that may touch later.
+		const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
+
+		// Query tree, create pairs and add them pair buffer.
+		m_tree.Query(this, fatAABB);
+	}
+
+	// Reset move buffer
+	m_moveCount = 0;
+
+	// Sort the pair buffer to expose duplicates.
+	std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
+
+	// Send the pairs back to the client.
+	int32 i = 0;
+	while (i < m_pairCount)
+	{
+		b2Pair* primaryPair = m_pairBuffer + i;
+		void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);
+		void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);
+
+		callback->AddPair(userDataA, userDataB);
+		++i;
+
+		// Skip any duplicate pairs.
+		while (i < m_pairCount)
+		{
+			b2Pair* pair = m_pairBuffer + i;
+			if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)
+			{
+				break;
+			}
+			++i;
+		}
+	}
+
+	// Try to keep the tree balanced.
+	//m_tree.Rebalance(4);
+}
+
+template <typename T>
+inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const
+{
+	m_tree.Query(callback, aabb);
+}
+
+template <typename T>
+inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const
+{
+	m_tree.RayCast(callback, input);
+}
+
+inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin)
+{
+	m_tree.ShiftOrigin(newOrigin);
+}
+
+#endif

+ 154 - 154
engine/source/Box2D/Collision/b2CollideCircle.cpp

@@ -1,154 +1,154 @@
-/*
-* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Collision/Shapes/b2CircleShape.h>
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-
-void b2CollideCircles(
-	b2Manifold* manifold,
-	const b2CircleShape* circleA, const b2Transform& xfA,
-	const b2CircleShape* circleB, const b2Transform& xfB)
-{
-	manifold->pointCount = 0;
-
-	b2Vec2 pA = b2Mul(xfA, circleA->m_p);
-	b2Vec2 pB = b2Mul(xfB, circleB->m_p);
-
-	b2Vec2 d = pB - pA;
-	float32 distSqr = b2Dot(d, d);
-	float32 rA = circleA->m_radius, rB = circleB->m_radius;
-	float32 radius = rA + rB;
-	if (distSqr > radius * radius)
-	{
-		return;
-	}
-
-	manifold->type = b2Manifold::e_circles;
-	manifold->localPoint = circleA->m_p;
-	manifold->localNormal.SetZero();
-	manifold->pointCount = 1;
-
-	manifold->points[0].localPoint = circleB->m_p;
-	manifold->points[0].id.key = 0;
-}
-
-void b2CollidePolygonAndCircle(
-	b2Manifold* manifold,
-	const b2PolygonShape* polygonA, const b2Transform& xfA,
-	const b2CircleShape* circleB, const b2Transform& xfB)
-{
-	manifold->pointCount = 0;
-
-	// Compute circle position in the frame of the polygon.
-	b2Vec2 c = b2Mul(xfB, circleB->m_p);
-	b2Vec2 cLocal = b2MulT(xfA, c);
-
-	// Find the min separating edge.
-	int32 normalIndex = 0;
-	float32 separation = -b2_maxFloat;
-	float32 radius = polygonA->m_radius + circleB->m_radius;
-	int32 vertexCount = polygonA->m_count;
-	const b2Vec2* vertices = polygonA->m_vertices;
-	const b2Vec2* normals = polygonA->m_normals;
-
-	for (int32 i = 0; i < vertexCount; ++i)
-	{
-		float32 s = b2Dot(normals[i], cLocal - vertices[i]);
-
-		if (s > radius)
-		{
-			// Early out.
-			return;
-		}
-
-		if (s > separation)
-		{
-			separation = s;
-			normalIndex = i;
-		}
-	}
-
-	// Vertices that subtend the incident face.
-	int32 vertIndex1 = normalIndex;
-	int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
-	b2Vec2 v1 = vertices[vertIndex1];
-	b2Vec2 v2 = vertices[vertIndex2];
-
-	// If the center is inside the polygon ...
-	if (separation < b2_epsilon)
-	{
-		manifold->pointCount = 1;
-		manifold->type = b2Manifold::e_faceA;
-		manifold->localNormal = normals[normalIndex];
-		manifold->localPoint = 0.5f * (v1 + v2);
-		manifold->points[0].localPoint = circleB->m_p;
-		manifold->points[0].id.key = 0;
-		return;
-	}
-
-	// Compute barycentric coordinates
-	float32 u1 = b2Dot(cLocal - v1, v2 - v1);
-	float32 u2 = b2Dot(cLocal - v2, v1 - v2);
-	if (u1 <= 0.0f)
-	{
-		if (b2DistanceSquared(cLocal, v1) > radius * radius)
-		{
-			return;
-		}
-
-		manifold->pointCount = 1;
-		manifold->type = b2Manifold::e_faceA;
-		manifold->localNormal = cLocal - v1;
-		manifold->localNormal.Normalize();
-		manifold->localPoint = v1;
-		manifold->points[0].localPoint = circleB->m_p;
-		manifold->points[0].id.key = 0;
-	}
-	else if (u2 <= 0.0f)
-	{
-		if (b2DistanceSquared(cLocal, v2) > radius * radius)
-		{
-			return;
-		}
-
-		manifold->pointCount = 1;
-		manifold->type = b2Manifold::e_faceA;
-		manifold->localNormal = cLocal - v2;
-		manifold->localNormal.Normalize();
-		manifold->localPoint = v2;
-		manifold->points[0].localPoint = circleB->m_p;
-		manifold->points[0].id.key = 0;
-	}
-	else
-	{
-		b2Vec2 faceCenter = 0.5f * (v1 + v2);
-		float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]);
-		if (separation > radius)
-		{
-			return;
-		}
-
-		manifold->pointCount = 1;
-		manifold->type = b2Manifold::e_faceA;
-		manifold->localNormal = normals[vertIndex1];
-		manifold->localPoint = faceCenter;
-		manifold->points[0].localPoint = circleB->m_p;
-		manifold->points[0].id.key = 0;
-	}
-}
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+void b2CollideCircles(
+	b2Manifold* manifold,
+	const b2CircleShape* circleA, const b2Transform& xfA,
+	const b2CircleShape* circleB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+
+	b2Vec2 pA = b2Mul(xfA, circleA->m_p);
+	b2Vec2 pB = b2Mul(xfB, circleB->m_p);
+
+	b2Vec2 d = pB - pA;
+	float32 distSqr = b2Dot(d, d);
+	float32 rA = circleA->m_radius, rB = circleB->m_radius;
+	float32 radius = rA + rB;
+	if (distSqr > radius * radius)
+	{
+		return;
+	}
+
+	manifold->type = b2Manifold::e_circles;
+	manifold->localPoint = circleA->m_p;
+	manifold->localNormal.SetZero();
+	manifold->pointCount = 1;
+
+	manifold->points[0].localPoint = circleB->m_p;
+	manifold->points[0].id.key = 0;
+}
+
+void b2CollidePolygonAndCircle(
+	b2Manifold* manifold,
+	const b2PolygonShape* polygonA, const b2Transform& xfA,
+	const b2CircleShape* circleB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+
+	// Compute circle position in the frame of the polygon.
+	b2Vec2 c = b2Mul(xfB, circleB->m_p);
+	b2Vec2 cLocal = b2MulT(xfA, c);
+
+	// Find the min separating edge.
+	int32 normalIndex = 0;
+	float32 separation = -b2_maxFloat;
+	float32 radius = polygonA->m_radius + circleB->m_radius;
+	int32 vertexCount = polygonA->m_count;
+	const b2Vec2* vertices = polygonA->m_vertices;
+	const b2Vec2* normals = polygonA->m_normals;
+
+	for (int32 i = 0; i < vertexCount; ++i)
+	{
+		float32 s = b2Dot(normals[i], cLocal - vertices[i]);
+
+		if (s > radius)
+		{
+			// Early out.
+			return;
+		}
+
+		if (s > separation)
+		{
+			separation = s;
+			normalIndex = i;
+		}
+	}
+
+	// Vertices that subtend the incident face.
+	int32 vertIndex1 = normalIndex;
+	int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
+	b2Vec2 v1 = vertices[vertIndex1];
+	b2Vec2 v2 = vertices[vertIndex2];
+
+	// If the center is inside the polygon ...
+	if (separation < b2_epsilon)
+	{
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = normals[normalIndex];
+		manifold->localPoint = 0.5f * (v1 + v2);
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+		return;
+	}
+
+	// Compute barycentric coordinates
+	float32 u1 = b2Dot(cLocal - v1, v2 - v1);
+	float32 u2 = b2Dot(cLocal - v2, v1 - v2);
+	if (u1 <= 0.0f)
+	{
+		if (b2DistanceSquared(cLocal, v1) > radius * radius)
+		{
+			return;
+		}
+
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = cLocal - v1;
+		manifold->localNormal.Normalize();
+		manifold->localPoint = v1;
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+	}
+	else if (u2 <= 0.0f)
+	{
+		if (b2DistanceSquared(cLocal, v2) > radius * radius)
+		{
+			return;
+		}
+
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = cLocal - v2;
+		manifold->localNormal.Normalize();
+		manifold->localPoint = v2;
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+	}
+	else
+	{
+		b2Vec2 faceCenter = 0.5f * (v1 + v2);
+		float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]);
+		if (separation > radius)
+		{
+			return;
+		}
+
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_faceA;
+		manifold->localNormal = normals[vertIndex1];
+		manifold->localPoint = faceCenter;
+		manifold->points[0].localPoint = circleB->m_p;
+		manifold->points[0].id.key = 0;
+	}
+}

+ 698 - 698
engine/source/Box2D/Collision/b2CollideEdge.cpp

@@ -1,698 +1,698 @@
-/*
- * Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
- *
- * This software is provided 'as-is', without any express or implied
- * warranty.  In no event will the authors be held liable for any damages
- * arising from the use of this software.
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
-
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Collision/Shapes/b2CircleShape.h>
-#include <Box2D/Collision/Shapes/b2EdgeShape.h>
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-
-
-// Compute contact points for edge versus circle.
-// This accounts for edge connectivity.
-void b2CollideEdgeAndCircle(b2Manifold* manifold,
-							const b2EdgeShape* edgeA, const b2Transform& xfA,
-							const b2CircleShape* circleB, const b2Transform& xfB)
-{
-	manifold->pointCount = 0;
-	
-	// Compute circle in frame of edge
-	b2Vec2 Q = b2MulT(xfA, b2Mul(xfB, circleB->m_p));
-	
-	b2Vec2 A = edgeA->m_vertex1, B = edgeA->m_vertex2;
-	b2Vec2 e = B - A;
-	
-	// Barycentric coordinates
-	float32 u = b2Dot(e, B - Q);
-	float32 v = b2Dot(e, Q - A);
-	
-	float32 radius = edgeA->m_radius + circleB->m_radius;
-	
-	b2ContactFeature cf;
-	cf.indexB = 0;
-	cf.typeB = b2ContactFeature::e_vertex;
-	
-	// Region A
-	if (v <= 0.0f)
-	{
-		b2Vec2 P = A;
-		b2Vec2 d = Q - P;
-		float32 dd = b2Dot(d, d);
-		if (dd > radius * radius)
-		{
-			return;
-		}
-		
-		// Is there an edge connected to A?
-		if (edgeA->m_hasVertex0)
-		{
-			b2Vec2 A1 = edgeA->m_vertex0;
-			b2Vec2 B1 = A;
-			b2Vec2 e1 = B1 - A1;
-			float32 u1 = b2Dot(e1, B1 - Q);
-			
-			// Is the circle in Region AB of the previous edge?
-			if (u1 > 0.0f)
-			{
-				return;
-			}
-		}
-		
-		cf.indexA = 0;
-		cf.typeA = b2ContactFeature::e_vertex;
-		manifold->pointCount = 1;
-		manifold->type = b2Manifold::e_circles;
-		manifold->localNormal.SetZero();
-		manifold->localPoint = P;
-		manifold->points[0].id.key = 0;
-		manifold->points[0].id.cf = cf;
-		manifold->points[0].localPoint = circleB->m_p;
-		return;
-	}
-	
-	// Region B
-	if (u <= 0.0f)
-	{
-		b2Vec2 P = B;
-		b2Vec2 d = Q - P;
-		float32 dd = b2Dot(d, d);
-		if (dd > radius * radius)
-		{
-			return;
-		}
-		
-		// Is there an edge connected to B?
-		if (edgeA->m_hasVertex3)
-		{
-			b2Vec2 B2 = edgeA->m_vertex3;
-			b2Vec2 A2 = B;
-			b2Vec2 e2 = B2 - A2;
-			float32 v2 = b2Dot(e2, Q - A2);
-			
-			// Is the circle in Region AB of the next edge?
-			if (v2 > 0.0f)
-			{
-				return;
-			}
-		}
-		
-		cf.indexA = 1;
-		cf.typeA = b2ContactFeature::e_vertex;
-		manifold->pointCount = 1;
-		manifold->type = b2Manifold::e_circles;
-		manifold->localNormal.SetZero();
-		manifold->localPoint = P;
-		manifold->points[0].id.key = 0;
-		manifold->points[0].id.cf = cf;
-		manifold->points[0].localPoint = circleB->m_p;
-		return;
-	}
-	
-	// Region AB
-	float32 den = b2Dot(e, e);
-	b2Assert(den > 0.0f);
-	b2Vec2 P = (1.0f / den) * (u * A + v * B);
-	b2Vec2 d = Q - P;
-	float32 dd = b2Dot(d, d);
-	if (dd > radius * radius)
-	{
-		return;
-	}
-	
-	b2Vec2 n(-e.y, e.x);
-	if (b2Dot(n, Q - A) < 0.0f)
-	{
-		n.Set(-n.x, -n.y);
-	}
-	n.Normalize();
-	
-	cf.indexA = 0;
-	cf.typeA = b2ContactFeature::e_face;
-	manifold->pointCount = 1;
-	manifold->type = b2Manifold::e_faceA;
-	manifold->localNormal = n;
-	manifold->localPoint = A;
-	manifold->points[0].id.key = 0;
-	manifold->points[0].id.cf = cf;
-	manifold->points[0].localPoint = circleB->m_p;
-}
-
-// This structure is used to keep track of the best separating axis.
-struct b2EPAxis
-{
-	enum Type
-	{
-		e_unknown,
-		e_edgeA,
-		e_edgeB
-	};
-	
-	Type type;
-	int32 index;
-	float32 separation;
-};
-
-// This holds polygon B expressed in frame A.
-struct b2TempPolygon
-{
-	b2Vec2 vertices[b2_maxPolygonVertices];
-	b2Vec2 normals[b2_maxPolygonVertices];
-	int32 count;
-};
-
-// Reference face used for clipping
-struct b2ReferenceFace
-{
-	int32 i1, i2;
-	
-	b2Vec2 v1, v2;
-	
-	b2Vec2 normal;
-	
-	b2Vec2 sideNormal1;
-	float32 sideOffset1;
-	
-	b2Vec2 sideNormal2;
-	float32 sideOffset2;
-};
-
-// This class collides and edge and a polygon, taking into account edge adjacency.
-struct b2EPCollider
-{
-	void Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
-				 const b2PolygonShape* polygonB, const b2Transform& xfB);
-	b2EPAxis ComputeEdgeSeparation();
-	b2EPAxis ComputePolygonSeparation();
-	
-	enum VertexType
-	{
-		e_isolated,
-		e_concave,
-		e_convex
-	};
-	
-	b2TempPolygon m_polygonB;
-	
-	b2Transform m_xf;
-	b2Vec2 m_centroidB;
-	b2Vec2 m_v0, m_v1, m_v2, m_v3;
-	b2Vec2 m_normal0, m_normal1, m_normal2;
-	b2Vec2 m_normal;
-	VertexType m_type1, m_type2;
-	b2Vec2 m_lowerLimit, m_upperLimit;
-	float32 m_radius;
-	bool m_front;
-};
-
-// Algorithm:
-// 1. Classify v1 and v2
-// 2. Classify polygon centroid as front or back
-// 3. Flip normal if necessary
-// 4. Initialize normal range to [-pi, pi] about face normal
-// 5. Adjust normal range according to adjacent edges
-// 6. Visit each separating axes, only accept axes within the range
-// 7. Return if _any_ axis indicates separation
-// 8. Clip
-void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
-						   const b2PolygonShape* polygonB, const b2Transform& xfB)
-{
-	m_xf = b2MulT(xfA, xfB);
-	
-	m_centroidB = b2Mul(m_xf, polygonB->m_centroid);
-	
-	m_v0 = edgeA->m_vertex0;
-	m_v1 = edgeA->m_vertex1;
-	m_v2 = edgeA->m_vertex2;
-	m_v3 = edgeA->m_vertex3;
-	
-	bool hasVertex0 = edgeA->m_hasVertex0;
-	bool hasVertex3 = edgeA->m_hasVertex3;
-	
-	b2Vec2 edge1 = m_v2 - m_v1;
-	edge1.Normalize();
-	m_normal1.Set(edge1.y, -edge1.x);
-	float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1);
-	float32 offset0 = 0.0f, offset2 = 0.0f;
-	bool convex1 = false, convex2 = false;
-	
-	// Is there a preceding edge?
-	if (hasVertex0)
-	{
-		b2Vec2 edge0 = m_v1 - m_v0;
-		edge0.Normalize();
-		m_normal0.Set(edge0.y, -edge0.x);
-		convex1 = b2Cross(edge0, edge1) >= 0.0f;
-		offset0 = b2Dot(m_normal0, m_centroidB - m_v0);
-	}
-	
-	// Is there a following edge?
-	if (hasVertex3)
-	{
-		b2Vec2 edge2 = m_v3 - m_v2;
-		edge2.Normalize();
-		m_normal2.Set(edge2.y, -edge2.x);
-		convex2 = b2Cross(edge1, edge2) > 0.0f;
-		offset2 = b2Dot(m_normal2, m_centroidB - m_v2);
-	}
-	
-	// Determine front or back collision. Determine collision normal limits.
-	if (hasVertex0 && hasVertex3)
-	{
-		if (convex1 && convex2)
-		{
-			m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = m_normal0;
-				m_upperLimit = m_normal2;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = -m_normal1;
-				m_upperLimit = -m_normal1;
-			}
-		}
-		else if (convex1)
-		{
-			m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = m_normal0;
-				m_upperLimit = m_normal1;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = -m_normal2;
-				m_upperLimit = -m_normal1;
-			}
-		}
-		else if (convex2)
-		{
-			m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = m_normal1;
-				m_upperLimit = m_normal2;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = -m_normal1;
-				m_upperLimit = -m_normal0;
-			}
-		}
-		else
-		{
-			m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = m_normal1;
-				m_upperLimit = m_normal1;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = -m_normal2;
-				m_upperLimit = -m_normal0;
-			}
-		}
-	}
-	else if (hasVertex0)
-	{
-		if (convex1)
-		{
-			m_front = offset0 >= 0.0f || offset1 >= 0.0f;
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = m_normal0;
-				m_upperLimit = -m_normal1;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = m_normal1;
-				m_upperLimit = -m_normal1;
-			}
-		}
-		else
-		{
-			m_front = offset0 >= 0.0f && offset1 >= 0.0f;
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = m_normal1;
-				m_upperLimit = -m_normal1;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = m_normal1;
-				m_upperLimit = -m_normal0;
-			}
-		}
-	}
-	else if (hasVertex3)
-	{
-		if (convex2)
-		{
-			m_front = offset1 >= 0.0f || offset2 >= 0.0f;
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = -m_normal1;
-				m_upperLimit = m_normal2;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = -m_normal1;
-				m_upperLimit = m_normal1;
-			}
-		}
-		else
-		{
-			m_front = offset1 >= 0.0f && offset2 >= 0.0f;
-			if (m_front)
-			{
-				m_normal = m_normal1;
-				m_lowerLimit = -m_normal1;
-				m_upperLimit = m_normal1;
-			}
-			else
-			{
-				m_normal = -m_normal1;
-				m_lowerLimit = -m_normal2;
-				m_upperLimit = m_normal1;
-			}
-		}		
-	}
-	else
-	{
-		m_front = offset1 >= 0.0f;
-		if (m_front)
-		{
-			m_normal = m_normal1;
-			m_lowerLimit = -m_normal1;
-			m_upperLimit = -m_normal1;
-		}
-		else
-		{
-			m_normal = -m_normal1;
-			m_lowerLimit = m_normal1;
-			m_upperLimit = m_normal1;
-		}
-	}
-	
-	// Get polygonB in frameA
-	m_polygonB.count = polygonB->m_count;
-	for (int32 i = 0; i < polygonB->m_count; ++i)
-	{
-		m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]);
-		m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]);
-	}
-	
-	m_radius = 2.0f * b2_polygonRadius;
-	
-	manifold->pointCount = 0;
-	
-	b2EPAxis edgeAxis = ComputeEdgeSeparation();
-	
-	// If no valid normal can be found than this edge should not collide.
-	if (edgeAxis.type == b2EPAxis::e_unknown)
-	{
-		return;
-	}
-	
-	if (edgeAxis.separation > m_radius)
-	{
-		return;
-	}
-	
-	b2EPAxis polygonAxis = ComputePolygonSeparation();
-	if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius)
-	{
-		return;
-	}
-	
-	// Use hysteresis for jitter reduction.
-	const float32 k_relativeTol = 0.98f;
-	const float32 k_absoluteTol = 0.001f;
-	
-	b2EPAxis primaryAxis;
-	if (polygonAxis.type == b2EPAxis::e_unknown)
-	{
-		primaryAxis = edgeAxis;
-	}
-	else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
-	{
-		primaryAxis = polygonAxis;
-	}
-	else
-	{
-		primaryAxis = edgeAxis;
-	}
-	
-	b2ClipVertex ie[2];
-	b2ReferenceFace rf;
-	if (primaryAxis.type == b2EPAxis::e_edgeA)
-	{
-		manifold->type = b2Manifold::e_faceA;
-		
-		// Search for the polygon normal that is most anti-parallel to the edge normal.
-		int32 bestIndex = 0;
-		float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]);
-		for (int32 i = 1; i < m_polygonB.count; ++i)
-		{
-			float32 value = b2Dot(m_normal, m_polygonB.normals[i]);
-			if (value < bestValue)
-			{
-				bestValue = value;
-				bestIndex = i;
-			}
-		}
-		
-		int32 i1 = bestIndex;
-		int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;
-		
-		ie[0].v = m_polygonB.vertices[i1];
-		ie[0].id.cf.indexA = 0;
-		ie[0].id.cf.indexB = i1;
-		ie[0].id.cf.typeA = b2ContactFeature::e_face;
-		ie[0].id.cf.typeB = b2ContactFeature::e_vertex;
-		
-		ie[1].v = m_polygonB.vertices[i2];
-		ie[1].id.cf.indexA = 0;
-		ie[1].id.cf.indexB = i2;
-		ie[1].id.cf.typeA = b2ContactFeature::e_face;
-		ie[1].id.cf.typeB = b2ContactFeature::e_vertex;
-		
-		if (m_front)
-		{
-			rf.i1 = 0;
-			rf.i2 = 1;
-			rf.v1 = m_v1;
-			rf.v2 = m_v2;
-			rf.normal = m_normal1;
-		}
-		else
-		{
-			rf.i1 = 1;
-			rf.i2 = 0;
-			rf.v1 = m_v2;
-			rf.v2 = m_v1;
-			rf.normal = -m_normal1;
-		}		
-	}
-	else
-	{
-		manifold->type = b2Manifold::e_faceB;
-		
-		ie[0].v = m_v1;
-		ie[0].id.cf.indexA = 0;
-		ie[0].id.cf.indexB = primaryAxis.index;
-		ie[0].id.cf.typeA = b2ContactFeature::e_vertex;
-		ie[0].id.cf.typeB = b2ContactFeature::e_face;
-		
-		ie[1].v = m_v2;
-		ie[1].id.cf.indexA = 0;
-		ie[1].id.cf.indexB = primaryAxis.index;		
-		ie[1].id.cf.typeA = b2ContactFeature::e_vertex;
-		ie[1].id.cf.typeB = b2ContactFeature::e_face;
-		
-		rf.i1 = primaryAxis.index;
-		rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
-		rf.v1 = m_polygonB.vertices[rf.i1];
-		rf.v2 = m_polygonB.vertices[rf.i2];
-		rf.normal = m_polygonB.normals[rf.i1];
-	}
-	
-	rf.sideNormal1.Set(rf.normal.y, -rf.normal.x);
-	rf.sideNormal2 = -rf.sideNormal1;
-	rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1);
-	rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2);
-	
-	// Clip incident edge against extruded edge1 side edges.
-	b2ClipVertex clipPoints1[2];
-	b2ClipVertex clipPoints2[2];
-	int32 np;
-	
-	// Clip to box side 1
-	np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);
-	
-	if (np < b2_maxManifoldPoints)
-	{
-		return;
-	}
-	
-	// Clip to negative box side 1
-	np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);
-	
-	if (np < b2_maxManifoldPoints)
-	{
-		return;
-	}
-	
-	// Now clipPoints2 contains the clipped points.
-	if (primaryAxis.type == b2EPAxis::e_edgeA)
-	{
-		manifold->localNormal = rf.normal;
-		manifold->localPoint = rf.v1;
-	}
-	else
-	{
-		manifold->localNormal = polygonB->m_normals[rf.i1];
-		manifold->localPoint = polygonB->m_vertices[rf.i1];
-	}
-	
-	int32 pointCount = 0;
-	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
-	{
-		float32 separation;
-		
-		separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1);
-		
-		if (separation <= m_radius)
-		{
-			b2ManifoldPoint* cp = manifold->points + pointCount;
-			
-			if (primaryAxis.type == b2EPAxis::e_edgeA)
-			{
-				cp->localPoint = b2MulT(m_xf, clipPoints2[i].v);
-				cp->id = clipPoints2[i].id;
-			}
-			else
-			{
-				cp->localPoint = clipPoints2[i].v;
-				cp->id.cf.typeA = clipPoints2[i].id.cf.typeB;
-				cp->id.cf.typeB = clipPoints2[i].id.cf.typeA;
-				cp->id.cf.indexA = clipPoints2[i].id.cf.indexB;
-				cp->id.cf.indexB = clipPoints2[i].id.cf.indexA;
-			}
-			
-			++pointCount;
-		}
-	}
-	
-	manifold->pointCount = pointCount;
-}
-
-b2EPAxis b2EPCollider::ComputeEdgeSeparation()
-{
-	b2EPAxis axis;
-	axis.type = b2EPAxis::e_edgeA;
-	axis.index = m_front ? 0 : 1;
-	axis.separation = FLT_MAX;
-	
-	for (int32 i = 0; i < m_polygonB.count; ++i)
-	{
-		float32 s = b2Dot(m_normal, m_polygonB.vertices[i] - m_v1);
-		if (s < axis.separation)
-		{
-			axis.separation = s;
-		}
-	}
-	
-	return axis;
-}
-
-b2EPAxis b2EPCollider::ComputePolygonSeparation()
-{
-	b2EPAxis axis;
-	axis.type = b2EPAxis::e_unknown;
-	axis.index = -1;
-	axis.separation = -FLT_MAX;
-
-	b2Vec2 perp(-m_normal.y, m_normal.x);
-
-	for (int32 i = 0; i < m_polygonB.count; ++i)
-	{
-		b2Vec2 n = -m_polygonB.normals[i];
-		
-		float32 s1 = b2Dot(n, m_polygonB.vertices[i] - m_v1);
-		float32 s2 = b2Dot(n, m_polygonB.vertices[i] - m_v2);
-		float32 s = b2Min(s1, s2);
-		
-		if (s > m_radius)
-		{
-			// No collision
-			axis.type = b2EPAxis::e_edgeB;
-			axis.index = i;
-			axis.separation = s;
-			return axis;
-		}
-		
-		// Adjacency
-		if (b2Dot(n, perp) >= 0.0f)
-		{
-			if (b2Dot(n - m_upperLimit, m_normal) < -b2_angularSlop)
-			{
-				continue;
-			}
-		}
-		else
-		{
-			if (b2Dot(n - m_lowerLimit, m_normal) < -b2_angularSlop)
-			{
-				continue;
-			}
-		}
-		
-		if (s > axis.separation)
-		{
-			axis.type = b2EPAxis::e_edgeB;
-			axis.index = i;
-			axis.separation = s;
-		}
-	}
-	
-	return axis;
-}
-
-void b2CollideEdgeAndPolygon(	b2Manifold* manifold,
-							 const b2EdgeShape* edgeA, const b2Transform& xfA,
-							 const b2PolygonShape* polygonB, const b2Transform& xfB)
-{
-	b2EPCollider collider;
-	collider.Collide(manifold, edgeA, xfA, polygonB, xfB);
-}
+/*
+ * Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+
+// Compute contact points for edge versus circle.
+// This accounts for edge connectivity.
+void b2CollideEdgeAndCircle(b2Manifold* manifold,
+							const b2EdgeShape* edgeA, const b2Transform& xfA,
+							const b2CircleShape* circleB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+	
+	// Compute circle in frame of edge
+	b2Vec2 Q = b2MulT(xfA, b2Mul(xfB, circleB->m_p));
+	
+	b2Vec2 A = edgeA->m_vertex1, B = edgeA->m_vertex2;
+	b2Vec2 e = B - A;
+	
+	// Barycentric coordinates
+	float32 u = b2Dot(e, B - Q);
+	float32 v = b2Dot(e, Q - A);
+	
+	float32 radius = edgeA->m_radius + circleB->m_radius;
+	
+	b2ContactFeature cf;
+	cf.indexB = 0;
+	cf.typeB = b2ContactFeature::e_vertex;
+	
+	// Region A
+	if (v <= 0.0f)
+	{
+		b2Vec2 P = A;
+		b2Vec2 d = Q - P;
+		float32 dd = b2Dot(d, d);
+		if (dd > radius * radius)
+		{
+			return;
+		}
+		
+		// Is there an edge connected to A?
+		if (edgeA->m_hasVertex0)
+		{
+			b2Vec2 A1 = edgeA->m_vertex0;
+			b2Vec2 B1 = A;
+			b2Vec2 e1 = B1 - A1;
+			float32 u1 = b2Dot(e1, B1 - Q);
+			
+			// Is the circle in Region AB of the previous edge?
+			if (u1 > 0.0f)
+			{
+				return;
+			}
+		}
+		
+		cf.indexA = 0;
+		cf.typeA = b2ContactFeature::e_vertex;
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_circles;
+		manifold->localNormal.SetZero();
+		manifold->localPoint = P;
+		manifold->points[0].id.key = 0;
+		manifold->points[0].id.cf = cf;
+		manifold->points[0].localPoint = circleB->m_p;
+		return;
+	}
+	
+	// Region B
+	if (u <= 0.0f)
+	{
+		b2Vec2 P = B;
+		b2Vec2 d = Q - P;
+		float32 dd = b2Dot(d, d);
+		if (dd > radius * radius)
+		{
+			return;
+		}
+		
+		// Is there an edge connected to B?
+		if (edgeA->m_hasVertex3)
+		{
+			b2Vec2 B2 = edgeA->m_vertex3;
+			b2Vec2 A2 = B;
+			b2Vec2 e2 = B2 - A2;
+			float32 v2 = b2Dot(e2, Q - A2);
+			
+			// Is the circle in Region AB of the next edge?
+			if (v2 > 0.0f)
+			{
+				return;
+			}
+		}
+		
+		cf.indexA = 1;
+		cf.typeA = b2ContactFeature::e_vertex;
+		manifold->pointCount = 1;
+		manifold->type = b2Manifold::e_circles;
+		manifold->localNormal.SetZero();
+		manifold->localPoint = P;
+		manifold->points[0].id.key = 0;
+		manifold->points[0].id.cf = cf;
+		manifold->points[0].localPoint = circleB->m_p;
+		return;
+	}
+	
+	// Region AB
+	float32 den = b2Dot(e, e);
+	b2Assert(den > 0.0f);
+	b2Vec2 P = (1.0f / den) * (u * A + v * B);
+	b2Vec2 d = Q - P;
+	float32 dd = b2Dot(d, d);
+	if (dd > radius * radius)
+	{
+		return;
+	}
+	
+	b2Vec2 n(-e.y, e.x);
+	if (b2Dot(n, Q - A) < 0.0f)
+	{
+		n.Set(-n.x, -n.y);
+	}
+	n.Normalize();
+	
+	cf.indexA = 0;
+	cf.typeA = b2ContactFeature::e_face;
+	manifold->pointCount = 1;
+	manifold->type = b2Manifold::e_faceA;
+	manifold->localNormal = n;
+	manifold->localPoint = A;
+	manifold->points[0].id.key = 0;
+	manifold->points[0].id.cf = cf;
+	manifold->points[0].localPoint = circleB->m_p;
+}
+
+// This structure is used to keep track of the best separating axis.
+struct b2EPAxis
+{
+	enum Type
+	{
+		e_unknown,
+		e_edgeA,
+		e_edgeB
+	};
+	
+	Type type;
+	int32 index;
+	float32 separation;
+};
+
+// This holds polygon B expressed in frame A.
+struct b2TempPolygon
+{
+	b2Vec2 vertices[b2_maxPolygonVertices];
+	b2Vec2 normals[b2_maxPolygonVertices];
+	int32 count;
+};
+
+// Reference face used for clipping
+struct b2ReferenceFace
+{
+	int32 i1, i2;
+	
+	b2Vec2 v1, v2;
+	
+	b2Vec2 normal;
+	
+	b2Vec2 sideNormal1;
+	float32 sideOffset1;
+	
+	b2Vec2 sideNormal2;
+	float32 sideOffset2;
+};
+
+// This class collides and edge and a polygon, taking into account edge adjacency.
+struct b2EPCollider
+{
+	void Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
+				 const b2PolygonShape* polygonB, const b2Transform& xfB);
+	b2EPAxis ComputeEdgeSeparation();
+	b2EPAxis ComputePolygonSeparation();
+	
+	enum VertexType
+	{
+		e_isolated,
+		e_concave,
+		e_convex
+	};
+	
+	b2TempPolygon m_polygonB;
+	
+	b2Transform m_xf;
+	b2Vec2 m_centroidB;
+	b2Vec2 m_v0, m_v1, m_v2, m_v3;
+	b2Vec2 m_normal0, m_normal1, m_normal2;
+	b2Vec2 m_normal;
+	VertexType m_type1, m_type2;
+	b2Vec2 m_lowerLimit, m_upperLimit;
+	float32 m_radius;
+	bool m_front;
+};
+
+// Algorithm:
+// 1. Classify v1 and v2
+// 2. Classify polygon centroid as front or back
+// 3. Flip normal if necessary
+// 4. Initialize normal range to [-pi, pi] about face normal
+// 5. Adjust normal range according to adjacent edges
+// 6. Visit each separating axes, only accept axes within the range
+// 7. Return if _any_ axis indicates separation
+// 8. Clip
+void b2EPCollider::Collide(b2Manifold* manifold, const b2EdgeShape* edgeA, const b2Transform& xfA,
+						   const b2PolygonShape* polygonB, const b2Transform& xfB)
+{
+	m_xf = b2MulT(xfA, xfB);
+	
+	m_centroidB = b2Mul(m_xf, polygonB->m_centroid);
+	
+	m_v0 = edgeA->m_vertex0;
+	m_v1 = edgeA->m_vertex1;
+	m_v2 = edgeA->m_vertex2;
+	m_v3 = edgeA->m_vertex3;
+	
+	bool hasVertex0 = edgeA->m_hasVertex0;
+	bool hasVertex3 = edgeA->m_hasVertex3;
+	
+	b2Vec2 edge1 = m_v2 - m_v1;
+	edge1.Normalize();
+	m_normal1.Set(edge1.y, -edge1.x);
+	float32 offset1 = b2Dot(m_normal1, m_centroidB - m_v1);
+	float32 offset0 = 0.0f, offset2 = 0.0f;
+	bool convex1 = false, convex2 = false;
+	
+	// Is there a preceding edge?
+	if (hasVertex0)
+	{
+		b2Vec2 edge0 = m_v1 - m_v0;
+		edge0.Normalize();
+		m_normal0.Set(edge0.y, -edge0.x);
+		convex1 = b2Cross(edge0, edge1) >= 0.0f;
+		offset0 = b2Dot(m_normal0, m_centroidB - m_v0);
+	}
+	
+	// Is there a following edge?
+	if (hasVertex3)
+	{
+		b2Vec2 edge2 = m_v3 - m_v2;
+		edge2.Normalize();
+		m_normal2.Set(edge2.y, -edge2.x);
+		convex2 = b2Cross(edge1, edge2) > 0.0f;
+		offset2 = b2Dot(m_normal2, m_centroidB - m_v2);
+	}
+	
+	// Determine front or back collision. Determine collision normal limits.
+	if (hasVertex0 && hasVertex3)
+	{
+		if (convex1 && convex2)
+		{
+			m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal0;
+				m_upperLimit = m_normal2;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = -m_normal1;
+			}
+		}
+		else if (convex1)
+		{
+			m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal0;
+				m_upperLimit = m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal2;
+				m_upperLimit = -m_normal1;
+			}
+		}
+		else if (convex2)
+		{
+			m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = m_normal2;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = -m_normal0;
+			}
+		}
+		else
+		{
+			m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal2;
+				m_upperLimit = -m_normal0;
+			}
+		}
+	}
+	else if (hasVertex0)
+	{
+		if (convex1)
+		{
+			m_front = offset0 >= 0.0f || offset1 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal0;
+				m_upperLimit = -m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = -m_normal1;
+			}
+		}
+		else
+		{
+			m_front = offset0 >= 0.0f && offset1 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = -m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = m_normal1;
+				m_upperLimit = -m_normal0;
+			}
+		}
+	}
+	else if (hasVertex3)
+	{
+		if (convex2)
+		{
+			m_front = offset1 >= 0.0f || offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = m_normal2;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = m_normal1;
+			}
+		}
+		else
+		{
+			m_front = offset1 >= 0.0f && offset2 >= 0.0f;
+			if (m_front)
+			{
+				m_normal = m_normal1;
+				m_lowerLimit = -m_normal1;
+				m_upperLimit = m_normal1;
+			}
+			else
+			{
+				m_normal = -m_normal1;
+				m_lowerLimit = -m_normal2;
+				m_upperLimit = m_normal1;
+			}
+		}		
+	}
+	else
+	{
+		m_front = offset1 >= 0.0f;
+		if (m_front)
+		{
+			m_normal = m_normal1;
+			m_lowerLimit = -m_normal1;
+			m_upperLimit = -m_normal1;
+		}
+		else
+		{
+			m_normal = -m_normal1;
+			m_lowerLimit = m_normal1;
+			m_upperLimit = m_normal1;
+		}
+	}
+	
+	// Get polygonB in frameA
+	m_polygonB.count = polygonB->m_count;
+	for (int32 i = 0; i < polygonB->m_count; ++i)
+	{
+		m_polygonB.vertices[i] = b2Mul(m_xf, polygonB->m_vertices[i]);
+		m_polygonB.normals[i] = b2Mul(m_xf.q, polygonB->m_normals[i]);
+	}
+	
+	m_radius = 2.0f * b2_polygonRadius;
+	
+	manifold->pointCount = 0;
+	
+	b2EPAxis edgeAxis = ComputeEdgeSeparation();
+	
+	// If no valid normal can be found than this edge should not collide.
+	if (edgeAxis.type == b2EPAxis::e_unknown)
+	{
+		return;
+	}
+	
+	if (edgeAxis.separation > m_radius)
+	{
+		return;
+	}
+	
+	b2EPAxis polygonAxis = ComputePolygonSeparation();
+	if (polygonAxis.type != b2EPAxis::e_unknown && polygonAxis.separation > m_radius)
+	{
+		return;
+	}
+	
+	// Use hysteresis for jitter reduction.
+	const float32 k_relativeTol = 0.98f;
+	const float32 k_absoluteTol = 0.001f;
+	
+	b2EPAxis primaryAxis;
+	if (polygonAxis.type == b2EPAxis::e_unknown)
+	{
+		primaryAxis = edgeAxis;
+	}
+	else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
+	{
+		primaryAxis = polygonAxis;
+	}
+	else
+	{
+		primaryAxis = edgeAxis;
+	}
+	
+	b2ClipVertex ie[2];
+	b2ReferenceFace rf;
+	if (primaryAxis.type == b2EPAxis::e_edgeA)
+	{
+		manifold->type = b2Manifold::e_faceA;
+		
+		// Search for the polygon normal that is most anti-parallel to the edge normal.
+		int32 bestIndex = 0;
+		float32 bestValue = b2Dot(m_normal, m_polygonB.normals[0]);
+		for (int32 i = 1; i < m_polygonB.count; ++i)
+		{
+			float32 value = b2Dot(m_normal, m_polygonB.normals[i]);
+			if (value < bestValue)
+			{
+				bestValue = value;
+				bestIndex = i;
+			}
+		}
+		
+		int32 i1 = bestIndex;
+		int32 i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;
+		
+		ie[0].v = m_polygonB.vertices[i1];
+		ie[0].id.cf.indexA = 0;
+		ie[0].id.cf.indexB = static_cast<uint8>(i1);
+		ie[0].id.cf.typeA = b2ContactFeature::e_face;
+		ie[0].id.cf.typeB = b2ContactFeature::e_vertex;
+		
+		ie[1].v = m_polygonB.vertices[i2];
+		ie[1].id.cf.indexA = 0;
+		ie[1].id.cf.indexB = static_cast<uint8>(i2);
+		ie[1].id.cf.typeA = b2ContactFeature::e_face;
+		ie[1].id.cf.typeB = b2ContactFeature::e_vertex;
+		
+		if (m_front)
+		{
+			rf.i1 = 0;
+			rf.i2 = 1;
+			rf.v1 = m_v1;
+			rf.v2 = m_v2;
+			rf.normal = m_normal1;
+		}
+		else
+		{
+			rf.i1 = 1;
+			rf.i2 = 0;
+			rf.v1 = m_v2;
+			rf.v2 = m_v1;
+			rf.normal = -m_normal1;
+		}		
+	}
+	else
+	{
+		manifold->type = b2Manifold::e_faceB;
+		
+		ie[0].v = m_v1;
+		ie[0].id.cf.indexA = 0;
+		ie[0].id.cf.indexB = static_cast<uint8>(primaryAxis.index);
+		ie[0].id.cf.typeA = b2ContactFeature::e_vertex;
+		ie[0].id.cf.typeB = b2ContactFeature::e_face;
+		
+		ie[1].v = m_v2;
+		ie[1].id.cf.indexA = 0;
+		ie[1].id.cf.indexB = static_cast<uint8>(primaryAxis.index);		
+		ie[1].id.cf.typeA = b2ContactFeature::e_vertex;
+		ie[1].id.cf.typeB = b2ContactFeature::e_face;
+		
+		rf.i1 = primaryAxis.index;
+		rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
+		rf.v1 = m_polygonB.vertices[rf.i1];
+		rf.v2 = m_polygonB.vertices[rf.i2];
+		rf.normal = m_polygonB.normals[rf.i1];
+	}
+	
+	rf.sideNormal1.Set(rf.normal.y, -rf.normal.x);
+	rf.sideNormal2 = -rf.sideNormal1;
+	rf.sideOffset1 = b2Dot(rf.sideNormal1, rf.v1);
+	rf.sideOffset2 = b2Dot(rf.sideNormal2, rf.v2);
+	
+	// Clip incident edge against extruded edge1 side edges.
+	b2ClipVertex clipPoints1[2];
+	b2ClipVertex clipPoints2[2];
+	int32 np;
+	
+	// Clip to box side 1
+	np = b2ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);
+	
+	if (np < b2_maxManifoldPoints)
+	{
+		return;
+	}
+	
+	// Clip to negative box side 1
+	np = b2ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);
+	
+	if (np < b2_maxManifoldPoints)
+	{
+		return;
+	}
+	
+	// Now clipPoints2 contains the clipped points.
+	if (primaryAxis.type == b2EPAxis::e_edgeA)
+	{
+		manifold->localNormal = rf.normal;
+		manifold->localPoint = rf.v1;
+	}
+	else
+	{
+		manifold->localNormal = polygonB->m_normals[rf.i1];
+		manifold->localPoint = polygonB->m_vertices[rf.i1];
+	}
+	
+	int32 pointCount = 0;
+	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		float32 separation;
+		
+		separation = b2Dot(rf.normal, clipPoints2[i].v - rf.v1);
+		
+		if (separation <= m_radius)
+		{
+			b2ManifoldPoint* cp = manifold->points + pointCount;
+			
+			if (primaryAxis.type == b2EPAxis::e_edgeA)
+			{
+				cp->localPoint = b2MulT(m_xf, clipPoints2[i].v);
+				cp->id = clipPoints2[i].id;
+			}
+			else
+			{
+				cp->localPoint = clipPoints2[i].v;
+				cp->id.cf.typeA = clipPoints2[i].id.cf.typeB;
+				cp->id.cf.typeB = clipPoints2[i].id.cf.typeA;
+				cp->id.cf.indexA = clipPoints2[i].id.cf.indexB;
+				cp->id.cf.indexB = clipPoints2[i].id.cf.indexA;
+			}
+			
+			++pointCount;
+		}
+	}
+	
+	manifold->pointCount = pointCount;
+}
+
+b2EPAxis b2EPCollider::ComputeEdgeSeparation()
+{
+	b2EPAxis axis;
+	axis.type = b2EPAxis::e_edgeA;
+	axis.index = m_front ? 0 : 1;
+	axis.separation = FLT_MAX;
+	
+	for (int32 i = 0; i < m_polygonB.count; ++i)
+	{
+		float32 s = b2Dot(m_normal, m_polygonB.vertices[i] - m_v1);
+		if (s < axis.separation)
+		{
+			axis.separation = s;
+		}
+	}
+	
+	return axis;
+}
+
+b2EPAxis b2EPCollider::ComputePolygonSeparation()
+{
+	b2EPAxis axis;
+	axis.type = b2EPAxis::e_unknown;
+	axis.index = -1;
+	axis.separation = -FLT_MAX;
+
+	b2Vec2 perp(-m_normal.y, m_normal.x);
+
+	for (int32 i = 0; i < m_polygonB.count; ++i)
+	{
+		b2Vec2 n = -m_polygonB.normals[i];
+		
+		float32 s1 = b2Dot(n, m_polygonB.vertices[i] - m_v1);
+		float32 s2 = b2Dot(n, m_polygonB.vertices[i] - m_v2);
+		float32 s = b2Min(s1, s2);
+		
+		if (s > m_radius)
+		{
+			// No collision
+			axis.type = b2EPAxis::e_edgeB;
+			axis.index = i;
+			axis.separation = s;
+			return axis;
+		}
+		
+		// Adjacency
+		if (b2Dot(n, perp) >= 0.0f)
+		{
+			if (b2Dot(n - m_upperLimit, m_normal) < -b2_angularSlop)
+			{
+				continue;
+			}
+		}
+		else
+		{
+			if (b2Dot(n - m_lowerLimit, m_normal) < -b2_angularSlop)
+			{
+				continue;
+			}
+		}
+		
+		if (s > axis.separation)
+		{
+			axis.type = b2EPAxis::e_edgeB;
+			axis.index = i;
+			axis.separation = s;
+		}
+	}
+	
+	return axis;
+}
+
+void b2CollideEdgeAndPolygon(	b2Manifold* manifold,
+							 const b2EdgeShape* edgeA, const b2Transform& xfA,
+							 const b2PolygonShape* polygonB, const b2Transform& xfB)
+{
+	b2EPCollider collider;
+	collider.Collide(manifold, edgeA, xfA, polygonB, xfB);
+}

+ 239 - 317
engine/source/Box2D/Collision/b2CollidePolygon.cpp

@@ -1,317 +1,239 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-
-// Find the separation between poly1 and poly2 for a give edge normal on poly1.
-static float32 b2EdgeSeparation(const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,
-							  const b2PolygonShape* poly2, const b2Transform& xf2)
-{
-	const b2Vec2* vertices1 = poly1->m_vertices;
-	const b2Vec2* normals1 = poly1->m_normals;
-
-	int32 count2 = poly2->m_count;
-	const b2Vec2* vertices2 = poly2->m_vertices;
-
-	b2Assert(0 <= edge1 && edge1 < poly1->m_count);
-
-	// Convert normal from poly1's frame into poly2's frame.
-	b2Vec2 normal1World = b2Mul(xf1.q, normals1[edge1]);
-	b2Vec2 normal1 = b2MulT(xf2.q, normal1World);
-
-	// Find support vertex on poly2 for -normal.
-	int32 index = 0;
-	float32 minDot = b2_maxFloat;
-
-	for (int32 i = 0; i < count2; ++i)
-	{
-		float32 dot = b2Dot(vertices2[i], normal1);
-		if (dot < minDot)
-		{
-			minDot = dot;
-			index = i;
-		}
-	}
-
-	b2Vec2 v1 = b2Mul(xf1, vertices1[edge1]);
-	b2Vec2 v2 = b2Mul(xf2, vertices2[index]);
-	float32 separation = b2Dot(v2 - v1, normal1World);
-	return separation;
-}
-
-// Find the max separation between poly1 and poly2 using edge normals from poly1.
-static float32 b2FindMaxSeparation(int32* edgeIndex,
-								 const b2PolygonShape* poly1, const b2Transform& xf1,
-								 const b2PolygonShape* poly2, const b2Transform& xf2)
-{
-	int32 count1 = poly1->m_count;
-	const b2Vec2* normals1 = poly1->m_normals;
-
-	// Vector pointing from the centroid of poly1 to the centroid of poly2.
-	b2Vec2 d = b2Mul(xf2, poly2->m_centroid) - b2Mul(xf1, poly1->m_centroid);
-	b2Vec2 dLocal1 = b2MulT(xf1.q, d);
-
-	// Find edge normal on poly1 that has the largest projection onto d.
-	int32 edge = 0;
-	float32 maxDot = -b2_maxFloat;
-	for (int32 i = 0; i < count1; ++i)
-	{
-		float32 dot = b2Dot(normals1[i], dLocal1);
-		if (dot > maxDot)
-		{
-			maxDot = dot;
-			edge = i;
-		}
-	}
-
-	// Get the separation for the edge normal.
-	float32 s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2);
-
-	// Check the separation for the previous edge normal.
-	int32 prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
-	float32 sPrev = b2EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);
-
-	// Check the separation for the next edge normal.
-	int32 nextEdge = edge + 1 < count1 ? edge + 1 : 0;
-	float32 sNext = b2EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);
-
-	// Find the best edge and the search direction.
-	int32 bestEdge;
-	float32 bestSeparation;
-	int32 increment;
-	if (sPrev > s && sPrev > sNext)
-	{
-		increment = -1;
-		bestEdge = prevEdge;
-		bestSeparation = sPrev;
-	}
-	else if (sNext > s)
-	{
-		increment = 1;
-		bestEdge = nextEdge;
-		bestSeparation = sNext;
-	}
-	else
-	{
-		*edgeIndex = edge;
-		return s;
-	}
-
-	// Perform a local search for the best edge normal.
-	for ( ; ; )
-	{
-		if (increment == -1)
-			edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
-		else
-			edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
-
-		s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2);
-
-		if (s > bestSeparation)
-		{
-			bestEdge = edge;
-			bestSeparation = s;
-		}
-		else
-		{
-			break;
-		}
-	}
-
-	*edgeIndex = bestEdge;
-	return bestSeparation;
-}
-
-static void b2FindIncidentEdge(b2ClipVertex c[2],
-							 const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,
-							 const b2PolygonShape* poly2, const b2Transform& xf2)
-{
-	const b2Vec2* normals1 = poly1->m_normals;
-
-	int32 count2 = poly2->m_count;
-	const b2Vec2* vertices2 = poly2->m_vertices;
-	const b2Vec2* normals2 = poly2->m_normals;
-
-	b2Assert(0 <= edge1 && edge1 < poly1->m_count);
-
-	// Get the normal of the reference edge in poly2's frame.
-	b2Vec2 normal1 = b2MulT(xf2.q, b2Mul(xf1.q, normals1[edge1]));
-
-	// Find the incident edge on poly2.
-	int32 index = 0;
-	float32 minDot = b2_maxFloat;
-	for (int32 i = 0; i < count2; ++i)
-	{
-		float32 dot = b2Dot(normal1, normals2[i]);
-		if (dot < minDot)
-		{
-			minDot = dot;
-			index = i;
-		}
-	}
-
-	// Build the clip vertices for the incident edge.
-	int32 i1 = index;
-	int32 i2 = i1 + 1 < count2 ? i1 + 1 : 0;
-
-	c[0].v = b2Mul(xf2, vertices2[i1]);
-	c[0].id.cf.indexA = (uint8)edge1;
-	c[0].id.cf.indexB = (uint8)i1;
-	c[0].id.cf.typeA = b2ContactFeature::e_face;
-	c[0].id.cf.typeB = b2ContactFeature::e_vertex;
-
-	c[1].v = b2Mul(xf2, vertices2[i2]);
-	c[1].id.cf.indexA = (uint8)edge1;
-	c[1].id.cf.indexB = (uint8)i2;
-	c[1].id.cf.typeA = b2ContactFeature::e_face;
-	c[1].id.cf.typeB = b2ContactFeature::e_vertex;
-}
-
-// Find edge normal of max separation on A - return if separating axis is found
-// Find edge normal of max separation on B - return if separation axis is found
-// Choose reference edge as min(minA, minB)
-// Find incident edge
-// Clip
-
-// The normal points from 1 to 2
-void b2CollidePolygons(b2Manifold* manifold,
-					  const b2PolygonShape* polyA, const b2Transform& xfA,
-					  const b2PolygonShape* polyB, const b2Transform& xfB)
-{
-	manifold->pointCount = 0;
-	float32 totalRadius = polyA->m_radius + polyB->m_radius;
-
-	int32 edgeA = 0;
-	float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB);
-	if (separationA > totalRadius)
-		return;
-
-	int32 edgeB = 0;
-	float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA);
-	if (separationB > totalRadius)
-		return;
-
-	const b2PolygonShape* poly1;	// reference polygon
-	const b2PolygonShape* poly2;	// incident polygon
-	b2Transform xf1, xf2;
-	int32 edge1;		// reference edge
-	uint8 flip;
-	const float32 k_relativeTol = 0.98f;
-	const float32 k_absoluteTol = 0.001f;
-
-	if (separationB > k_relativeTol * separationA + k_absoluteTol)
-	{
-		poly1 = polyB;
-		poly2 = polyA;
-		xf1 = xfB;
-		xf2 = xfA;
-		edge1 = edgeB;
-		manifold->type = b2Manifold::e_faceB;
-		flip = 1;
-	}
-	else
-	{
-		poly1 = polyA;
-		poly2 = polyB;
-		xf1 = xfA;
-		xf2 = xfB;
-		edge1 = edgeA;
-		manifold->type = b2Manifold::e_faceA;
-		flip = 0;
-	}
-
-	b2ClipVertex incidentEdge[2];
-	b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
-
-	int32 count1 = poly1->m_count;
-	const b2Vec2* vertices1 = poly1->m_vertices;
-
-	int32 iv1 = edge1;
-	int32 iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0;
-
-	b2Vec2 v11 = vertices1[iv1];
-	b2Vec2 v12 = vertices1[iv2];
-
-	b2Vec2 localTangent = v12 - v11;
-	localTangent.Normalize();
-	
-	b2Vec2 localNormal = b2Cross(localTangent, 1.0f);
-	b2Vec2 planePoint = 0.5f * (v11 + v12);
-
-	b2Vec2 tangent = b2Mul(xf1.q, localTangent);
-	b2Vec2 normal = b2Cross(tangent, 1.0f);
-	
-	v11 = b2Mul(xf1, v11);
-	v12 = b2Mul(xf1, v12);
-
-	// Face offset.
-	float32 frontOffset = b2Dot(normal, v11);
-
-	// Side offsets, extended by polytope skin thickness.
-	float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius;
-	float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius;
-
-	// Clip incident edge against extruded edge1 side edges.
-	b2ClipVertex clipPoints1[2];
-	b2ClipVertex clipPoints2[2];
-	int np;
-
-	// Clip to box side 1
-	np = b2ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1, iv1);
-
-	if (np < 2)
-		return;
-
-	// Clip to negative box side 1
-	np = b2ClipSegmentToLine(clipPoints2, clipPoints1,  tangent, sideOffset2, iv2);
-
-	if (np < 2)
-	{
-		return;
-	}
-
-	// Now clipPoints2 contains the clipped points.
-	manifold->localNormal = localNormal;
-	manifold->localPoint = planePoint;
-
-	int32 pointCount = 0;
-	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
-	{
-		float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset;
-
-		if (separation <= totalRadius)
-		{
-			b2ManifoldPoint* cp = manifold->points + pointCount;
-			cp->localPoint = b2MulT(xf2, clipPoints2[i].v);
-			cp->id = clipPoints2[i].id;
-			if (flip)
-			{
-				// Swap features
-				b2ContactFeature cf = cp->id.cf;
-				cp->id.cf.indexA = cf.indexB;
-				cp->id.cf.indexB = cf.indexA;
-				cp->id.cf.typeA = cf.typeB;
-				cp->id.cf.typeB = cf.typeA;
-			}
-			++pointCount;
-		}
-	}
-
-	manifold->pointCount = pointCount;
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+// Find the max separation between poly1 and poly2 using edge normals from poly1.
+static float32 b2FindMaxSeparation(int32* edgeIndex,
+								 const b2PolygonShape* poly1, const b2Transform& xf1,
+								 const b2PolygonShape* poly2, const b2Transform& xf2)
+{
+	int32 count1 = poly1->m_count;
+	int32 count2 = poly2->m_count;
+	const b2Vec2* n1s = poly1->m_normals;
+	const b2Vec2* v1s = poly1->m_vertices;
+	const b2Vec2* v2s = poly2->m_vertices;
+	b2Transform xf = b2MulT(xf2, xf1);
+
+	int32 bestIndex = 0;
+	float32 maxSeparation = -b2_maxFloat;
+	for (int32 i = 0; i < count1; ++i)
+	{
+		// Get poly1 normal in frame2.
+		b2Vec2 n = b2Mul(xf.q, n1s[i]);
+		b2Vec2 v1 = b2Mul(xf, v1s[i]);
+
+		// Find deepest point for normal i.
+		float32 si = b2_maxFloat;
+		for (int32 j = 0; j < count2; ++j)
+		{
+			float32 sij = b2Dot(n, v2s[j] - v1);
+			if (sij < si)
+			{
+				si = sij;
+			}
+		}
+
+		if (si > maxSeparation)
+		{
+			maxSeparation = si;
+			bestIndex = i;
+		}
+	}
+
+	*edgeIndex = bestIndex;
+	return maxSeparation;
+}
+
+static void b2FindIncidentEdge(b2ClipVertex c[2],
+							 const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,
+							 const b2PolygonShape* poly2, const b2Transform& xf2)
+{
+	const b2Vec2* normals1 = poly1->m_normals;
+
+	int32 count2 = poly2->m_count;
+	const b2Vec2* vertices2 = poly2->m_vertices;
+	const b2Vec2* normals2 = poly2->m_normals;
+
+	b2Assert(0 <= edge1 && edge1 < poly1->m_count);
+
+	// Get the normal of the reference edge in poly2's frame.
+	b2Vec2 normal1 = b2MulT(xf2.q, b2Mul(xf1.q, normals1[edge1]));
+
+	// Find the incident edge on poly2.
+	int32 index = 0;
+	float32 minDot = b2_maxFloat;
+	for (int32 i = 0; i < count2; ++i)
+	{
+		float32 dot = b2Dot(normal1, normals2[i]);
+		if (dot < minDot)
+		{
+			minDot = dot;
+			index = i;
+		}
+	}
+
+	// Build the clip vertices for the incident edge.
+	int32 i1 = index;
+	int32 i2 = i1 + 1 < count2 ? i1 + 1 : 0;
+
+	c[0].v = b2Mul(xf2, vertices2[i1]);
+	c[0].id.cf.indexA = (uint8)edge1;
+	c[0].id.cf.indexB = (uint8)i1;
+	c[0].id.cf.typeA = b2ContactFeature::e_face;
+	c[0].id.cf.typeB = b2ContactFeature::e_vertex;
+
+	c[1].v = b2Mul(xf2, vertices2[i2]);
+	c[1].id.cf.indexA = (uint8)edge1;
+	c[1].id.cf.indexB = (uint8)i2;
+	c[1].id.cf.typeA = b2ContactFeature::e_face;
+	c[1].id.cf.typeB = b2ContactFeature::e_vertex;
+}
+
+// Find edge normal of max separation on A - return if separating axis is found
+// Find edge normal of max separation on B - return if separation axis is found
+// Choose reference edge as min(minA, minB)
+// Find incident edge
+// Clip
+
+// The normal points from 1 to 2
+void b2CollidePolygons(b2Manifold* manifold,
+					  const b2PolygonShape* polyA, const b2Transform& xfA,
+					  const b2PolygonShape* polyB, const b2Transform& xfB)
+{
+	manifold->pointCount = 0;
+	float32 totalRadius = polyA->m_radius + polyB->m_radius;
+
+	int32 edgeA = 0;
+	float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB);
+	if (separationA > totalRadius)
+		return;
+
+	int32 edgeB = 0;
+	float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA);
+	if (separationB > totalRadius)
+		return;
+
+	const b2PolygonShape* poly1;	// reference polygon
+	const b2PolygonShape* poly2;	// incident polygon
+	b2Transform xf1, xf2;
+	int32 edge1;					// reference edge
+	uint8 flip;
+	const float32 k_tol = 0.1f * b2_linearSlop;
+
+	if (separationB > separationA + k_tol)
+	{
+		poly1 = polyB;
+		poly2 = polyA;
+		xf1 = xfB;
+		xf2 = xfA;
+		edge1 = edgeB;
+		manifold->type = b2Manifold::e_faceB;
+		flip = 1;
+	}
+	else
+	{
+		poly1 = polyA;
+		poly2 = polyB;
+		xf1 = xfA;
+		xf2 = xfB;
+		edge1 = edgeA;
+		manifold->type = b2Manifold::e_faceA;
+		flip = 0;
+	}
+
+	b2ClipVertex incidentEdge[2];
+	b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);
+
+	int32 count1 = poly1->m_count;
+	const b2Vec2* vertices1 = poly1->m_vertices;
+
+	int32 iv1 = edge1;
+	int32 iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0;
+
+	b2Vec2 v11 = vertices1[iv1];
+	b2Vec2 v12 = vertices1[iv2];
+
+	b2Vec2 localTangent = v12 - v11;
+	localTangent.Normalize();
+	
+	b2Vec2 localNormal = b2Cross(localTangent, 1.0f);
+	b2Vec2 planePoint = 0.5f * (v11 + v12);
+
+	b2Vec2 tangent = b2Mul(xf1.q, localTangent);
+	b2Vec2 normal = b2Cross(tangent, 1.0f);
+	
+	v11 = b2Mul(xf1, v11);
+	v12 = b2Mul(xf1, v12);
+
+	// Face offset.
+	float32 frontOffset = b2Dot(normal, v11);
+
+	// Side offsets, extended by polytope skin thickness.
+	float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius;
+	float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius;
+
+	// Clip incident edge against extruded edge1 side edges.
+	b2ClipVertex clipPoints1[2];
+	b2ClipVertex clipPoints2[2];
+	int np;
+
+	// Clip to box side 1
+	np = b2ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1, iv1);
+
+	if (np < 2)
+		return;
+
+	// Clip to negative box side 1
+	np = b2ClipSegmentToLine(clipPoints2, clipPoints1,  tangent, sideOffset2, iv2);
+
+	if (np < 2)
+	{
+		return;
+	}
+
+	// Now clipPoints2 contains the clipped points.
+	manifold->localNormal = localNormal;
+	manifold->localPoint = planePoint;
+
+	int32 pointCount = 0;
+	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset;
+
+		if (separation <= totalRadius)
+		{
+			b2ManifoldPoint* cp = manifold->points + pointCount;
+			cp->localPoint = b2MulT(xf2, clipPoints2[i].v);
+			cp->id = clipPoints2[i].id;
+			if (flip)
+			{
+				// Swap features
+				b2ContactFeature cf = cp->id.cf;
+				cp->id.cf.indexA = cf.indexB;
+				cp->id.cf.indexB = cf.indexA;
+				cp->id.cf.typeA = cf.typeB;
+				cp->id.cf.typeB = cf.typeA;
+			}
+			++pointCount;
+		}
+	}
+
+	manifold->pointCount = pointCount;
+}

+ 252 - 249
engine/source/Box2D/Collision/b2Collision.cpp

@@ -1,249 +1,252 @@
-/*
-* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Collision/b2Distance.h>
-
-void b2WorldManifold::Initialize(const b2Manifold* manifold,
-						  const b2Transform& xfA, float32 radiusA,
-						  const b2Transform& xfB, float32 radiusB)
-{
-	if (manifold->pointCount == 0)
-	{
-		return;
-	}
-
-	switch (manifold->type)
-	{
-	case b2Manifold::e_circles:
-		{
-			normal.Set(1.0f, 0.0f);
-			b2Vec2 pointA = b2Mul(xfA, manifold->localPoint);
-			b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint);
-			if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon)
-			{
-				normal = pointB - pointA;
-				normal.Normalize();
-			}
-
-			b2Vec2 cA = pointA + radiusA * normal;
-			b2Vec2 cB = pointB - radiusB * normal;
-			points[0] = 0.5f * (cA + cB);
-		}
-		break;
-
-	case b2Manifold::e_faceA:
-		{
-			normal = b2Mul(xfA.q, manifold->localNormal);
-			b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint);
-			
-			for (int32 i = 0; i < manifold->pointCount; ++i)
-			{
-				b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);
-				b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal;
-				b2Vec2 cB = clipPoint - radiusB * normal;
-				points[i] = 0.5f * (cA + cB);
-			}
-		}
-		break;
-
-	case b2Manifold::e_faceB:
-		{
-			normal = b2Mul(xfB.q, manifold->localNormal);
-			b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint);
-
-			for (int32 i = 0; i < manifold->pointCount; ++i)
-			{
-				b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);
-				b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;
-				b2Vec2 cA = clipPoint - radiusA * normal;
-				points[i] = 0.5f * (cA + cB);
-			}
-
-			// Ensure normal points from A to B.
-			normal = -normal;
-		}
-		break;
-	}
-}
-
-void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
-					  const b2Manifold* manifold1, const b2Manifold* manifold2)
-{
-	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
-	{
-		state1[i] = b2_nullState;
-		state2[i] = b2_nullState;
-	}
-
-	// Detect persists and removes.
-	for (int32 i = 0; i < manifold1->pointCount; ++i)
-	{
-		b2ContactID id = manifold1->points[i].id;
-
-		state1[i] = b2_removeState;
-
-		for (int32 j = 0; j < manifold2->pointCount; ++j)
-		{
-			if (manifold2->points[j].id.key == id.key)
-			{
-				state1[i] = b2_persistState;
-				break;
-			}
-		}
-	}
-
-	// Detect persists and adds.
-	for (int32 i = 0; i < manifold2->pointCount; ++i)
-	{
-		b2ContactID id = manifold2->points[i].id;
-
-		state2[i] = b2_addState;
-
-		for (int32 j = 0; j < manifold1->pointCount; ++j)
-		{
-			if (manifold1->points[j].id.key == id.key)
-			{
-				state2[i] = b2_persistState;
-				break;
-			}
-		}
-	}
-}
-
-// From Real-time Collision Detection, p179.
-bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const
-{
-	float32 tmin = -b2_maxFloat;
-	float32 tmax = b2_maxFloat;
-
-	b2Vec2 p = input.p1;
-	b2Vec2 d = input.p2 - input.p1;
-	b2Vec2 absD = b2Abs(d);
-
-	b2Vec2 normal;
-
-	for (int32 i = 0; i < 2; ++i)
-	{
-		if (absD(i) < b2_epsilon)
-		{
-			// Parallel.
-			if (p(i) < lowerBound(i) || upperBound(i) < p(i))
-			{
-				return false;
-			}
-		}
-		else
-		{
-			float32 inv_d = 1.0f / d(i);
-			float32 t1 = (lowerBound(i) - p(i)) * inv_d;
-			float32 t2 = (upperBound(i) - p(i)) * inv_d;
-
-			// Sign of the normal vector.
-			float32 s = -1.0f;
-
-			if (t1 > t2)
-			{
-				b2Swap(t1, t2);
-				s = 1.0f;
-			}
-
-			// Push the min up
-			if (t1 > tmin)
-			{
-				normal.SetZero();
-				normal(i) = s;
-				tmin = t1;
-			}
-
-			// Pull the max down
-			tmax = b2Min(tmax, t2);
-
-			if (tmin > tmax)
-			{
-				return false;
-			}
-		}
-	}
-
-	// Does the ray start inside the box?
-	// Does the ray intersect beyond the max fraction?
-	if (tmin < 0.0f || input.maxFraction < tmin)
-	{
-		return false;
-	}
-
-	// Intersection.
-	output->fraction = tmin;
-	output->normal = normal;
-	return true;
-}
-
-// Sutherland-Hodgman clipping.
-int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
-						const b2Vec2& normal, float32 offset, int32 vertexIndexA)
-{
-	// Start with no output points
-	int32 numOut = 0;
-
-	// Calculate the distance of end points to the line
-	float32 distance0 = b2Dot(normal, vIn[0].v) - offset;
-	float32 distance1 = b2Dot(normal, vIn[1].v) - offset;
-
-	// If the points are behind the plane
-	if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
-	if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
-
-	// If the points are on different sides of the plane
-	if (distance0 * distance1 < 0.0f)
-	{
-		// Find intersection point of edge and plane
-		float32 interp = distance0 / (distance0 - distance1);
-		vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
-
-		// VertexA is hitting edgeB.
-		vOut[numOut].id.cf.indexA = vertexIndexA;
-		vOut[numOut].id.cf.indexB = vIn[0].id.cf.indexB;
-		vOut[numOut].id.cf.typeA = b2ContactFeature::e_vertex;
-		vOut[numOut].id.cf.typeB = b2ContactFeature::e_face;
-		++numOut;
-	}
-
-	return numOut;
-}
-
-bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
-					const b2Shape* shapeB, int32 indexB,
-					const b2Transform& xfA, const b2Transform& xfB)
-{
-	b2DistanceInput input;
-	input.proxyA.Set(shapeA, indexA);
-	input.proxyB.Set(shapeB, indexB);
-	input.transformA = xfA;
-	input.transformB = xfB;
-	input.useRadii = true;
-
-	b2SimplexCache cache;
-	cache.count = 0;
-
-	b2DistanceOutput output;
-
-	b2Distance(&output, &cache, &input);
-
-	return output.distance < 10.0f * b2_epsilon;
-}
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2Distance.h>
+
+void b2WorldManifold::Initialize(const b2Manifold* manifold,
+						  const b2Transform& xfA, float32 radiusA,
+						  const b2Transform& xfB, float32 radiusB)
+{
+	if (manifold->pointCount == 0)
+	{
+		return;
+	}
+
+	switch (manifold->type)
+	{
+	case b2Manifold::e_circles:
+		{
+			normal.Set(1.0f, 0.0f);
+			b2Vec2 pointA = b2Mul(xfA, manifold->localPoint);
+			b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint);
+			if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon)
+			{
+				normal = pointB - pointA;
+				normal.Normalize();
+			}
+
+			b2Vec2 cA = pointA + radiusA * normal;
+			b2Vec2 cB = pointB - radiusB * normal;
+			points[0] = 0.5f * (cA + cB);
+			separations[0] = b2Dot(cB - cA, normal);
+		}
+		break;
+
+	case b2Manifold::e_faceA:
+		{
+			normal = b2Mul(xfA.q, manifold->localNormal);
+			b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint);
+			
+			for (int32 i = 0; i < manifold->pointCount; ++i)
+			{
+				b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);
+				b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal;
+				b2Vec2 cB = clipPoint - radiusB * normal;
+				points[i] = 0.5f * (cA + cB);
+				separations[i] = b2Dot(cB - cA, normal);
+			}
+		}
+		break;
+
+	case b2Manifold::e_faceB:
+		{
+			normal = b2Mul(xfB.q, manifold->localNormal);
+			b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint);
+
+			for (int32 i = 0; i < manifold->pointCount; ++i)
+			{
+				b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);
+				b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;
+				b2Vec2 cA = clipPoint - radiusA * normal;
+				points[i] = 0.5f * (cA + cB);
+				separations[i] = b2Dot(cA - cB, normal);
+			}
+
+			// Ensure normal points from A to B.
+			normal = -normal;
+		}
+		break;
+	}
+}
+
+void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
+					  const b2Manifold* manifold1, const b2Manifold* manifold2)
+{
+	for (int32 i = 0; i < b2_maxManifoldPoints; ++i)
+	{
+		state1[i] = b2_nullState;
+		state2[i] = b2_nullState;
+	}
+
+	// Detect persists and removes.
+	for (int32 i = 0; i < manifold1->pointCount; ++i)
+	{
+		b2ContactID id = manifold1->points[i].id;
+
+		state1[i] = b2_removeState;
+
+		for (int32 j = 0; j < manifold2->pointCount; ++j)
+		{
+			if (manifold2->points[j].id.key == id.key)
+			{
+				state1[i] = b2_persistState;
+				break;
+			}
+		}
+	}
+
+	// Detect persists and adds.
+	for (int32 i = 0; i < manifold2->pointCount; ++i)
+	{
+		b2ContactID id = manifold2->points[i].id;
+
+		state2[i] = b2_addState;
+
+		for (int32 j = 0; j < manifold1->pointCount; ++j)
+		{
+			if (manifold1->points[j].id.key == id.key)
+			{
+				state2[i] = b2_persistState;
+				break;
+			}
+		}
+	}
+}
+
+// From Real-time Collision Detection, p179.
+bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const
+{
+	float32 tmin = -b2_maxFloat;
+	float32 tmax = b2_maxFloat;
+
+	b2Vec2 p = input.p1;
+	b2Vec2 d = input.p2 - input.p1;
+	b2Vec2 absD = b2Abs(d);
+
+	b2Vec2 normal;
+
+	for (int32 i = 0; i < 2; ++i)
+	{
+		if (absD(i) < b2_epsilon)
+		{
+			// Parallel.
+			if (p(i) < lowerBound(i) || upperBound(i) < p(i))
+			{
+				return false;
+			}
+		}
+		else
+		{
+			float32 inv_d = 1.0f / d(i);
+			float32 t1 = (lowerBound(i) - p(i)) * inv_d;
+			float32 t2 = (upperBound(i) - p(i)) * inv_d;
+
+			// Sign of the normal vector.
+			float32 s = -1.0f;
+
+			if (t1 > t2)
+			{
+				b2Swap(t1, t2);
+				s = 1.0f;
+			}
+
+			// Push the min up
+			if (t1 > tmin)
+			{
+				normal.SetZero();
+				normal(i) = s;
+				tmin = t1;
+			}
+
+			// Pull the max down
+			tmax = b2Min(tmax, t2);
+
+			if (tmin > tmax)
+			{
+				return false;
+			}
+		}
+	}
+
+	// Does the ray start inside the box?
+	// Does the ray intersect beyond the max fraction?
+	if (tmin < 0.0f || input.maxFraction < tmin)
+	{
+		return false;
+	}
+
+	// Intersection.
+	output->fraction = tmin;
+	output->normal = normal;
+	return true;
+}
+
+// Sutherland-Hodgman clipping.
+int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
+						const b2Vec2& normal, float32 offset, int32 vertexIndexA)
+{
+	// Start with no output points
+	int32 numOut = 0;
+
+	// Calculate the distance of end points to the line
+	float32 distance0 = b2Dot(normal, vIn[0].v) - offset;
+	float32 distance1 = b2Dot(normal, vIn[1].v) - offset;
+
+	// If the points are behind the plane
+	if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
+	if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];
+
+	// If the points are on different sides of the plane
+	if (distance0 * distance1 < 0.0f)
+	{
+		// Find intersection point of edge and plane
+		float32 interp = distance0 / (distance0 - distance1);
+		vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
+
+		// VertexA is hitting edgeB.
+		vOut[numOut].id.cf.indexA = static_cast<uint8>(vertexIndexA);
+		vOut[numOut].id.cf.indexB = vIn[0].id.cf.indexB;
+		vOut[numOut].id.cf.typeA = b2ContactFeature::e_vertex;
+		vOut[numOut].id.cf.typeB = b2ContactFeature::e_face;
+		++numOut;
+	}
+
+	return numOut;
+}
+
+bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
+					const b2Shape* shapeB, int32 indexB,
+					const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2DistanceInput input;
+	input.proxyA.Set(shapeA, indexA);
+	input.proxyB.Set(shapeB, indexB);
+	input.transformA = xfA;
+	input.transformB = xfB;
+	input.useRadii = true;
+
+	b2SimplexCache cache;
+	cache.count = 0;
+
+	b2DistanceOutput output;
+
+	b2Distance(&output, &cache, &input);
+
+	return output.distance < 10.0f * b2_epsilon;
+}

+ 277 - 276
engine/source/Box2D/Collision/b2Collision.h

@@ -1,276 +1,277 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_COLLISION_H
-#define B2_COLLISION_H
-
-#include <Box2D/Common/b2Math.h>
-#include <climits>
-
-/// @file
-/// Structures and functions used for computing contact points, distance
-/// queries, and TOI queries.
-
-class b2Shape;
-class b2CircleShape;
-class b2EdgeShape;
-class b2PolygonShape;
-
-const uint8 b2_nullFeature = UCHAR_MAX;
-
-/// The features that intersect to form the contact point
-/// This must be 4 bytes or less.
-struct b2ContactFeature
-{
-	enum Type
-	{
-		e_vertex = 0,
-		e_face = 1
-	};
-
-	uint8 indexA;		///< Feature index on shapeA
-	uint8 indexB;		///< Feature index on shapeB
-	uint8 typeA;		///< The feature type on shapeA
-	uint8 typeB;		///< The feature type on shapeB
-};
-
-/// Contact ids to facilitate warm starting.
-union b2ContactID
-{
-	b2ContactFeature cf;
-	uint32 key;					///< Used to quickly compare contact ids.
-};
-
-/// A manifold point is a contact point belonging to a contact
-/// manifold. It holds details related to the geometry and dynamics
-/// of the contact points.
-/// The local point usage depends on the manifold type:
-/// -e_circles: the local center of circleB
-/// -e_faceA: the local center of cirlceB or the clip point of polygonB
-/// -e_faceB: the clip point of polygonA
-/// This structure is stored across time steps, so we keep it small.
-/// Note: the impulses are used for internal caching and may not
-/// provide reliable contact forces, especially for high speed collisions.
-struct b2ManifoldPoint
-{
-	b2Vec2 localPoint;		///< usage depends on manifold type
-	float32 normalImpulse;	///< the non-penetration impulse
-	float32 tangentImpulse;	///< the friction impulse
-	b2ContactID id;			///< uniquely identifies a contact point between two shapes
-};
-
-/// A manifold for two touching convex shapes.
-/// Box2D supports multiple types of contact:
-/// - clip point versus plane with radius
-/// - point versus point with radius (circles)
-/// The local point usage depends on the manifold type:
-/// -e_circles: the local center of circleA
-/// -e_faceA: the center of faceA
-/// -e_faceB: the center of faceB
-/// Similarly the local normal usage:
-/// -e_circles: not used
-/// -e_faceA: the normal on polygonA
-/// -e_faceB: the normal on polygonB
-/// We store contacts in this way so that position correction can
-/// account for movement, which is critical for continuous physics.
-/// All contact scenarios must be expressed in one of these types.
-/// This structure is stored across time steps, so we keep it small.
-struct b2Manifold
-{
-	enum Type
-	{
-		e_circles,
-		e_faceA,
-		e_faceB
-	};
-
-	b2ManifoldPoint points[b2_maxManifoldPoints];	///< the points of contact
-	b2Vec2 localNormal;								///< not use for Type::e_points
-	b2Vec2 localPoint;								///< usage depends on manifold type
-	Type type;
-	int32 pointCount;								///< the number of manifold points
-};
-
-/// This is used to compute the current state of a contact manifold.
-struct b2WorldManifold
-{
-	/// Evaluate the manifold with supplied transforms. This assumes
-	/// modest motion from the original state. This does not change the
-	/// point count, impulses, etc. The radii must come from the shapes
-	/// that generated the manifold.
-	void Initialize(const b2Manifold* manifold,
-					const b2Transform& xfA, float32 radiusA,
-					const b2Transform& xfB, float32 radiusB);
-
-	b2Vec2 normal;							///< world vector pointing from A to B
-	b2Vec2 points[b2_maxManifoldPoints];	///< world contact point (point of intersection)
-};
-
-/// This is used for determining the state of contact points.
-enum b2PointState
-{
-	b2_nullState,		///< point does not exist
-	b2_addState,		///< point was added in the update
-	b2_persistState,	///< point persisted across the update
-	b2_removeState		///< point was removed in the update
-};
-
-/// Compute the point states given two manifolds. The states pertain to the transition from manifold1
-/// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
-void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
-					  const b2Manifold* manifold1, const b2Manifold* manifold2);
-
-/// Used for computing contact manifolds.
-struct b2ClipVertex
-{
-	b2Vec2 v;
-	b2ContactID id;
-};
-
-/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
-struct b2RayCastInput
-{
-	b2Vec2 p1, p2;
-	float32 maxFraction;
-};
-
-/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
-/// come from b2RayCastInput.
-struct b2RayCastOutput
-{
-	b2Vec2 normal;
-	float32 fraction;
-};
-
-/// An axis aligned bounding box.
-struct b2AABB
-{
-	/// Verify that the bounds are sorted.
-	bool IsValid() const;
-
-	/// Get the center of the AABB.
-	b2Vec2 GetCenter() const
-	{
-		return 0.5f * (lowerBound + upperBound);
-	}
-
-	/// Get the extents of the AABB (half-widths).
-	b2Vec2 GetExtents() const
-	{
-		return 0.5f * (upperBound - lowerBound);
-	}
-
-	/// Get the perimeter length
-	float32 GetPerimeter() const
-	{
-		float32 wx = upperBound.x - lowerBound.x;
-		float32 wy = upperBound.y - lowerBound.y;
-		return 2.0f * (wx + wy);
-	}
-
-	/// Combine an AABB into this one.
-	void Combine(const b2AABB& aabb)
-	{
-		lowerBound = b2Min(lowerBound, aabb.lowerBound);
-		upperBound = b2Max(upperBound, aabb.upperBound);
-	}
-
-	/// Combine two AABBs into this one.
-	void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
-	{
-		lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
-		upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
-	}
-
-	/// Does this aabb contain the provided AABB.
-	bool Contains(const b2AABB& aabb) const
-	{
-		bool result = true;
-		result = result && lowerBound.x <= aabb.lowerBound.x;
-		result = result && lowerBound.y <= aabb.lowerBound.y;
-		result = result && aabb.upperBound.x <= upperBound.x;
-		result = result && aabb.upperBound.y <= upperBound.y;
-		return result;
-	}
-
-	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
-
-	b2Vec2 lowerBound;	///< the lower vertex
-	b2Vec2 upperBound;	///< the upper vertex
-};
-
-/// Compute the collision manifold between two circles.
-void b2CollideCircles(b2Manifold* manifold,
-					  const b2CircleShape* circleA, const b2Transform& xfA,
-					  const b2CircleShape* circleB, const b2Transform& xfB);
-
-/// Compute the collision manifold between a polygon and a circle.
-void b2CollidePolygonAndCircle(b2Manifold* manifold,
-							   const b2PolygonShape* polygonA, const b2Transform& xfA,
-							   const b2CircleShape* circleB, const b2Transform& xfB);
-
-/// Compute the collision manifold between two polygons.
-void b2CollidePolygons(b2Manifold* manifold,
-					   const b2PolygonShape* polygonA, const b2Transform& xfA,
-					   const b2PolygonShape* polygonB, const b2Transform& xfB);
-
-/// Compute the collision manifold between an edge and a circle.
-void b2CollideEdgeAndCircle(b2Manifold* manifold,
-							   const b2EdgeShape* polygonA, const b2Transform& xfA,
-							   const b2CircleShape* circleB, const b2Transform& xfB);
-
-/// Compute the collision manifold between an edge and a circle.
-void b2CollideEdgeAndPolygon(b2Manifold* manifold,
-							   const b2EdgeShape* edgeA, const b2Transform& xfA,
-							   const b2PolygonShape* circleB, const b2Transform& xfB);
-
-/// Clipping for contact manifolds.
-int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
-							const b2Vec2& normal, float32 offset, int32 vertexIndexA);
-
-/// Determine if two generic shapes overlap.
-bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
-					const b2Shape* shapeB, int32 indexB,
-					const b2Transform& xfA, const b2Transform& xfB);
-
-// ---------------- Inline Functions ------------------------------------------
-
-inline bool b2AABB::IsValid() const
-{
-	b2Vec2 d = upperBound - lowerBound;
-	bool valid = d.x >= 0.0f && d.y >= 0.0f;
-	valid = valid && lowerBound.IsValid() && upperBound.IsValid();
-	return valid;
-}
-
-inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
-{
-	b2Vec2 d1, d2;
-	d1 = b.lowerBound - a.upperBound;
-	d2 = a.lowerBound - b.upperBound;
-
-	if (d1.x > 0.0f || d1.y > 0.0f)
-		return false;
-
-	if (d2.x > 0.0f || d2.y > 0.0f)
-		return false;
-
-	return true;
-}
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_COLLISION_H
+#define B2_COLLISION_H
+
+#include <Box2D/Common/b2Math.h>
+#include <limits.h>
+
+/// @file
+/// Structures and functions used for computing contact points, distance
+/// queries, and TOI queries.
+
+class b2Shape;
+class b2CircleShape;
+class b2EdgeShape;
+class b2PolygonShape;
+
+const uint8 b2_nullFeature = UCHAR_MAX;
+
+/// The features that intersect to form the contact point
+/// This must be 4 bytes or less.
+struct b2ContactFeature
+{
+	enum Type
+	{
+		e_vertex = 0,
+		e_face = 1
+	};
+
+	uint8 indexA;		///< Feature index on shapeA
+	uint8 indexB;		///< Feature index on shapeB
+	uint8 typeA;		///< The feature type on shapeA
+	uint8 typeB;		///< The feature type on shapeB
+};
+
+/// Contact ids to facilitate warm starting.
+union b2ContactID
+{
+	b2ContactFeature cf;
+	uint32 key;					///< Used to quickly compare contact ids.
+};
+
+/// A manifold point is a contact point belonging to a contact
+/// manifold. It holds details related to the geometry and dynamics
+/// of the contact points.
+/// The local point usage depends on the manifold type:
+/// -e_circles: the local center of circleB
+/// -e_faceA: the local center of cirlceB or the clip point of polygonB
+/// -e_faceB: the clip point of polygonA
+/// This structure is stored across time steps, so we keep it small.
+/// Note: the impulses are used for internal caching and may not
+/// provide reliable contact forces, especially for high speed collisions.
+struct b2ManifoldPoint
+{
+	b2Vec2 localPoint;		///< usage depends on manifold type
+	float32 normalImpulse;	///< the non-penetration impulse
+	float32 tangentImpulse;	///< the friction impulse
+	b2ContactID id;			///< uniquely identifies a contact point between two shapes
+};
+
+/// A manifold for two touching convex shapes.
+/// Box2D supports multiple types of contact:
+/// - clip point versus plane with radius
+/// - point versus point with radius (circles)
+/// The local point usage depends on the manifold type:
+/// -e_circles: the local center of circleA
+/// -e_faceA: the center of faceA
+/// -e_faceB: the center of faceB
+/// Similarly the local normal usage:
+/// -e_circles: not used
+/// -e_faceA: the normal on polygonA
+/// -e_faceB: the normal on polygonB
+/// We store contacts in this way so that position correction can
+/// account for movement, which is critical for continuous physics.
+/// All contact scenarios must be expressed in one of these types.
+/// This structure is stored across time steps, so we keep it small.
+struct b2Manifold
+{
+	enum Type
+	{
+		e_circles,
+		e_faceA,
+		e_faceB
+	};
+
+	b2ManifoldPoint points[b2_maxManifoldPoints];	///< the points of contact
+	b2Vec2 localNormal;								///< not use for Type::e_points
+	b2Vec2 localPoint;								///< usage depends on manifold type
+	Type type;
+	int32 pointCount;								///< the number of manifold points
+};
+
+/// This is used to compute the current state of a contact manifold.
+struct b2WorldManifold
+{
+	/// Evaluate the manifold with supplied transforms. This assumes
+	/// modest motion from the original state. This does not change the
+	/// point count, impulses, etc. The radii must come from the shapes
+	/// that generated the manifold.
+	void Initialize(const b2Manifold* manifold,
+					const b2Transform& xfA, float32 radiusA,
+					const b2Transform& xfB, float32 radiusB);
+
+	b2Vec2 normal;								///< world vector pointing from A to B
+	b2Vec2 points[b2_maxManifoldPoints];		///< world contact point (point of intersection)
+	float32 separations[b2_maxManifoldPoints];	///< a negative value indicates overlap, in meters
+};
+
+/// This is used for determining the state of contact points.
+enum b2PointState
+{
+	b2_nullState,		///< point does not exist
+	b2_addState,		///< point was added in the update
+	b2_persistState,	///< point persisted across the update
+	b2_removeState		///< point was removed in the update
+};
+
+/// Compute the point states given two manifolds. The states pertain to the transition from manifold1
+/// to manifold2. So state1 is either persist or remove while state2 is either add or persist.
+void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],
+					  const b2Manifold* manifold1, const b2Manifold* manifold2);
+
+/// Used for computing contact manifolds.
+struct b2ClipVertex
+{
+	b2Vec2 v;
+	b2ContactID id;
+};
+
+/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
+struct b2RayCastInput
+{
+	b2Vec2 p1, p2;
+	float32 maxFraction;
+};
+
+/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
+/// come from b2RayCastInput.
+struct b2RayCastOutput
+{
+	b2Vec2 normal;
+	float32 fraction;
+};
+
+/// An axis aligned bounding box.
+struct b2AABB
+{
+	/// Verify that the bounds are sorted.
+	bool IsValid() const;
+
+	/// Get the center of the AABB.
+	b2Vec2 GetCenter() const
+	{
+		return 0.5f * (lowerBound + upperBound);
+	}
+
+	/// Get the extents of the AABB (half-widths).
+	b2Vec2 GetExtents() const
+	{
+		return 0.5f * (upperBound - lowerBound);
+	}
+
+	/// Get the perimeter length
+	float32 GetPerimeter() const
+	{
+		float32 wx = upperBound.x - lowerBound.x;
+		float32 wy = upperBound.y - lowerBound.y;
+		return 2.0f * (wx + wy);
+	}
+
+	/// Combine an AABB into this one.
+	void Combine(const b2AABB& aabb)
+	{
+		lowerBound = b2Min(lowerBound, aabb.lowerBound);
+		upperBound = b2Max(upperBound, aabb.upperBound);
+	}
+
+	/// Combine two AABBs into this one.
+	void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
+	{
+		lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
+		upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
+	}
+
+	/// Does this aabb contain the provided AABB.
+	bool Contains(const b2AABB& aabb) const
+	{
+		bool result = true;
+		result = result && lowerBound.x <= aabb.lowerBound.x;
+		result = result && lowerBound.y <= aabb.lowerBound.y;
+		result = result && aabb.upperBound.x <= upperBound.x;
+		result = result && aabb.upperBound.y <= upperBound.y;
+		return result;
+	}
+
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
+
+	b2Vec2 lowerBound;	///< the lower vertex
+	b2Vec2 upperBound;	///< the upper vertex
+};
+
+/// Compute the collision manifold between two circles.
+void b2CollideCircles(b2Manifold* manifold,
+					  const b2CircleShape* circleA, const b2Transform& xfA,
+					  const b2CircleShape* circleB, const b2Transform& xfB);
+
+/// Compute the collision manifold between a polygon and a circle.
+void b2CollidePolygonAndCircle(b2Manifold* manifold,
+							   const b2PolygonShape* polygonA, const b2Transform& xfA,
+							   const b2CircleShape* circleB, const b2Transform& xfB);
+
+/// Compute the collision manifold between two polygons.
+void b2CollidePolygons(b2Manifold* manifold,
+					   const b2PolygonShape* polygonA, const b2Transform& xfA,
+					   const b2PolygonShape* polygonB, const b2Transform& xfB);
+
+/// Compute the collision manifold between an edge and a circle.
+void b2CollideEdgeAndCircle(b2Manifold* manifold,
+							   const b2EdgeShape* polygonA, const b2Transform& xfA,
+							   const b2CircleShape* circleB, const b2Transform& xfB);
+
+/// Compute the collision manifold between an edge and a circle.
+void b2CollideEdgeAndPolygon(b2Manifold* manifold,
+							   const b2EdgeShape* edgeA, const b2Transform& xfA,
+							   const b2PolygonShape* circleB, const b2Transform& xfB);
+
+/// Clipping for contact manifolds.
+int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],
+							const b2Vec2& normal, float32 offset, int32 vertexIndexA);
+
+/// Determine if two generic shapes overlap.
+bool b2TestOverlap(	const b2Shape* shapeA, int32 indexA,
+					const b2Shape* shapeB, int32 indexB,
+					const b2Transform& xfA, const b2Transform& xfB);
+
+// ---------------- Inline Functions ------------------------------------------
+
+inline bool b2AABB::IsValid() const
+{
+	b2Vec2 d = upperBound - lowerBound;
+	bool valid = d.x >= 0.0f && d.y >= 0.0f;
+	valid = valid && lowerBound.IsValid() && upperBound.IsValid();
+	return valid;
+}
+
+inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
+{
+	b2Vec2 d1, d2;
+	d1 = b.lowerBound - a.upperBound;
+	d2 = a.lowerBound - b.upperBound;
+
+	if (d1.x > 0.0f || d1.y > 0.0f)
+		return false;
+
+	if (d2.x > 0.0f || d2.y > 0.0f)
+		return false;
+
+	return true;
+}
+
+#endif

+ 614 - 603
engine/source/Box2D/Collision/b2Distance.cpp

@@ -1,603 +1,614 @@
-/*
-* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2Distance.h>
-#include <Box2D/Collision/Shapes/b2CircleShape.h>
-#include <Box2D/Collision/Shapes/b2EdgeShape.h>
-#include <Box2D/Collision/Shapes/b2ChainShape.h>
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-
-// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.
-int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
-
-void b2DistanceProxy::Set(const b2Shape* shape, int32 index)
-{
-	switch (shape->GetType())
-	{
-	case b2Shape::e_circle:
-		{
-			const b2CircleShape* circle = (b2CircleShape*)shape;
-			m_vertices = &circle->m_p;
-			m_count = 1;
-			m_radius = circle->m_radius;
-		}
-		break;
-
-	case b2Shape::e_polygon:
-		{
-			const b2PolygonShape* polygon = (b2PolygonShape*)shape;
-			m_vertices = polygon->m_vertices;
-			m_count = polygon->m_count;
-			m_radius = polygon->m_radius;
-		}
-		break;
-
-	case b2Shape::e_chain:
-		{
-			const b2ChainShape* chain = (b2ChainShape*)shape;
-			b2Assert(0 <= index && index < chain->m_count);
-
-			m_buffer[0] = chain->m_vertices[index];
-			if (index + 1 < chain->m_count)
-			{
-				m_buffer[1] = chain->m_vertices[index + 1];
-			}
-			else
-			{
-				m_buffer[1] = chain->m_vertices[0];
-			}
-
-			m_vertices = m_buffer;
-			m_count = 2;
-			m_radius = chain->m_radius;
-		}
-		break;
-
-	case b2Shape::e_edge:
-		{
-			const b2EdgeShape* edge = (b2EdgeShape*)shape;
-			m_vertices = &edge->m_vertex1;
-			m_count = 2;
-			m_radius = edge->m_radius;
-		}
-		break;
-
-	default:
-		b2Assert(false);
-	}
-}
-
-
-struct b2SimplexVertex
-{
-	b2Vec2 wA;		// support point in proxyA
-	b2Vec2 wB;		// support point in proxyB
-	b2Vec2 w;		// wB - wA
-	float32 a;		// barycentric coordinate for closest point
-	int32 indexA;	// wA index
-	int32 indexB;	// wB index
-};
-
-struct b2Simplex
-{
-	void ReadCache(	const b2SimplexCache* cache,
-					const b2DistanceProxy* proxyA, const b2Transform& transformA,
-					const b2DistanceProxy* proxyB, const b2Transform& transformB)
-	{
-		b2Assert(cache->count <= 3);
-		
-		// Copy data from cache.
-		m_count = cache->count;
-		b2SimplexVertex* vertices = &m_v1;
-		for (int32 i = 0; i < m_count; ++i)
-		{
-			b2SimplexVertex* v = vertices + i;
-			v->indexA = cache->indexA[i];
-			v->indexB = cache->indexB[i];
-			b2Vec2 wALocal = proxyA->GetVertex(v->indexA);
-			b2Vec2 wBLocal = proxyB->GetVertex(v->indexB);
-			v->wA = b2Mul(transformA, wALocal);
-			v->wB = b2Mul(transformB, wBLocal);
-			v->w = v->wB - v->wA;
-			v->a = 0.0f;
-		}
-
-		// Compute the new simplex metric, if it is substantially different than
-		// old metric then flush the simplex.
-		if (m_count > 1)
-		{
-			float32 metric1 = cache->metric;
-			float32 metric2 = GetMetric();
-			if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon)
-			{
-				// Reset the simplex.
-				m_count = 0;
-			}
-		}
-
-		// If the cache is empty or invalid ...
-		if (m_count == 0)
-		{
-			b2SimplexVertex* v = vertices + 0;
-			v->indexA = 0;
-			v->indexB = 0;
-			b2Vec2 wALocal = proxyA->GetVertex(0);
-			b2Vec2 wBLocal = proxyB->GetVertex(0);
-			v->wA = b2Mul(transformA, wALocal);
-			v->wB = b2Mul(transformB, wBLocal);
-			v->w = v->wB - v->wA;
-			v->a = 1.0f;
-			m_count = 1;
-		}
-	}
-
-	void WriteCache(b2SimplexCache* cache) const
-	{
-		cache->metric = GetMetric();
-		cache->count = uint16(m_count);
-		const b2SimplexVertex* vertices = &m_v1;
-		for (int32 i = 0; i < m_count; ++i)
-		{
-			cache->indexA[i] = uint8(vertices[i].indexA);
-			cache->indexB[i] = uint8(vertices[i].indexB);
-		}
-	}
-
-	b2Vec2 GetSearchDirection() const
-	{
-		switch (m_count)
-		{
-		case 1:
-			return -m_v1.w;
-
-		case 2:
-			{
-				b2Vec2 e12 = m_v2.w - m_v1.w;
-				float32 sgn = b2Cross(e12, -m_v1.w);
-				if (sgn > 0.0f)
-				{
-					// Origin is left of e12.
-					return b2Cross(1.0f, e12);
-				}
-				else
-				{
-					// Origin is right of e12.
-					return b2Cross(e12, 1.0f);
-				}
-			}
-
-		default:
-			b2Assert(false);
-			return b2Vec2_zero;
-		}
-	}
-
-	b2Vec2 GetClosestPoint() const
-	{
-		switch (m_count)
-		{
-		case 0:
-			b2Assert(false);
-			return b2Vec2_zero;
-
-		case 1:
-			return m_v1.w;
-
-		case 2:
-			return m_v1.a * m_v1.w + m_v2.a * m_v2.w;
-
-		case 3:
-			return b2Vec2_zero;
-
-		default:
-			b2Assert(false);
-			return b2Vec2_zero;
-		}
-	}
-
-	void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const
-	{
-		switch (m_count)
-		{
-		case 0:
-			b2Assert(false);
-			break;
-
-		case 1:
-			*pA = m_v1.wA;
-			*pB = m_v1.wB;
-			break;
-
-		case 2:
-			*pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA;
-			*pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB;
-			break;
-
-		case 3:
-			*pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA;
-			*pB = *pA;
-			break;
-
-		default:
-			b2Assert(false);
-			break;
-		}
-	}
-
-	float32 GetMetric() const
-	{
-		switch (m_count)
-		{
-		case 0:
-			b2Assert(false);
-			return 0.0f;
-
-		case 1:
-			return 0.0f;
-
-		case 2:
-			return b2Distance(m_v1.w, m_v2.w);
-
-		case 3:
-			return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w);
-
-		default:
-			b2Assert(false);
-			return 0.0f;
-		}
-	}
-
-	void Solve2();
-	void Solve3();
-
-	b2SimplexVertex m_v1, m_v2, m_v3;
-	int32 m_count;
-};
-
-
-// Solve a line segment using barycentric coordinates.
-//
-// p = a1 * w1 + a2 * w2
-// a1 + a2 = 1
-//
-// The vector from the origin to the closest point on the line is
-// perpendicular to the line.
-// e12 = w2 - w1
-// dot(p, e) = 0
-// a1 * dot(w1, e) + a2 * dot(w2, e) = 0
-//
-// 2-by-2 linear system
-// [1      1     ][a1] = [1]
-// [w1.e12 w2.e12][a2] = [0]
-//
-// Define
-// d12_1 =  dot(w2, e12)
-// d12_2 = -dot(w1, e12)
-// d12 = d12_1 + d12_2
-//
-// Solution
-// a1 = d12_1 / d12
-// a2 = d12_2 / d12
-void b2Simplex::Solve2()
-{
-	b2Vec2 w1 = m_v1.w;
-	b2Vec2 w2 = m_v2.w;
-	b2Vec2 e12 = w2 - w1;
-
-	// w1 region
-	float32 d12_2 = -b2Dot(w1, e12);
-	if (d12_2 <= 0.0f)
-	{
-		// a2 <= 0, so we clamp it to 0
-		m_v1.a = 1.0f;
-		m_count = 1;
-		return;
-	}
-
-	// w2 region
-	float32 d12_1 = b2Dot(w2, e12);
-	if (d12_1 <= 0.0f)
-	{
-		// a1 <= 0, so we clamp it to 0
-		m_v2.a = 1.0f;
-		m_count = 1;
-		m_v1 = m_v2;
-		return;
-	}
-
-	// Must be in e12 region.
-	float32 inv_d12 = 1.0f / (d12_1 + d12_2);
-	m_v1.a = d12_1 * inv_d12;
-	m_v2.a = d12_2 * inv_d12;
-	m_count = 2;
-}
-
-// Possible regions:
-// - points[2]
-// - edge points[0]-points[2]
-// - edge points[1]-points[2]
-// - inside the triangle
-void b2Simplex::Solve3()
-{
-	b2Vec2 w1 = m_v1.w;
-	b2Vec2 w2 = m_v2.w;
-	b2Vec2 w3 = m_v3.w;
-
-	// Edge12
-	// [1      1     ][a1] = [1]
-	// [w1.e12 w2.e12][a2] = [0]
-	// a3 = 0
-	b2Vec2 e12 = w2 - w1;
-	float32 w1e12 = b2Dot(w1, e12);
-	float32 w2e12 = b2Dot(w2, e12);
-	float32 d12_1 = w2e12;
-	float32 d12_2 = -w1e12;
-
-	// Edge13
-	// [1      1     ][a1] = [1]
-	// [w1.e13 w3.e13][a3] = [0]
-	// a2 = 0
-	b2Vec2 e13 = w3 - w1;
-	float32 w1e13 = b2Dot(w1, e13);
-	float32 w3e13 = b2Dot(w3, e13);
-	float32 d13_1 = w3e13;
-	float32 d13_2 = -w1e13;
-
-	// Edge23
-	// [1      1     ][a2] = [1]
-	// [w2.e23 w3.e23][a3] = [0]
-	// a1 = 0
-	b2Vec2 e23 = w3 - w2;
-	float32 w2e23 = b2Dot(w2, e23);
-	float32 w3e23 = b2Dot(w3, e23);
-	float32 d23_1 = w3e23;
-	float32 d23_2 = -w2e23;
-	
-	// Triangle123
-	float32 n123 = b2Cross(e12, e13);
-
-	float32 d123_1 = n123 * b2Cross(w2, w3);
-	float32 d123_2 = n123 * b2Cross(w3, w1);
-	float32 d123_3 = n123 * b2Cross(w1, w2);
-
-	// w1 region
-	if (d12_2 <= 0.0f && d13_2 <= 0.0f)
-	{
-		m_v1.a = 1.0f;
-		m_count = 1;
-		return;
-	}
-
-	// e12
-	if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f)
-	{
-		float32 inv_d12 = 1.0f / (d12_1 + d12_2);
-		m_v1.a = d12_1 * inv_d12;
-		m_v2.a = d12_2 * inv_d12;
-		m_count = 2;
-		return;
-	}
-
-	// e13
-	if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f)
-	{
-		float32 inv_d13 = 1.0f / (d13_1 + d13_2);
-		m_v1.a = d13_1 * inv_d13;
-		m_v3.a = d13_2 * inv_d13;
-		m_count = 2;
-		m_v2 = m_v3;
-		return;
-	}
-
-	// w2 region
-	if (d12_1 <= 0.0f && d23_2 <= 0.0f)
-	{
-		m_v2.a = 1.0f;
-		m_count = 1;
-		m_v1 = m_v2;
-		return;
-	}
-
-	// w3 region
-	if (d13_1 <= 0.0f && d23_1 <= 0.0f)
-	{
-		m_v3.a = 1.0f;
-		m_count = 1;
-		m_v1 = m_v3;
-		return;
-	}
-
-	// e23
-	if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f)
-	{
-		float32 inv_d23 = 1.0f / (d23_1 + d23_2);
-		m_v2.a = d23_1 * inv_d23;
-		m_v3.a = d23_2 * inv_d23;
-		m_count = 2;
-		m_v1 = m_v3;
-		return;
-	}
-
-	// Must be in triangle123
-	float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3);
-	m_v1.a = d123_1 * inv_d123;
-	m_v2.a = d123_2 * inv_d123;
-	m_v3.a = d123_3 * inv_d123;
-	m_count = 3;
-}
-
-void b2Distance(b2DistanceOutput* output,
-				b2SimplexCache* cache,
-				const b2DistanceInput* input)
-{
-	++b2_gjkCalls;
-
-	const b2DistanceProxy* proxyA = &input->proxyA;
-	const b2DistanceProxy* proxyB = &input->proxyB;
-
-	b2Transform transformA = input->transformA;
-	b2Transform transformB = input->transformB;
-
-	// Initialize the simplex.
-	b2Simplex simplex;
-	simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);
-
-	// Get simplex vertices as an array.
-	b2SimplexVertex* vertices = &simplex.m_v1;
-	const int32 k_maxIters = 20;
-
-	// These store the vertices of the last simplex so that we
-	// can check for duplicates and prevent cycling.
-	int32 saveA[3], saveB[3];
-	int32 saveCount = 0;
-
-	float32 distanceSqr1 = b2_maxFloat;
-	float32 distanceSqr2 = distanceSqr1;
-
-	// Main iteration loop.
-	int32 iter = 0;
-	while (iter < k_maxIters)
-	{
-		// Copy simplex so we can identify duplicates.
-		saveCount = simplex.m_count;
-		for (int32 i = 0; i < saveCount; ++i)
-		{
-			saveA[i] = vertices[i].indexA;
-			saveB[i] = vertices[i].indexB;
-		}
-
-		switch (simplex.m_count)
-		{
-		case 1:
-			break;
-
-		case 2:
-			simplex.Solve2();
-			break;
-
-		case 3:
-			simplex.Solve3();
-			break;
-
-		default:
-			b2Assert(false);
-		}
-
-		// If we have 3 points, then the origin is in the corresponding triangle.
-		if (simplex.m_count == 3)
-		{
-			break;
-		}
-
-		// Compute closest point.
-		b2Vec2 p = simplex.GetClosestPoint();
-		distanceSqr2 = p.LengthSquared();
-
-		// Ensure progress
-		if (distanceSqr2 >= distanceSqr1)
-		{
-			//break;
-		}
-		distanceSqr1 = distanceSqr2;
-
-		// Get search direction.
-		b2Vec2 d = simplex.GetSearchDirection();
-
-		// Ensure the search direction is numerically fit.
-		if (d.LengthSquared() < b2_epsilon * b2_epsilon)
-		{
-			// The origin is probably contained by a line segment
-			// or triangle. Thus the shapes are overlapped.
-
-			// We can't return zero here even though there may be overlap.
-			// In case the simplex is a point, segment, or triangle it is difficult
-			// to determine if the origin is contained in the CSO or very close to it.
-			break;
-		}
-
-		// Compute a tentative new simplex vertex using support points.
-		b2SimplexVertex* vertex = vertices + simplex.m_count;
-		vertex->indexA = proxyA->GetSupport(b2MulT(transformA.q, -d));
-		vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA));
-		b2Vec2 wBLocal;
-		vertex->indexB = proxyB->GetSupport(b2MulT(transformB.q, d));
-		vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB));
-		vertex->w = vertex->wB - vertex->wA;
-
-		// Iteration count is equated to the number of support point calls.
-		++iter;
-		++b2_gjkIters;
-
-		// Check for duplicate support points. This is the main termination criteria.
-		bool duplicate = false;
-		for (int32 i = 0; i < saveCount; ++i)
-		{
-			if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i])
-			{
-				duplicate = true;
-				break;
-			}
-		}
-
-		// If we found a duplicate support point we must exit to avoid cycling.
-		if (duplicate)
-		{
-			break;
-		}
-
-		// New vertex is ok and needed.
-		++simplex.m_count;
-	}
-
-	b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter);
-
-	// Prepare output.
-	simplex.GetWitnessPoints(&output->pointA, &output->pointB);
-	output->distance = b2Distance(output->pointA, output->pointB);
-	output->iterations = iter;
-
-	// Cache the simplex.
-	simplex.WriteCache(cache);
-
-	// Apply radii if requested.
-	if (input->useRadii)
-	{
-		float32 rA = proxyA->m_radius;
-		float32 rB = proxyB->m_radius;
-
-		if (output->distance > rA + rB && output->distance > b2_epsilon)
-		{
-			// Shapes are still no overlapped.
-			// Move the witness points to the outer surface.
-			output->distance -= rA + rB;
-			b2Vec2 normal = output->pointB - output->pointA;
-			normal.Normalize();
-			output->pointA += rA * normal;
-			output->pointB -= rB * normal;
-		}
-		else
-		{
-			// Shapes are overlapped when radii are considered.
-			// Move the witness points to the middle.
-			b2Vec2 p = 0.5f * (output->pointA + output->pointB);
-			output->pointA = p;
-			output->pointB = p;
-			output->distance = 0.0f;
-		}
-	}
-}
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#include <string.h>
+#include <memory.h>
+
+#include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2EdgeShape.h>
+#include <Box2D/Collision/Shapes/b2ChainShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.
+int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;
+
+void b2DistanceProxy::Set(const b2Shape* shape, int32 index)
+{
+	switch (shape->GetType())
+	{
+	case b2Shape::e_circle:
+		{
+			const b2CircleShape* circle = static_cast<const b2CircleShape*>(shape);
+			m_vertices = &circle->m_p;
+			m_count = 1;
+			m_radius = circle->m_radius;
+		}
+		break;
+
+	case b2Shape::e_polygon:
+		{
+			const b2PolygonShape* polygon = static_cast<const b2PolygonShape*>(shape);
+			m_vertices = polygon->m_vertices;
+			m_count = polygon->m_count;
+			m_radius = polygon->m_radius;
+		}
+		break;
+
+	case b2Shape::e_chain:
+		{
+			const b2ChainShape* chain = static_cast<const b2ChainShape*>(shape);
+			b2Assert(0 <= index && index < chain->m_count);
+
+			m_buffer[0] = chain->m_vertices[index];
+			if (index + 1 < chain->m_count)
+			{
+				m_buffer[1] = chain->m_vertices[index + 1];
+			}
+			else
+			{
+				m_buffer[1] = chain->m_vertices[0];
+			}
+
+			m_vertices = m_buffer;
+			m_count = 2;
+			m_radius = chain->m_radius;
+		}
+		break;
+
+	case b2Shape::e_edge:
+		{
+			const b2EdgeShape* edge = static_cast<const b2EdgeShape*>(shape);
+			m_vertices = &edge->m_vertex1;
+			m_count = 2;
+			m_radius = edge->m_radius;
+		}
+		break;
+
+	default:
+		b2Assert(false);
+	}
+}
+
+
+struct b2SimplexVertex
+{
+	b2Vec2 wA;		// support point in proxyA
+	b2Vec2 wB;		// support point in proxyB
+	b2Vec2 w;		// wB - wA
+	float32 a;		// barycentric coordinate for closest point
+	int32 indexA;	// wA index
+	int32 indexB;	// wB index
+};
+
+struct b2Simplex
+{
+	void ReadCache(	const b2SimplexCache* cache,
+					const b2DistanceProxy* proxyA, const b2Transform& transformA,
+					const b2DistanceProxy* proxyB, const b2Transform& transformB)
+	{
+		b2Assert(cache->count <= 3);
+		
+		// Copy data from cache.
+		m_count = cache->count;
+		b2SimplexVertex* vertices = &m_v1;
+		for (int32 i = 0; i < m_count; ++i)
+		{
+			b2SimplexVertex* v = vertices + i;
+			v->indexA = cache->indexA[i];
+			v->indexB = cache->indexB[i];
+			b2Vec2 wALocal = proxyA->GetVertex(v->indexA);
+			b2Vec2 wBLocal = proxyB->GetVertex(v->indexB);
+			v->wA = b2Mul(transformA, wALocal);
+			v->wB = b2Mul(transformB, wBLocal);
+			v->w = v->wB - v->wA;
+			v->a = 0.0f;
+		}
+
+		// Compute the new simplex metric, if it is substantially different than
+		// old metric then flush the simplex.
+		if (m_count > 1)
+		{
+			float32 metric1 = cache->metric;
+			float32 metric2 = GetMetric();
+			if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon)
+			{
+				// Reset the simplex.
+				m_count = 0;
+			}
+		}
+
+		// If the cache is empty or invalid ...
+		if (m_count == 0)
+		{
+			b2SimplexVertex* v = vertices + 0;
+			v->indexA = 0;
+			v->indexB = 0;
+			b2Vec2 wALocal = proxyA->GetVertex(0);
+			b2Vec2 wBLocal = proxyB->GetVertex(0);
+			v->wA = b2Mul(transformA, wALocal);
+			v->wB = b2Mul(transformB, wBLocal);
+			v->w = v->wB - v->wA;
+			v->a = 1.0f;
+			m_count = 1;
+		}
+	}
+
+	void WriteCache(b2SimplexCache* cache) const
+	{
+		cache->metric = GetMetric();
+		cache->count = uint16(m_count);
+		const b2SimplexVertex* vertices = &m_v1;
+		for (int32 i = 0; i < m_count; ++i)
+		{
+			cache->indexA[i] = uint8(vertices[i].indexA);
+			cache->indexB[i] = uint8(vertices[i].indexB);
+		}
+	}
+
+	b2Vec2 GetSearchDirection() const
+	{
+		switch (m_count)
+		{
+		case 1:
+			return -m_v1.w;
+
+		case 2:
+			{
+				b2Vec2 e12 = m_v2.w - m_v1.w;
+				float32 sgn = b2Cross(e12, -m_v1.w);
+				if (sgn > 0.0f)
+				{
+					// Origin is left of e12.
+					return b2Cross(1.0f, e12);
+				}
+				else
+				{
+					// Origin is right of e12.
+					return b2Cross(e12, 1.0f);
+				}
+			}
+
+		default:
+			b2Assert(false);
+			return b2Vec2_zero;
+		}
+	}
+
+	b2Vec2 GetClosestPoint() const
+	{
+		switch (m_count)
+		{
+		case 0:
+			b2Assert(false);
+			return b2Vec2_zero;
+
+		case 1:
+			return m_v1.w;
+
+		case 2:
+			return m_v1.a * m_v1.w + m_v2.a * m_v2.w;
+
+		case 3:
+			return b2Vec2_zero;
+
+		default:
+			b2Assert(false);
+			return b2Vec2_zero;
+		}
+	}
+
+	void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const
+	{
+		switch (m_count)
+		{
+		case 0:
+			b2Assert(false);
+			break;
+
+		case 1:
+			*pA = m_v1.wA;
+			*pB = m_v1.wB;
+			break;
+
+		case 2:
+			*pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA;
+			*pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB;
+			break;
+
+		case 3:
+			*pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA;
+			*pB = *pA;
+			break;
+
+		default:
+			b2Assert(false);
+			break;
+		}
+	}
+
+	float32 GetMetric() const
+	{
+		switch (m_count)
+		{
+		case 0:
+			b2Assert(false);
+			return 0.0f;
+
+		case 1:
+			return 0.0f;
+
+		case 2:
+			return b2Distance(m_v1.w, m_v2.w);
+
+		case 3:
+			return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w);
+
+		default:
+			b2Assert(false);
+			return 0.0f;
+		}
+	}
+
+	void Solve2();
+	void Solve3();
+
+	b2SimplexVertex m_v1, m_v2, m_v3;
+	int32 m_count;
+};
+
+
+// Solve a line segment using barycentric coordinates.
+//
+// p = a1 * w1 + a2 * w2
+// a1 + a2 = 1
+//
+// The vector from the origin to the closest point on the line is
+// perpendicular to the line.
+// e12 = w2 - w1
+// dot(p, e) = 0
+// a1 * dot(w1, e) + a2 * dot(w2, e) = 0
+//
+// 2-by-2 linear system
+// [1      1     ][a1] = [1]
+// [w1.e12 w2.e12][a2] = [0]
+//
+// Define
+// d12_1 =  dot(w2, e12)
+// d12_2 = -dot(w1, e12)
+// d12 = d12_1 + d12_2
+//
+// Solution
+// a1 = d12_1 / d12
+// a2 = d12_2 / d12
+void b2Simplex::Solve2()
+{
+	b2Vec2 w1 = m_v1.w;
+	b2Vec2 w2 = m_v2.w;
+	b2Vec2 e12 = w2 - w1;
+
+	// w1 region
+	float32 d12_2 = -b2Dot(w1, e12);
+	if (d12_2 <= 0.0f)
+	{
+		// a2 <= 0, so we clamp it to 0
+		m_v1.a = 1.0f;
+		m_count = 1;
+		return;
+	}
+
+	// w2 region
+	float32 d12_1 = b2Dot(w2, e12);
+	if (d12_1 <= 0.0f)
+	{
+		// a1 <= 0, so we clamp it to 0
+		m_v2.a = 1.0f;
+		m_count = 1;
+		m_v1 = m_v2;
+		return;
+	}
+
+	// Must be in e12 region.
+	float32 inv_d12 = 1.0f / (d12_1 + d12_2);
+	m_v1.a = d12_1 * inv_d12;
+	m_v2.a = d12_2 * inv_d12;
+	m_count = 2;
+}
+
+// Possible regions:
+// - points[2]
+// - edge points[0]-points[2]
+// - edge points[1]-points[2]
+// - inside the triangle
+void b2Simplex::Solve3()
+{
+	b2Vec2 w1 = m_v1.w;
+	b2Vec2 w2 = m_v2.w;
+	b2Vec2 w3 = m_v3.w;
+
+	// Edge12
+	// [1      1     ][a1] = [1]
+	// [w1.e12 w2.e12][a2] = [0]
+	// a3 = 0
+	b2Vec2 e12 = w2 - w1;
+	float32 w1e12 = b2Dot(w1, e12);
+	float32 w2e12 = b2Dot(w2, e12);
+	float32 d12_1 = w2e12;
+	float32 d12_2 = -w1e12;
+
+	// Edge13
+	// [1      1     ][a1] = [1]
+	// [w1.e13 w3.e13][a3] = [0]
+	// a2 = 0
+	b2Vec2 e13 = w3 - w1;
+	float32 w1e13 = b2Dot(w1, e13);
+	float32 w3e13 = b2Dot(w3, e13);
+	float32 d13_1 = w3e13;
+	float32 d13_2 = -w1e13;
+
+	// Edge23
+	// [1      1     ][a2] = [1]
+	// [w2.e23 w3.e23][a3] = [0]
+	// a1 = 0
+	b2Vec2 e23 = w3 - w2;
+	float32 w2e23 = b2Dot(w2, e23);
+	float32 w3e23 = b2Dot(w3, e23);
+	float32 d23_1 = w3e23;
+	float32 d23_2 = -w2e23;
+	
+	// Triangle123
+	float32 n123 = b2Cross(e12, e13);
+
+	float32 d123_1 = n123 * b2Cross(w2, w3);
+	float32 d123_2 = n123 * b2Cross(w3, w1);
+	float32 d123_3 = n123 * b2Cross(w1, w2);
+
+	// w1 region
+	if (d12_2 <= 0.0f && d13_2 <= 0.0f)
+	{
+		m_v1.a = 1.0f;
+		m_count = 1;
+		return;
+	}
+
+	// e12
+	if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f)
+	{
+		float32 inv_d12 = 1.0f / (d12_1 + d12_2);
+		m_v1.a = d12_1 * inv_d12;
+		m_v2.a = d12_2 * inv_d12;
+		m_count = 2;
+		return;
+	}
+
+	// e13
+	if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f)
+	{
+		float32 inv_d13 = 1.0f / (d13_1 + d13_2);
+		m_v1.a = d13_1 * inv_d13;
+		m_v3.a = d13_2 * inv_d13;
+		m_count = 2;
+		m_v2 = m_v3;
+		return;
+	}
+
+	// w2 region
+	if (d12_1 <= 0.0f && d23_2 <= 0.0f)
+	{
+		m_v2.a = 1.0f;
+		m_count = 1;
+		m_v1 = m_v2;
+		return;
+	}
+
+	// w3 region
+	if (d13_1 <= 0.0f && d23_1 <= 0.0f)
+	{
+		m_v3.a = 1.0f;
+		m_count = 1;
+		m_v1 = m_v3;
+		return;
+	}
+
+	// e23
+	if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f)
+	{
+		float32 inv_d23 = 1.0f / (d23_1 + d23_2);
+		m_v2.a = d23_1 * inv_d23;
+		m_v3.a = d23_2 * inv_d23;
+		m_count = 2;
+		m_v1 = m_v3;
+		return;
+	}
+
+	// Must be in triangle123
+	float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3);
+	m_v1.a = d123_1 * inv_d123;
+	m_v2.a = d123_2 * inv_d123;
+	m_v3.a = d123_3 * inv_d123;
+	m_count = 3;
+}
+
+void b2Distance(b2DistanceOutput* output,
+				b2SimplexCache* cache,
+				const b2DistanceInput* input)
+{
+	++b2_gjkCalls;
+
+	const b2DistanceProxy* proxyA = &input->proxyA;
+	const b2DistanceProxy* proxyB = &input->proxyB;
+
+	b2Transform transformA = input->transformA;
+	b2Transform transformB = input->transformB;
+
+	// Initialize the simplex.
+	b2Simplex simplex;
+	simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);
+
+	// Get simplex vertices as an array.
+	b2SimplexVertex* vertices = &simplex.m_v1;
+	const int32 k_maxIters = 20;
+
+	// These store the vertices of the last simplex so that we
+	// can check for duplicates and prevent cycling.
+	int32 saveA[3], saveB[3];
+	int32 saveCount = 0;
+
+	// Work around spurious gcc-4.8.2 warnings when -Wmaybe-uninitialized is
+	// enabled by initializing saveA / saveB arrays when they're referenced
+	// at the end of the main iteration loop below even though saveCount
+	// entries of each array are initialized at the start of the main
+	// iteration loop.
+	memset(saveA, 0, sizeof(saveA));
+	memset(saveB, 0, sizeof(saveB));
+
+	float32 distanceSqr1 = b2_maxFloat;
+	float32 distanceSqr2;
+
+	// Main iteration loop.
+	int32 iter = 0;
+	while (iter < k_maxIters)
+	{
+		// Copy simplex so we can identify duplicates.
+		saveCount = simplex.m_count;
+		for (int32 i = 0; i < saveCount; ++i)
+		{
+			saveA[i] = vertices[i].indexA;
+			saveB[i] = vertices[i].indexB;
+		}
+
+		switch (simplex.m_count)
+		{
+		case 1:
+			break;
+
+		case 2:
+			simplex.Solve2();
+			break;
+
+		case 3:
+			simplex.Solve3();
+			break;
+
+		default:
+			b2Assert(false);
+		}
+
+		// If we have 3 points, then the origin is in the corresponding triangle.
+		if (simplex.m_count == 3)
+		{
+			break;
+		}
+
+		// Compute closest point.
+		b2Vec2 p = simplex.GetClosestPoint();
+		distanceSqr2 = p.LengthSquared();
+
+		// Ensure progress
+		if (distanceSqr2 >= distanceSqr1)
+		{
+			//break;
+		}
+		distanceSqr1 = distanceSqr2;
+
+		// Get search direction.
+		b2Vec2 d = simplex.GetSearchDirection();
+
+		// Ensure the search direction is numerically fit.
+		if (d.LengthSquared() < b2_epsilon * b2_epsilon)
+		{
+			// The origin is probably contained by a line segment
+			// or triangle. Thus the shapes are overlapped.
+
+			// We can't return zero here even though there may be overlap.
+			// In case the simplex is a point, segment, or triangle it is difficult
+			// to determine if the origin is contained in the CSO or very close to it.
+			break;
+		}
+
+		// Compute a tentative new simplex vertex using support points.
+		b2SimplexVertex* vertex = vertices + simplex.m_count;
+		vertex->indexA = proxyA->GetSupport(b2MulT(transformA.q, -d));
+		vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA));
+		b2Vec2 wBLocal;
+		vertex->indexB = proxyB->GetSupport(b2MulT(transformB.q, d));
+		vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB));
+		vertex->w = vertex->wB - vertex->wA;
+
+		// Iteration count is equated to the number of support point calls.
+		++iter;
+		++b2_gjkIters;
+
+		// Check for duplicate support points. This is the main termination criteria.
+		bool duplicate = false;
+		for (int32 i = 0; i < saveCount; ++i)
+		{
+			if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i])
+			{
+				duplicate = true;
+				break;
+			}
+		}
+
+		// If we found a duplicate support point we must exit to avoid cycling.
+		if (duplicate)
+		{
+			break;
+		}
+
+		// New vertex is ok and needed.
+		++simplex.m_count;
+	}
+
+	b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter);
+
+	// Prepare output.
+	simplex.GetWitnessPoints(&output->pointA, &output->pointB);
+	output->distance = b2Distance(output->pointA, output->pointB);
+	output->iterations = iter;
+
+	// Cache the simplex.
+	simplex.WriteCache(cache);
+
+	// Apply radii if requested.
+	if (input->useRadii)
+	{
+		float32 rA = proxyA->m_radius;
+		float32 rB = proxyB->m_radius;
+
+		if (output->distance > rA + rB && output->distance > b2_epsilon)
+		{
+			// Shapes are still no overlapped.
+			// Move the witness points to the outer surface.
+			output->distance -= rA + rB;
+			b2Vec2 normal = output->pointB - output->pointA;
+			normal.Normalize();
+			output->pointA += rA * normal;
+			output->pointB -= rB * normal;
+		}
+		else
+		{
+			// Shapes are overlapped when radii are considered.
+			// Move the witness points to the middle.
+			b2Vec2 p = 0.5f * (output->pointA + output->pointB);
+			output->pointA = p;
+			output->pointB = p;
+			output->distance = 0.0f;
+		}
+	}
+}

+ 141 - 141
engine/source/Box2D/Collision/b2Distance.h

@@ -1,141 +1,141 @@
-
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_DISTANCE_H
-#define B2_DISTANCE_H
-
-#include <Box2D/Common/b2Math.h>
-
-class b2Shape;
-
-/// A distance proxy is used by the GJK algorithm.
-/// It encapsulates any shape.
-struct b2DistanceProxy
-{
-	b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {}
-
-	/// Initialize the proxy using the given shape. The shape
-	/// must remain in scope while the proxy is in use.
-	void Set(const b2Shape* shape, int32 index);
-
-	/// Get the supporting vertex index in the given direction.
-	int32 GetSupport(const b2Vec2& d) const;
-
-	/// Get the supporting vertex in the given direction.
-	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
-
-	/// Get the vertex count.
-	int32 GetVertexCount() const;
-
-	/// Get a vertex by index. Used by b2Distance.
-	const b2Vec2& GetVertex(int32 index) const;
-
-	b2Vec2 m_buffer[2];
-	const b2Vec2* m_vertices;
-	int32 m_count;
-	float32 m_radius;
-};
-
-/// Used to warm start b2Distance.
-/// Set count to zero on first call.
-struct b2SimplexCache
-{
-	float32 metric;		///< length or area
-	uint16 count;
-	uint8 indexA[3];	///< vertices on shape A
-	uint8 indexB[3];	///< vertices on shape B
-};
-
-/// Input for b2Distance.
-/// You have to option to use the shape radii
-/// in the computation. Even 
-struct b2DistanceInput
-{
-	b2DistanceProxy proxyA;
-	b2DistanceProxy proxyB;
-	b2Transform transformA;
-	b2Transform transformB;
-	bool useRadii;
-};
-
-/// Output for b2Distance.
-struct b2DistanceOutput
-{
-	b2Vec2 pointA;		///< closest point on shapeA
-	b2Vec2 pointB;		///< closest point on shapeB
-	float32 distance;
-	int32 iterations;	///< number of GJK iterations used
-};
-
-/// Compute the closest points between two shapes. Supports any combination of:
-/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.
-/// On the first call set b2SimplexCache.count to zero.
-void b2Distance(b2DistanceOutput* output,
-				b2SimplexCache* cache, 
-				const b2DistanceInput* input);
-
-
-//////////////////////////////////////////////////////////////////////////
-
-inline int32 b2DistanceProxy::GetVertexCount() const
-{
-	return m_count;
-}
-
-inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const
-{
-	b2Assert(0 <= index && index < m_count);
-	return m_vertices[index];
-}
-
-inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const
-{
-	int32 bestIndex = 0;
-	float32 bestValue = b2Dot(m_vertices[0], d);
-	for (int32 i = 1; i < m_count; ++i)
-	{
-		float32 value = b2Dot(m_vertices[i], d);
-		if (value > bestValue)
-		{
-			bestIndex = i;
-			bestValue = value;
-		}
-	}
-
-	return bestIndex;
-}
-
-inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const
-{
-	int32 bestIndex = 0;
-	float32 bestValue = b2Dot(m_vertices[0], d);
-	for (int32 i = 1; i < m_count; ++i)
-	{
-		float32 value = b2Dot(m_vertices[i], d);
-		if (value > bestValue)
-		{
-			bestIndex = i;
-			bestValue = value;
-		}
-	}
-
-	return m_vertices[bestIndex];
-}
-
-#endif
+
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_DISTANCE_H
+#define B2_DISTANCE_H
+
+#include <Box2D/Common/b2Math.h>
+
+class b2Shape;
+
+/// A distance proxy is used by the GJK algorithm.
+/// It encapsulates any shape.
+struct b2DistanceProxy
+{
+	b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {}
+
+	/// Initialize the proxy using the given shape. The shape
+	/// must remain in scope while the proxy is in use.
+	void Set(const b2Shape* shape, int32 index);
+
+	/// Get the supporting vertex index in the given direction.
+	int32 GetSupport(const b2Vec2& d) const;
+
+	/// Get the supporting vertex in the given direction.
+	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const;
+
+	/// Get a vertex by index. Used by b2Distance.
+	const b2Vec2& GetVertex(int32 index) const;
+
+	b2Vec2 m_buffer[2];
+	const b2Vec2* m_vertices;
+	int32 m_count;
+	float32 m_radius;
+};
+
+/// Used to warm start b2Distance.
+/// Set count to zero on first call.
+struct b2SimplexCache
+{
+	float32 metric;		///< length or area
+	uint16 count;
+	uint8 indexA[3];	///< vertices on shape A
+	uint8 indexB[3];	///< vertices on shape B
+};
+
+/// Input for b2Distance.
+/// You have to option to use the shape radii
+/// in the computation. Even 
+struct b2DistanceInput
+{
+	b2DistanceProxy proxyA;
+	b2DistanceProxy proxyB;
+	b2Transform transformA;
+	b2Transform transformB;
+	bool useRadii;
+};
+
+/// Output for b2Distance.
+struct b2DistanceOutput
+{
+	b2Vec2 pointA;		///< closest point on shapeA
+	b2Vec2 pointB;		///< closest point on shapeB
+	float32 distance;
+	int32 iterations;	///< number of GJK iterations used
+};
+
+/// Compute the closest points between two shapes. Supports any combination of:
+/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.
+/// On the first call set b2SimplexCache.count to zero.
+void b2Distance(b2DistanceOutput* output,
+				b2SimplexCache* cache, 
+				const b2DistanceInput* input);
+
+
+//////////////////////////////////////////////////////////////////////////
+
+inline int32 b2DistanceProxy::GetVertexCount() const
+{
+	return m_count;
+}
+
+inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const
+{
+	b2Assert(0 <= index && index < m_count);
+	return m_vertices[index];
+}
+
+inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const
+{
+	int32 bestIndex = 0;
+	float32 bestValue = b2Dot(m_vertices[0], d);
+	for (int32 i = 1; i < m_count; ++i)
+	{
+		float32 value = b2Dot(m_vertices[i], d);
+		if (value > bestValue)
+		{
+			bestIndex = i;
+			bestValue = value;
+		}
+	}
+
+	return bestIndex;
+}
+
+inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const
+{
+	int32 bestIndex = 0;
+	float32 bestValue = b2Dot(m_vertices[0], d);
+	for (int32 i = 1; i < m_count; ++i)
+	{
+		float32 value = b2Dot(m_vertices[i], d);
+		if (value > bestValue)
+		{
+			bestIndex = i;
+			bestValue = value;
+		}
+	}
+
+	return m_vertices[bestIndex];
+}
+
+#endif

+ 784 - 781
engine/source/Box2D/Collision/b2DynamicTree.cpp

@@ -1,781 +1,784 @@
-/*
-* Copyright (c) 2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2DynamicTree.h>
-#include <cstring>
-#include <cfloat>
-using namespace std;
-
-
-b2DynamicTree::b2DynamicTree()
-{
-	m_root = b2_nullNode;
-
-	m_nodeCapacity = 16;
-	m_nodeCount = 0;
-	m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
-	memset(m_nodes, 0, m_nodeCapacity * sizeof(b2TreeNode));
-
-	// Build a linked list for the free list.
-	for (int32 i = 0; i < m_nodeCapacity - 1; ++i)
-	{
-		m_nodes[i].next = i + 1;
-		m_nodes[i].height = -1;
-	}
-	m_nodes[m_nodeCapacity-1].next = b2_nullNode;
-	m_nodes[m_nodeCapacity-1].height = -1;
-	m_freeList = 0;
-
-	m_path = 0;
-
-	m_insertionCount = 0;
-}
-
-b2DynamicTree::~b2DynamicTree()
-{
-	// This frees the entire tree in one shot.
-	b2Free(m_nodes);
-}
-
-// Allocate a node from the pool. Grow the pool if necessary.
-int32 b2DynamicTree::AllocateNode()
-{
-	// Expand the node pool as needed.
-	if (m_freeList == b2_nullNode)
-	{
-		b2Assert(m_nodeCount == m_nodeCapacity);
-
-		// The free list is empty. Rebuild a bigger pool.
-		b2TreeNode* oldNodes = m_nodes;
-		m_nodeCapacity *= 2;
-		m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
-		memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2TreeNode));
-		b2Free(oldNodes);
-
-		// Build a linked list for the free list. The parent
-		// pointer becomes the "next" pointer.
-		for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i)
-		{
-			m_nodes[i].next = i + 1;
-			m_nodes[i].height = -1;
-		}
-		m_nodes[m_nodeCapacity-1].next = b2_nullNode;
-		m_nodes[m_nodeCapacity-1].height = -1;
-		m_freeList = m_nodeCount;
-	}
-
-	// Peel a node off the free list.
-	int32 nodeId = m_freeList;
-	m_freeList = m_nodes[nodeId].next;
-	m_nodes[nodeId].parent = b2_nullNode;
-	m_nodes[nodeId].child1 = b2_nullNode;
-	m_nodes[nodeId].child2 = b2_nullNode;
-	m_nodes[nodeId].height = 0;
-	m_nodes[nodeId].userData = NULL;
-	++m_nodeCount;
-	return nodeId;
-}
-
-// Return a node to the pool.
-void b2DynamicTree::FreeNode(int32 nodeId)
-{
-	b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
-	b2Assert(0 < m_nodeCount);
-	m_nodes[nodeId].next = m_freeList;
-	m_nodes[nodeId].height = -1;
-	m_freeList = nodeId;
-	--m_nodeCount;
-}
-
-// Create a proxy in the tree as a leaf node. We return the index
-// of the node instead of a pointer so that we can grow
-// the node pool.
-int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
-{
-	int32 proxyId = AllocateNode();
-
-	// Fatten the aabb.
-	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
-	m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
-	m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
-	m_nodes[proxyId].userData = userData;
-	m_nodes[proxyId].height = 0;
-
-	InsertLeaf(proxyId);
-
-	return proxyId;
-}
-
-void b2DynamicTree::DestroyProxy(int32 proxyId)
-{
-	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
-	b2Assert(m_nodes[proxyId].IsLeaf());
-
-	RemoveLeaf(proxyId);
-	FreeNode(proxyId);
-}
-
-bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
-{
-	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
-
-	b2Assert(m_nodes[proxyId].IsLeaf());
-
-	if (m_nodes[proxyId].aabb.Contains(aabb))
-	{
-		return false;
-	}
-
-	RemoveLeaf(proxyId);
-
-	// Extend AABB.
-	b2AABB b = aabb;
-	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
-	b.lowerBound = b.lowerBound - r;
-	b.upperBound = b.upperBound + r;
-
-	// Predict AABB displacement.
-	b2Vec2 d = b2_aabbMultiplier * displacement;
-
-	if (d.x < 0.0f)
-	{
-		b.lowerBound.x += d.x;
-	}
-	else
-	{
-		b.upperBound.x += d.x;
-	}
-
-	if (d.y < 0.0f)
-	{
-		b.lowerBound.y += d.y;
-	}
-	else
-	{
-		b.upperBound.y += d.y;
-	}
-
-	m_nodes[proxyId].aabb = b;
-
-	InsertLeaf(proxyId);
-	return true;
-}
-
-void b2DynamicTree::InsertLeaf(int32 leaf)
-{
-	++m_insertionCount;
-
-	if (m_root == b2_nullNode)
-	{
-		m_root = leaf;
-		m_nodes[m_root].parent = b2_nullNode;
-		return;
-	}
-
-	// Find the best sibling for this node
-	b2AABB leafAABB = m_nodes[leaf].aabb;
-	int32 index = m_root;
-	while (m_nodes[index].IsLeaf() == false)
-	{
-		int32 child1 = m_nodes[index].child1;
-		int32 child2 = m_nodes[index].child2;
-
-		float32 area = m_nodes[index].aabb.GetPerimeter();
-
-		b2AABB combinedAABB;
-		combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
-		float32 combinedArea = combinedAABB.GetPerimeter();
-
-		// Cost of creating a new parent for this node and the new leaf
-		float32 cost = 2.0f * combinedArea;
-
-		// Minimum cost of pushing the leaf further down the tree
-		float32 inheritanceCost = 2.0f * (combinedArea - area);
-
-		// Cost of descending into child1
-		float32 cost1;
-		if (m_nodes[child1].IsLeaf())
-		{
-			b2AABB aabb;
-			aabb.Combine(leafAABB, m_nodes[child1].aabb);
-			cost1 = aabb.GetPerimeter() + inheritanceCost;
-		}
-		else
-		{
-			b2AABB aabb;
-			aabb.Combine(leafAABB, m_nodes[child1].aabb);
-			float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
-			float32 newArea = aabb.GetPerimeter();
-			cost1 = (newArea - oldArea) + inheritanceCost;
-		}
-
-		// Cost of descending into child2
-		float32 cost2;
-		if (m_nodes[child2].IsLeaf())
-		{
-			b2AABB aabb;
-			aabb.Combine(leafAABB, m_nodes[child2].aabb);
-			cost2 = aabb.GetPerimeter() + inheritanceCost;
-		}
-		else
-		{
-			b2AABB aabb;
-			aabb.Combine(leafAABB, m_nodes[child2].aabb);
-			float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
-			float32 newArea = aabb.GetPerimeter();
-			cost2 = newArea - oldArea + inheritanceCost;
-		}
-
-		// Descend according to the minimum cost.
-		if (cost < cost1 && cost < cost2)
-		{
-			break;
-		}
-
-		// Descend
-		if (cost1 < cost2)
-		{
-			index = child1;
-		}
-		else
-		{
-			index = child2;
-		}
-	}
-
-	int32 sibling = index;
-
-	// Create a new parent.
-	int32 oldParent = m_nodes[sibling].parent;
-	int32 newParent = AllocateNode();
-	m_nodes[newParent].parent = oldParent;
-	m_nodes[newParent].userData = NULL;
-	m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb);
-	m_nodes[newParent].height = m_nodes[sibling].height + 1;
-
-	if (oldParent != b2_nullNode)
-	{
-		// The sibling was not the root.
-		if (m_nodes[oldParent].child1 == sibling)
-		{
-			m_nodes[oldParent].child1 = newParent;
-		}
-		else
-		{
-			m_nodes[oldParent].child2 = newParent;
-		}
-
-		m_nodes[newParent].child1 = sibling;
-		m_nodes[newParent].child2 = leaf;
-		m_nodes[sibling].parent = newParent;
-		m_nodes[leaf].parent = newParent;
-	}
-	else
-	{
-		// The sibling was the root.
-		m_nodes[newParent].child1 = sibling;
-		m_nodes[newParent].child2 = leaf;
-		m_nodes[sibling].parent = newParent;
-		m_nodes[leaf].parent = newParent;
-		m_root = newParent;
-	}
-
-	// Walk back up the tree fixing heights and AABBs
-	index = m_nodes[leaf].parent;
-	while (index != b2_nullNode)
-	{
-		index = Balance(index);
-
-		int32 child1 = m_nodes[index].child1;
-		int32 child2 = m_nodes[index].child2;
-
-		b2Assert(child1 != b2_nullNode);
-		b2Assert(child2 != b2_nullNode);
-
-		m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
-		m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
-
-		index = m_nodes[index].parent;
-	}
-
-	//Validate();
-}
-
-void b2DynamicTree::RemoveLeaf(int32 leaf)
-{
-	if (leaf == m_root)
-	{
-		m_root = b2_nullNode;
-		return;
-	}
-
-	int32 parent = m_nodes[leaf].parent;
-	int32 grandParent = m_nodes[parent].parent;
-	int32 sibling;
-	if (m_nodes[parent].child1 == leaf)
-	{
-		sibling = m_nodes[parent].child2;
-	}
-	else
-	{
-		sibling = m_nodes[parent].child1;
-	}
-
-	if (grandParent != b2_nullNode)
-	{
-		// Destroy parent and connect sibling to grandParent.
-		if (m_nodes[grandParent].child1 == parent)
-		{
-			m_nodes[grandParent].child1 = sibling;
-		}
-		else
-		{
-			m_nodes[grandParent].child2 = sibling;
-		}
-		m_nodes[sibling].parent = grandParent;
-		FreeNode(parent);
-
-		// Adjust ancestor bounds.
-		int32 index = grandParent;
-		while (index != b2_nullNode)
-		{
-			index = Balance(index);
-
-			int32 child1 = m_nodes[index].child1;
-			int32 child2 = m_nodes[index].child2;
-
-			m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
-			m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
-
-			index = m_nodes[index].parent;
-		}
-	}
-	else
-	{
-		m_root = sibling;
-		m_nodes[sibling].parent = b2_nullNode;
-		FreeNode(parent);
-	}
-
-	//Validate();
-}
-
-// Perform a left or right rotation if node A is imbalanced.
-// Returns the new root index.
-int32 b2DynamicTree::Balance(int32 iA)
-{
-	b2Assert(iA != b2_nullNode);
-
-	b2TreeNode* A = m_nodes + iA;
-	if (A->IsLeaf() || A->height < 2)
-	{
-		return iA;
-	}
-
-	int32 iB = A->child1;
-	int32 iC = A->child2;
-	b2Assert(0 <= iB && iB < m_nodeCapacity);
-	b2Assert(0 <= iC && iC < m_nodeCapacity);
-
-	b2TreeNode* B = m_nodes + iB;
-	b2TreeNode* C = m_nodes + iC;
-
-	int32 balance = C->height - B->height;
-
-	// Rotate C up
-	if (balance > 1)
-	{
-		int32 iF = C->child1;
-		int32 iG = C->child2;
-		b2TreeNode* F = m_nodes + iF;
-		b2TreeNode* G = m_nodes + iG;
-		b2Assert(0 <= iF && iF < m_nodeCapacity);
-		b2Assert(0 <= iG && iG < m_nodeCapacity);
-
-		// Swap A and C
-		C->child1 = iA;
-		C->parent = A->parent;
-		A->parent = iC;
-
-		// A's old parent should point to C
-		if (C->parent != b2_nullNode)
-		{
-			if (m_nodes[C->parent].child1 == iA)
-			{
-				m_nodes[C->parent].child1 = iC;
-			}
-			else
-			{
-				b2Assert(m_nodes[C->parent].child2 == iA);
-				m_nodes[C->parent].child2 = iC;
-			}
-		}
-		else
-		{
-			m_root = iC;
-		}
-
-		// Rotate
-		if (F->height > G->height)
-		{
-			C->child2 = iF;
-			A->child2 = iG;
-			G->parent = iA;
-			A->aabb.Combine(B->aabb, G->aabb);
-			C->aabb.Combine(A->aabb, F->aabb);
-
-			A->height = 1 + b2Max(B->height, G->height);
-			C->height = 1 + b2Max(A->height, F->height);
-		}
-		else
-		{
-			C->child2 = iG;
-			A->child2 = iF;
-			F->parent = iA;
-			A->aabb.Combine(B->aabb, F->aabb);
-			C->aabb.Combine(A->aabb, G->aabb);
-
-			A->height = 1 + b2Max(B->height, F->height);
-			C->height = 1 + b2Max(A->height, G->height);
-		}
-
-		return iC;
-	}
-	
-	// Rotate B up
-	if (balance < -1)
-	{
-		int32 iD = B->child1;
-		int32 iE = B->child2;
-		b2TreeNode* D = m_nodes + iD;
-		b2TreeNode* E = m_nodes + iE;
-		b2Assert(0 <= iD && iD < m_nodeCapacity);
-		b2Assert(0 <= iE && iE < m_nodeCapacity);
-
-		// Swap A and B
-		B->child1 = iA;
-		B->parent = A->parent;
-		A->parent = iB;
-
-		// A's old parent should point to B
-		if (B->parent != b2_nullNode)
-		{
-			if (m_nodes[B->parent].child1 == iA)
-			{
-				m_nodes[B->parent].child1 = iB;
-			}
-			else
-			{
-				b2Assert(m_nodes[B->parent].child2 == iA);
-				m_nodes[B->parent].child2 = iB;
-			}
-		}
-		else
-		{
-			m_root = iB;
-		}
-
-		// Rotate
-		if (D->height > E->height)
-		{
-			B->child2 = iD;
-			A->child1 = iE;
-			E->parent = iA;
-			A->aabb.Combine(C->aabb, E->aabb);
-			B->aabb.Combine(A->aabb, D->aabb);
-
-			A->height = 1 + b2Max(C->height, E->height);
-			B->height = 1 + b2Max(A->height, D->height);
-		}
-		else
-		{
-			B->child2 = iE;
-			A->child1 = iD;
-			D->parent = iA;
-			A->aabb.Combine(C->aabb, D->aabb);
-			B->aabb.Combine(A->aabb, E->aabb);
-
-			A->height = 1 + b2Max(C->height, D->height);
-			B->height = 1 + b2Max(A->height, E->height);
-		}
-
-		return iB;
-	}
-
-	return iA;
-}
-
-int32 b2DynamicTree::GetHeight() const
-{
-	if (m_root == b2_nullNode)
-	{
-		return 0;
-	}
-
-	return m_nodes[m_root].height;
-}
-
-//
-float32 b2DynamicTree::GetAreaRatio() const
-{
-	if (m_root == b2_nullNode)
-	{
-		return 0.0f;
-	}
-
-	const b2TreeNode* root = m_nodes + m_root;
-	float32 rootArea = root->aabb.GetPerimeter();
-
-	float32 totalArea = 0.0f;
-	for (int32 i = 0; i < m_nodeCapacity; ++i)
-	{
-		const b2TreeNode* node = m_nodes + i;
-		if (node->height < 0)
-		{
-			// Free node in pool
-			continue;
-		}
-
-		totalArea += node->aabb.GetPerimeter();
-	}
-
-	return totalArea / rootArea;
-}
-
-// Compute the height of a sub-tree.
-int32 b2DynamicTree::ComputeHeight(int32 nodeId) const
-{
-	b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
-	b2TreeNode* node = m_nodes + nodeId;
-
-	if (node->IsLeaf())
-	{
-		return 0;
-	}
-
-	int32 height1 = ComputeHeight(node->child1);
-	int32 height2 = ComputeHeight(node->child2);
-	return 1 + b2Max(height1, height2);
-}
-
-int32 b2DynamicTree::ComputeHeight() const
-{
-	int32 height = ComputeHeight(m_root);
-	return height;
-}
-
-void b2DynamicTree::ValidateStructure(int32 index) const
-{
-	if (index == b2_nullNode)
-	{
-		return;
-	}
-
-	if (index == m_root)
-	{
-		b2Assert(m_nodes[index].parent == b2_nullNode);
-	}
-
-	const b2TreeNode* node = m_nodes + index;
-
-	int32 child1 = node->child1;
-	int32 child2 = node->child2;
-
-	if (node->IsLeaf())
-	{
-		b2Assert(child1 == b2_nullNode);
-		b2Assert(child2 == b2_nullNode);
-		b2Assert(node->height == 0);
-		return;
-	}
-
-	b2Assert(0 <= child1 && child1 < m_nodeCapacity);
-	b2Assert(0 <= child2 && child2 < m_nodeCapacity);
-
-	b2Assert(m_nodes[child1].parent == index);
-	b2Assert(m_nodes[child2].parent == index);
-
-	ValidateStructure(child1);
-	ValidateStructure(child2);
-}
-
-void b2DynamicTree::ValidateMetrics(int32 index) const
-{
-	if (index == b2_nullNode)
-	{
-		return;
-	}
-
-	const b2TreeNode* node = m_nodes + index;
-
-	int32 child1 = node->child1;
-	int32 child2 = node->child2;
-
-	if (node->IsLeaf())
-	{
-		b2Assert(child1 == b2_nullNode);
-		b2Assert(child2 == b2_nullNode);
-		b2Assert(node->height == 0);
-		return;
-	}
-
-	b2Assert(0 <= child1 && child1 < m_nodeCapacity);
-	b2Assert(0 <= child2 && child2 < m_nodeCapacity);
-
-	int32 height1 = m_nodes[child1].height;
-	int32 height2 = m_nodes[child2].height;
-	int32 height;
-	height = 1 + b2Max(height1, height2);
-	b2Assert(node->height == height);
-
-	b2AABB aabb;
-	aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
-
-	b2Assert(aabb.lowerBound == node->aabb.lowerBound);
-	b2Assert(aabb.upperBound == node->aabb.upperBound);
-
-	ValidateMetrics(child1);
-	ValidateMetrics(child2);
-}
-
-void b2DynamicTree::Validate() const
-{
-	ValidateStructure(m_root);
-	ValidateMetrics(m_root);
-
-	int32 freeCount = 0;
-	int32 freeIndex = m_freeList;
-	while (freeIndex != b2_nullNode)
-	{
-		b2Assert(0 <= freeIndex && freeIndex < m_nodeCapacity);
-		freeIndex = m_nodes[freeIndex].next;
-		++freeCount;
-	}
-
-	b2Assert(GetHeight() == ComputeHeight());
-
-	b2Assert(m_nodeCount + freeCount == m_nodeCapacity);
-}
-
-int32 b2DynamicTree::GetMaxBalance() const
-{
-	int32 maxBalance = 0;
-	for (int32 i = 0; i < m_nodeCapacity; ++i)
-	{
-		const b2TreeNode* node = m_nodes + i;
-		if (node->height <= 1)
-		{
-			continue;
-		}
-
-		b2Assert(node->IsLeaf() == false);
-
-		int32 child1 = node->child1;
-		int32 child2 = node->child2;
-		int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height);
-		maxBalance = b2Max(maxBalance, balance);
-	}
-
-	return maxBalance;
-}
-
-void b2DynamicTree::RebuildBottomUp()
-{
-	int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
-	int32 count = 0;
-
-	// Build array of leaves. Free the rest.
-	for (int32 i = 0; i < m_nodeCapacity; ++i)
-	{
-		if (m_nodes[i].height < 0)
-		{
-			// free node in pool
-			continue;
-		}
-
-		if (m_nodes[i].IsLeaf())
-		{
-			m_nodes[i].parent = b2_nullNode;
-			nodes[count] = i;
-			++count;
-		}
-		else
-		{
-			FreeNode(i);
-		}
-	}
-
-	while (count > 1)
-	{
-		float32 minCost = b2_maxFloat;
-		int32 iMin = -1, jMin = -1;
-		for (int32 i = 0; i < count; ++i)
-		{
-			b2AABB aabbi = m_nodes[nodes[i]].aabb;
-
-			for (int32 j = i + 1; j < count; ++j)
-			{
-				b2AABB aabbj = m_nodes[nodes[j]].aabb;
-				b2AABB b;
-				b.Combine(aabbi, aabbj);
-				float32 cost = b.GetPerimeter();
-				if (cost < minCost)
-				{
-					iMin = i;
-					jMin = j;
-					minCost = cost;
-				}
-			}
-		}
-
-		int32 index1 = nodes[iMin];
-		int32 index2 = nodes[jMin];
-		b2TreeNode* child1 = m_nodes + index1;
-		b2TreeNode* child2 = m_nodes + index2;
-
-		int32 parentIndex = AllocateNode();
-		b2TreeNode* parent = m_nodes + parentIndex;
-		parent->child1 = index1;
-		parent->child2 = index2;
-		parent->height = 1 + b2Max(child1->height, child2->height);
-		parent->aabb.Combine(child1->aabb, child2->aabb);
-		parent->parent = b2_nullNode;
-
-		child1->parent = parentIndex;
-		child2->parent = parentIndex;
-
-		nodes[jMin] = nodes[count-1];
-		nodes[iMin] = parentIndex;
-		--count;
-	}
-
-	m_root = nodes[0];
-	b2Free(nodes);
-
-	Validate();
-}
-
-void b2DynamicTree::ShiftOrigin(const b2Vec2& newOrigin)
-{
-	// Build array of leaves. Free the rest.
-	for (int32 i = 0; i < m_nodeCapacity; ++i)
-	{
-		m_nodes[i].aabb.lowerBound -= newOrigin;
-		m_nodes[i].aabb.upperBound -= newOrigin;
-	}
-}
+/*
+* Copyright (c) 2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2DynamicTree.h>
+#include <memory.h>
+#include <string.h>
+
+b2DynamicTree::b2DynamicTree()
+{
+	m_root = b2_nullNode;
+
+	m_nodeCapacity = 16;
+	m_nodeCount = 0;
+	m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
+	memset(m_nodes, 0, m_nodeCapacity * sizeof(b2TreeNode));
+
+	// Build a linked list for the free list.
+	for (int32 i = 0; i < m_nodeCapacity - 1; ++i)
+	{
+		m_nodes[i].next = i + 1;
+		m_nodes[i].height = -1;
+	}
+	m_nodes[m_nodeCapacity-1].next = b2_nullNode;
+	m_nodes[m_nodeCapacity-1].height = -1;
+	m_freeList = 0;
+
+	m_path = 0;
+
+	m_insertionCount = 0;
+}
+
+b2DynamicTree::~b2DynamicTree()
+{
+	// This frees the entire tree in one shot.
+	b2Free(m_nodes);
+}
+
+// Allocate a node from the pool. Grow the pool if necessary.
+int32 b2DynamicTree::AllocateNode()
+{
+	// Expand the node pool as needed.
+	if (m_freeList == b2_nullNode)
+	{
+		b2Assert(m_nodeCount == m_nodeCapacity);
+
+		// The free list is empty. Rebuild a bigger pool.
+		b2TreeNode* oldNodes = m_nodes;
+		m_nodeCapacity *= 2;
+		m_nodes = (b2TreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2TreeNode));
+		memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2TreeNode));
+		b2Free(oldNodes);
+
+		// Build a linked list for the free list. The parent
+		// pointer becomes the "next" pointer.
+		for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i)
+		{
+			m_nodes[i].next = i + 1;
+			m_nodes[i].height = -1;
+		}
+		m_nodes[m_nodeCapacity-1].next = b2_nullNode;
+		m_nodes[m_nodeCapacity-1].height = -1;
+		m_freeList = m_nodeCount;
+	}
+
+	// Peel a node off the free list.
+	int32 nodeId = m_freeList;
+	m_freeList = m_nodes[nodeId].next;
+	m_nodes[nodeId].parent = b2_nullNode;
+	m_nodes[nodeId].child1 = b2_nullNode;
+	m_nodes[nodeId].child2 = b2_nullNode;
+	m_nodes[nodeId].height = 0;
+	m_nodes[nodeId].userData = NULL;
+	++m_nodeCount;
+	return nodeId;
+}
+
+// Return a node to the pool.
+void b2DynamicTree::FreeNode(int32 nodeId)
+{
+	b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
+	b2Assert(0 < m_nodeCount);
+	m_nodes[nodeId].next = m_freeList;
+	m_nodes[nodeId].height = -1;
+	m_freeList = nodeId;
+	--m_nodeCount;
+}
+
+// Create a proxy in the tree as a leaf node. We return the index
+// of the node instead of a pointer so that we can grow
+// the node pool.
+int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
+{
+	int32 proxyId = AllocateNode();
+
+	// Fatten the aabb.
+	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
+	m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
+	m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
+	m_nodes[proxyId].userData = userData;
+	m_nodes[proxyId].height = 0;
+
+	InsertLeaf(proxyId);
+
+	return proxyId;
+}
+
+void b2DynamicTree::DestroyProxy(int32 proxyId)
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+	b2Assert(m_nodes[proxyId].IsLeaf());
+
+	RemoveLeaf(proxyId);
+	FreeNode(proxyId);
+}
+
+bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+
+	b2Assert(m_nodes[proxyId].IsLeaf());
+
+	if (m_nodes[proxyId].aabb.Contains(aabb))
+	{
+		return false;
+	}
+
+	RemoveLeaf(proxyId);
+
+	// Extend AABB.
+	b2AABB b = aabb;
+	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
+	b.lowerBound = b.lowerBound - r;
+	b.upperBound = b.upperBound + r;
+
+	// Predict AABB displacement.
+	b2Vec2 d = b2_aabbMultiplier * displacement;
+
+	if (d.x < 0.0f)
+	{
+		b.lowerBound.x += d.x;
+	}
+	else
+	{
+		b.upperBound.x += d.x;
+	}
+
+	if (d.y < 0.0f)
+	{
+		b.lowerBound.y += d.y;
+	}
+	else
+	{
+		b.upperBound.y += d.y;
+	}
+
+	m_nodes[proxyId].aabb = b;
+
+	InsertLeaf(proxyId);
+	return true;
+}
+
+void b2DynamicTree::InsertLeaf(int32 leaf)
+{
+	++m_insertionCount;
+
+	if (m_root == b2_nullNode)
+	{
+		m_root = leaf;
+		m_nodes[m_root].parent = b2_nullNode;
+		return;
+	}
+
+	// Find the best sibling for this node
+	b2AABB leafAABB = m_nodes[leaf].aabb;
+	int32 index = m_root;
+	while (m_nodes[index].IsLeaf() == false)
+	{
+		int32 child1 = m_nodes[index].child1;
+		int32 child2 = m_nodes[index].child2;
+
+		float32 area = m_nodes[index].aabb.GetPerimeter();
+
+		b2AABB combinedAABB;
+		combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
+		float32 combinedArea = combinedAABB.GetPerimeter();
+
+		// Cost of creating a new parent for this node and the new leaf
+		float32 cost = 2.0f * combinedArea;
+
+		// Minimum cost of pushing the leaf further down the tree
+		float32 inheritanceCost = 2.0f * (combinedArea - area);
+
+		// Cost of descending into child1
+		float32 cost1;
+		if (m_nodes[child1].IsLeaf())
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child1].aabb);
+			cost1 = aabb.GetPerimeter() + inheritanceCost;
+		}
+		else
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child1].aabb);
+			float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
+			float32 newArea = aabb.GetPerimeter();
+			cost1 = (newArea - oldArea) + inheritanceCost;
+		}
+
+		// Cost of descending into child2
+		float32 cost2;
+		if (m_nodes[child2].IsLeaf())
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child2].aabb);
+			cost2 = aabb.GetPerimeter() + inheritanceCost;
+		}
+		else
+		{
+			b2AABB aabb;
+			aabb.Combine(leafAABB, m_nodes[child2].aabb);
+			float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
+			float32 newArea = aabb.GetPerimeter();
+			cost2 = newArea - oldArea + inheritanceCost;
+		}
+
+		// Descend according to the minimum cost.
+		if (cost < cost1 && cost < cost2)
+		{
+			break;
+		}
+
+		// Descend
+		if (cost1 < cost2)
+		{
+			index = child1;
+		}
+		else
+		{
+			index = child2;
+		}
+	}
+
+	int32 sibling = index;
+
+	// Create a new parent.
+	int32 oldParent = m_nodes[sibling].parent;
+	int32 newParent = AllocateNode();
+	m_nodes[newParent].parent = oldParent;
+	m_nodes[newParent].userData = NULL;
+	m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb);
+	m_nodes[newParent].height = m_nodes[sibling].height + 1;
+
+	if (oldParent != b2_nullNode)
+	{
+		// The sibling was not the root.
+		if (m_nodes[oldParent].child1 == sibling)
+		{
+			m_nodes[oldParent].child1 = newParent;
+		}
+		else
+		{
+			m_nodes[oldParent].child2 = newParent;
+		}
+
+		m_nodes[newParent].child1 = sibling;
+		m_nodes[newParent].child2 = leaf;
+		m_nodes[sibling].parent = newParent;
+		m_nodes[leaf].parent = newParent;
+	}
+	else
+	{
+		// The sibling was the root.
+		m_nodes[newParent].child1 = sibling;
+		m_nodes[newParent].child2 = leaf;
+		m_nodes[sibling].parent = newParent;
+		m_nodes[leaf].parent = newParent;
+		m_root = newParent;
+	}
+
+	// Walk back up the tree fixing heights and AABBs
+	index = m_nodes[leaf].parent;
+	while (index != b2_nullNode)
+	{
+		index = Balance(index);
+
+		int32 child1 = m_nodes[index].child1;
+		int32 child2 = m_nodes[index].child2;
+
+		b2Assert(child1 != b2_nullNode);
+		b2Assert(child2 != b2_nullNode);
+
+		m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
+		m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
+
+		index = m_nodes[index].parent;
+	}
+
+	//Validate();
+}
+
+void b2DynamicTree::RemoveLeaf(int32 leaf)
+{
+	if (leaf == m_root)
+	{
+		m_root = b2_nullNode;
+		return;
+	}
+
+	int32 parent = m_nodes[leaf].parent;
+	int32 grandParent = m_nodes[parent].parent;
+	int32 sibling;
+	if (m_nodes[parent].child1 == leaf)
+	{
+		sibling = m_nodes[parent].child2;
+	}
+	else
+	{
+		sibling = m_nodes[parent].child1;
+	}
+
+	if (grandParent != b2_nullNode)
+	{
+		// Destroy parent and connect sibling to grandParent.
+		if (m_nodes[grandParent].child1 == parent)
+		{
+			m_nodes[grandParent].child1 = sibling;
+		}
+		else
+		{
+			m_nodes[grandParent].child2 = sibling;
+		}
+		m_nodes[sibling].parent = grandParent;
+		FreeNode(parent);
+
+		// Adjust ancestor bounds.
+		int32 index = grandParent;
+		while (index != b2_nullNode)
+		{
+			index = Balance(index);
+
+			int32 child1 = m_nodes[index].child1;
+			int32 child2 = m_nodes[index].child2;
+
+			m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
+			m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
+
+			index = m_nodes[index].parent;
+		}
+	}
+	else
+	{
+		m_root = sibling;
+		m_nodes[sibling].parent = b2_nullNode;
+		FreeNode(parent);
+	}
+
+	//Validate();
+}
+
+// Perform a left or right rotation if node A is imbalanced.
+// Returns the new root index.
+int32 b2DynamicTree::Balance(int32 iA)
+{
+	b2Assert(iA != b2_nullNode);
+
+	b2TreeNode* A = m_nodes + iA;
+	if (A->IsLeaf() || A->height < 2)
+	{
+		return iA;
+	}
+
+	int32 iB = A->child1;
+	int32 iC = A->child2;
+	b2Assert(0 <= iB && iB < m_nodeCapacity);
+	b2Assert(0 <= iC && iC < m_nodeCapacity);
+
+	b2TreeNode* B = m_nodes + iB;
+	b2TreeNode* C = m_nodes + iC;
+
+	int32 balance = C->height - B->height;
+
+	// Rotate C up
+	if (balance > 1)
+	{
+		int32 iF = C->child1;
+		int32 iG = C->child2;
+		b2TreeNode* F = m_nodes + iF;
+		b2TreeNode* G = m_nodes + iG;
+		b2Assert(0 <= iF && iF < m_nodeCapacity);
+		b2Assert(0 <= iG && iG < m_nodeCapacity);
+
+		// Swap A and C
+		C->child1 = iA;
+		C->parent = A->parent;
+		A->parent = iC;
+
+		// A's old parent should point to C
+		if (C->parent != b2_nullNode)
+		{
+			if (m_nodes[C->parent].child1 == iA)
+			{
+				m_nodes[C->parent].child1 = iC;
+			}
+			else
+			{
+				b2Assert(m_nodes[C->parent].child2 == iA);
+				m_nodes[C->parent].child2 = iC;
+			}
+		}
+		else
+		{
+			m_root = iC;
+		}
+
+		// Rotate
+		if (F->height > G->height)
+		{
+			C->child2 = iF;
+			A->child2 = iG;
+			G->parent = iA;
+			A->aabb.Combine(B->aabb, G->aabb);
+			C->aabb.Combine(A->aabb, F->aabb);
+
+			A->height = 1 + b2Max(B->height, G->height);
+			C->height = 1 + b2Max(A->height, F->height);
+		}
+		else
+		{
+			C->child2 = iG;
+			A->child2 = iF;
+			F->parent = iA;
+			A->aabb.Combine(B->aabb, F->aabb);
+			C->aabb.Combine(A->aabb, G->aabb);
+
+			A->height = 1 + b2Max(B->height, F->height);
+			C->height = 1 + b2Max(A->height, G->height);
+		}
+
+		return iC;
+	}
+	
+	// Rotate B up
+	if (balance < -1)
+	{
+		int32 iD = B->child1;
+		int32 iE = B->child2;
+		b2TreeNode* D = m_nodes + iD;
+		b2TreeNode* E = m_nodes + iE;
+		b2Assert(0 <= iD && iD < m_nodeCapacity);
+		b2Assert(0 <= iE && iE < m_nodeCapacity);
+
+		// Swap A and B
+		B->child1 = iA;
+		B->parent = A->parent;
+		A->parent = iB;
+
+		// A's old parent should point to B
+		if (B->parent != b2_nullNode)
+		{
+			if (m_nodes[B->parent].child1 == iA)
+			{
+				m_nodes[B->parent].child1 = iB;
+			}
+			else
+			{
+				b2Assert(m_nodes[B->parent].child2 == iA);
+				m_nodes[B->parent].child2 = iB;
+			}
+		}
+		else
+		{
+			m_root = iB;
+		}
+
+		// Rotate
+		if (D->height > E->height)
+		{
+			B->child2 = iD;
+			A->child1 = iE;
+			E->parent = iA;
+			A->aabb.Combine(C->aabb, E->aabb);
+			B->aabb.Combine(A->aabb, D->aabb);
+
+			A->height = 1 + b2Max(C->height, E->height);
+			B->height = 1 + b2Max(A->height, D->height);
+		}
+		else
+		{
+			B->child2 = iE;
+			A->child1 = iD;
+			D->parent = iA;
+			A->aabb.Combine(C->aabb, D->aabb);
+			B->aabb.Combine(A->aabb, E->aabb);
+
+			A->height = 1 + b2Max(C->height, D->height);
+			B->height = 1 + b2Max(A->height, E->height);
+		}
+
+		return iB;
+	}
+
+	return iA;
+}
+
+int32 b2DynamicTree::GetHeight() const
+{
+	if (m_root == b2_nullNode)
+	{
+		return 0;
+	}
+
+	return m_nodes[m_root].height;
+}
+
+//
+float32 b2DynamicTree::GetAreaRatio() const
+{
+	if (m_root == b2_nullNode)
+	{
+		return 0.0f;
+	}
+
+	const b2TreeNode* root = m_nodes + m_root;
+	float32 rootArea = root->aabb.GetPerimeter();
+
+	float32 totalArea = 0.0f;
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		const b2TreeNode* node = m_nodes + i;
+		if (node->height < 0)
+		{
+			// Free node in pool
+			continue;
+		}
+
+		totalArea += node->aabb.GetPerimeter();
+	}
+
+	return totalArea / rootArea;
+}
+
+// Compute the height of a sub-tree.
+int32 b2DynamicTree::ComputeHeight(int32 nodeId) const
+{
+	b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);
+	b2TreeNode* node = m_nodes + nodeId;
+
+	if (node->IsLeaf())
+	{
+		return 0;
+	}
+
+	int32 height1 = ComputeHeight(node->child1);
+	int32 height2 = ComputeHeight(node->child2);
+	return 1 + b2Max(height1, height2);
+}
+
+int32 b2DynamicTree::ComputeHeight() const
+{
+	int32 height = ComputeHeight(m_root);
+	return height;
+}
+
+void b2DynamicTree::ValidateStructure(int32 index) const
+{
+	if (index == b2_nullNode)
+	{
+		return;
+	}
+
+	if (index == m_root)
+	{
+		b2Assert(m_nodes[index].parent == b2_nullNode);
+	}
+
+	const b2TreeNode* node = m_nodes + index;
+
+#if B2_ASSERT_ENABLED || DEBUG
+	int32 child1 = node->child1;
+	int32 child2 = node->child2;
+#endif  // B2_ASSERT_ENABLED || DEBUG
+
+	if (node->IsLeaf())
+	{
+		b2Assert(child1 == b2_nullNode);
+		b2Assert(child2 == b2_nullNode);
+		b2Assert(node->height == 0);
+		return;
+	}
+
+	b2Assert(0 <= child1 && child1 < m_nodeCapacity);
+	b2Assert(0 <= child2 && child2 < m_nodeCapacity);
+
+	b2Assert(m_nodes[child1].parent == index);
+	b2Assert(m_nodes[child2].parent == index);
+
+	B2_DEBUG_STATEMENT(ValidateStructure(child1));
+	B2_DEBUG_STATEMENT(ValidateStructure(child2));
+}
+
+void b2DynamicTree::ValidateMetrics(int32 index) const
+{
+	if (index == b2_nullNode)
+	{
+		return;
+	}
+
+	const b2TreeNode* node = m_nodes + index;
+
+	int32 child1 = node->child1;
+	int32 child2 = node->child2;
+
+	if (node->IsLeaf())
+	{
+		b2Assert(child1 == b2_nullNode);
+		b2Assert(child2 == b2_nullNode);
+		b2Assert(node->height == 0);
+		return;
+	}
+
+	b2Assert(0 <= child1 && child1 < m_nodeCapacity);
+	b2Assert(0 <= child2 && child2 < m_nodeCapacity);
+
+#if B2_ASSERT_ENABLED
+	int32 height1 = m_nodes[child1].height;
+	int32 height2 = m_nodes[child2].height;
+	int32 height;
+	height = 1 + b2Max(height1, height2);
+#endif // B2_ASSERT_ENABLED
+	b2Assert(node->height == height);
+
+	b2AABB aabb;
+	aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);
+
+	b2Assert(aabb.lowerBound == node->aabb.lowerBound);
+	b2Assert(aabb.upperBound == node->aabb.upperBound);
+
+	ValidateMetrics(child1);
+	ValidateMetrics(child2);
+}
+
+void b2DynamicTree::Validate() const
+{
+	B2_DEBUG_STATEMENT(ValidateStructure(m_root));
+	B2_DEBUG_STATEMENT(ValidateMetrics(m_root));
+
+	int32 freeCount = 0;
+	int32 freeIndex = m_freeList;
+	while (freeIndex != b2_nullNode)
+	{
+		b2Assert(0 <= freeIndex && freeIndex < m_nodeCapacity);
+		freeIndex = m_nodes[freeIndex].next;
+		++freeCount;
+	}
+
+	b2Assert(GetHeight() == ComputeHeight());
+
+	b2Assert(m_nodeCount + freeCount == m_nodeCapacity);
+}
+
+int32 b2DynamicTree::GetMaxBalance() const
+{
+	int32 maxBalance = 0;
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		const b2TreeNode* node = m_nodes + i;
+		if (node->height <= 1)
+		{
+			continue;
+		}
+
+		b2Assert(node->IsLeaf() == false);
+
+		int32 child1 = node->child1;
+		int32 child2 = node->child2;
+		int32 balance = b2Abs(m_nodes[child2].height - m_nodes[child1].height);
+		maxBalance = b2Max(maxBalance, balance);
+	}
+
+	return maxBalance;
+}
+
+void b2DynamicTree::RebuildBottomUp()
+{
+	int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
+	int32 count = 0;
+
+	// Build array of leaves. Free the rest.
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		if (m_nodes[i].height < 0)
+		{
+			// free node in pool
+			continue;
+		}
+
+		if (m_nodes[i].IsLeaf())
+		{
+			m_nodes[i].parent = b2_nullNode;
+			nodes[count] = i;
+			++count;
+		}
+		else
+		{
+			FreeNode(i);
+		}
+	}
+
+	while (count > 1)
+	{
+		float32 minCost = b2_maxFloat;
+		int32 iMin = -1, jMin = -1;
+		for (int32 i = 0; i < count; ++i)
+		{
+			b2AABB aabbi = m_nodes[nodes[i]].aabb;
+
+			for (int32 j = i + 1; j < count; ++j)
+			{
+				b2AABB aabbj = m_nodes[nodes[j]].aabb;
+				b2AABB b;
+				b.Combine(aabbi, aabbj);
+				float32 cost = b.GetPerimeter();
+				if (cost < minCost)
+				{
+					iMin = i;
+					jMin = j;
+					minCost = cost;
+				}
+			}
+		}
+
+		int32 index1 = nodes[iMin];
+		int32 index2 = nodes[jMin];
+		b2TreeNode* child1 = m_nodes + index1;
+		b2TreeNode* child2 = m_nodes + index2;
+
+		int32 parentIndex = AllocateNode();
+		b2TreeNode* parent = m_nodes + parentIndex;
+		parent->child1 = index1;
+		parent->child2 = index2;
+		parent->height = 1 + b2Max(child1->height, child2->height);
+		parent->aabb.Combine(child1->aabb, child2->aabb);
+		parent->parent = b2_nullNode;
+
+		child1->parent = parentIndex;
+		child2->parent = parentIndex;
+
+		nodes[jMin] = nodes[count-1];
+		nodes[iMin] = parentIndex;
+		--count;
+	}
+
+	m_root = nodes[0];
+	b2Free(nodes);
+
+	B2_DEBUG_STATEMENT(Validate());
+}
+
+void b2DynamicTree::ShiftOrigin(const b2Vec2& newOrigin)
+{
+	// Build array of leaves. Free the rest.
+	for (int32 i = 0; i < m_nodeCapacity; ++i)
+	{
+		m_nodes[i].aabb.lowerBound -= newOrigin;
+		m_nodes[i].aabb.upperBound -= newOrigin;
+	}
+}

+ 289 - 289
engine/source/Box2D/Collision/b2DynamicTree.h

@@ -1,289 +1,289 @@
-/*
-* Copyright (c) 2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_DYNAMIC_TREE_H
-#define B2_DYNAMIC_TREE_H
-
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Common/b2GrowableStack.h>
-
-#define b2_nullNode (-1)
-
-/// A node in the dynamic tree. The client does not interact with this directly.
-struct b2TreeNode
-{
-	bool IsLeaf() const
-	{
-		return child1 == b2_nullNode;
-	}
-
-	/// Enlarged AABB
-	b2AABB aabb;
-
-	void* userData;
-
-	union
-	{
-		int32 parent;
-		int32 next;
-	};
-
-	int32 child1;
-	int32 child2;
-
-	// leaf = 0, free node = -1
-	int32 height;
-};
-
-/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt.
-/// A dynamic tree arranges data in a binary tree to accelerate
-/// queries such as volume queries and ray casts. Leafs are proxies
-/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor
-/// so that the proxy AABB is bigger than the client object. This allows the client
-/// object to move by small amounts without triggering a tree update.
-///
-/// Nodes are pooled and relocatable, so we use node indices rather than pointers.
-class b2DynamicTree
-{
-public:
-	/// Constructing the tree initializes the node pool.
-	b2DynamicTree();
-
-	/// Destroy the tree, freeing the node pool.
-	~b2DynamicTree();
-
-	/// Create a proxy. Provide a tight fitting AABB and a userData pointer.
-	int32 CreateProxy(const b2AABB& aabb, void* userData);
-
-	/// Destroy a proxy. This asserts if the id is invalid.
-	void DestroyProxy(int32 proxyId);
-
-	/// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB,
-	/// then the proxy is removed from the tree and re-inserted. Otherwise
-	/// the function returns immediately.
-	/// @return true if the proxy was re-inserted.
-	bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement);
-
-	/// Get proxy user data.
-	/// @return the proxy user data or 0 if the id is invalid.
-	void* GetUserData(int32 proxyId) const;
-
-	/// Get the fat AABB for a proxy.
-	const b2AABB& GetFatAABB(int32 proxyId) const;
-
-	/// Query an AABB for overlapping proxies. The callback class
-	/// is called for each proxy that overlaps the supplied AABB.
-	template <typename T>
-	void Query(T* callback, const b2AABB& aabb) const;
-
-	/// Ray-cast against the proxies in the tree. This relies on the callback
-	/// to perform a exact ray-cast in the case were the proxy contains a shape.
-	/// The callback also performs the any collision filtering. This has performance
-	/// roughly equal to k * log(n), where k is the number of collisions and n is the
-	/// number of proxies in the tree.
-	/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
-	/// @param callback a callback class that is called for each proxy that is hit by the ray.
-	template <typename T>
-	void RayCast(T* callback, const b2RayCastInput& input) const;
-
-	/// Validate this tree. For testing.
-	void Validate() const;
-
-	/// Compute the height of the binary tree in O(N) time. Should not be
-	/// called often.
-	int32 GetHeight() const;
-
-	/// Get the maximum balance of an node in the tree. The balance is the difference
-	/// in height of the two children of a node.
-	int32 GetMaxBalance() const;
-
-	/// Get the ratio of the sum of the node areas to the root area.
-	float32 GetAreaRatio() const;
-
-	/// Build an optimal tree. Very expensive. For testing.
-	void RebuildBottomUp();
-
-	/// Shift the world origin. Useful for large worlds.
-	/// The shift formula is: position -= newOrigin
-	/// @param newOrigin the new origin with respect to the old origin
-	void ShiftOrigin(const b2Vec2& newOrigin);
-
-private:
-
-	int32 AllocateNode();
-	void FreeNode(int32 node);
-
-	void InsertLeaf(int32 node);
-	void RemoveLeaf(int32 node);
-
-	int32 Balance(int32 index);
-
-	int32 ComputeHeight() const;
-	int32 ComputeHeight(int32 nodeId) const;
-
-	void ValidateStructure(int32 index) const;
-	void ValidateMetrics(int32 index) const;
-
-	int32 m_root;
-
-	b2TreeNode* m_nodes;
-	int32 m_nodeCount;
-	int32 m_nodeCapacity;
-
-	int32 m_freeList;
-
-	/// This is used to incrementally traverse the tree for re-balancing.
-	uint32 m_path;
-
-	int32 m_insertionCount;
-};
-
-inline void* b2DynamicTree::GetUserData(int32 proxyId) const
-{
-	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
-	return m_nodes[proxyId].userData;
-}
-
-inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const
-{
-	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
-	return m_nodes[proxyId].aabb;
-}
-
-template <typename T>
-inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const
-{
-	b2GrowableStack<int32, 256> stack;
-	stack.Push(m_root);
-
-	while (stack.GetCount() > 0)
-	{
-		int32 nodeId = stack.Pop();
-		if (nodeId == b2_nullNode)
-		{
-			continue;
-		}
-
-		const b2TreeNode* node = m_nodes + nodeId;
-
-		if (b2TestOverlap(node->aabb, aabb))
-		{
-			if (node->IsLeaf())
-			{
-				bool proceed = callback->QueryCallback(nodeId);
-				if (proceed == false)
-				{
-					return;
-				}
-			}
-			else
-			{
-				stack.Push(node->child1);
-				stack.Push(node->child2);
-			}
-		}
-	}
-}
-
-template <typename T>
-inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const
-{
-	b2Vec2 p1 = input.p1;
-	b2Vec2 p2 = input.p2;
-	b2Vec2 r = p2 - p1;
-	b2Assert(r.LengthSquared() > 0.0f);
-	r.Normalize();
-
-	// v is perpendicular to the segment.
-	b2Vec2 v = b2Cross(1.0f, r);
-	b2Vec2 abs_v = b2Abs(v);
-
-	// Separating axis for segment (Gino, p80).
-	// |dot(v, p1 - c)| > dot(|v|, h)
-
-	float32 maxFraction = input.maxFraction;
-
-	// Build a bounding box for the segment.
-	b2AABB segmentAABB;
-	{
-		b2Vec2 t = p1 + maxFraction * (p2 - p1);
-		segmentAABB.lowerBound = b2Min(p1, t);
-		segmentAABB.upperBound = b2Max(p1, t);
-	}
-
-	b2GrowableStack<int32, 256> stack;
-	stack.Push(m_root);
-
-	while (stack.GetCount() > 0)
-	{
-		int32 nodeId = stack.Pop();
-		if (nodeId == b2_nullNode)
-		{
-			continue;
-		}
-
-		const b2TreeNode* node = m_nodes + nodeId;
-
-		if (b2TestOverlap(node->aabb, segmentAABB) == false)
-		{
-			continue;
-		}
-
-		// Separating axis for segment (Gino, p80).
-		// |dot(v, p1 - c)| > dot(|v|, h)
-		b2Vec2 c = node->aabb.GetCenter();
-		b2Vec2 h = node->aabb.GetExtents();
-		float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h);
-		if (separation > 0.0f)
-		{
-			continue;
-		}
-
-		if (node->IsLeaf())
-		{
-			b2RayCastInput subInput;
-			subInput.p1 = input.p1;
-			subInput.p2 = input.p2;
-			subInput.maxFraction = maxFraction;
-
-			float32 value = callback->RayCastCallback(subInput, nodeId);
-
-			if (value == 0.0f)
-			{
-				// The client has terminated the ray cast.
-				return;
-			}
-
-			if (value > 0.0f)
-			{
-				// Update segment bounding box.
-				maxFraction = value;
-				b2Vec2 t = p1 + maxFraction * (p2 - p1);
-				segmentAABB.lowerBound = b2Min(p1, t);
-				segmentAABB.upperBound = b2Max(p1, t);
-			}
-		}
-		else
-		{
-			stack.Push(node->child1);
-			stack.Push(node->child2);
-		}
-	}
-}
-
-#endif
+/*
+* Copyright (c) 2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_DYNAMIC_TREE_H
+#define B2_DYNAMIC_TREE_H
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Common/b2GrowableStack.h>
+
+#define b2_nullNode (-1)
+
+/// A node in the dynamic tree. The client does not interact with this directly.
+struct b2TreeNode
+{
+	bool IsLeaf() const
+	{
+		return child1 == b2_nullNode;
+	}
+
+	/// Enlarged AABB
+	b2AABB aabb;
+
+	void* userData;
+
+	union
+	{
+		int32 parent;
+		int32 next;
+	};
+
+	int32 child1;
+	int32 child2;
+
+	// leaf = 0, free node = -1
+	int32 height;
+};
+
+/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt.
+/// A dynamic tree arranges data in a binary tree to accelerate
+/// queries such as volume queries and ray casts. Leafs are proxies
+/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor
+/// so that the proxy AABB is bigger than the client object. This allows the client
+/// object to move by small amounts without triggering a tree update.
+///
+/// Nodes are pooled and relocatable, so we use node indices rather than pointers.
+class b2DynamicTree
+{
+public:
+	/// Constructing the tree initializes the node pool.
+	b2DynamicTree();
+
+	/// Destroy the tree, freeing the node pool.
+	~b2DynamicTree();
+
+	/// Create a proxy. Provide a tight fitting AABB and a userData pointer.
+	int32 CreateProxy(const b2AABB& aabb, void* userData);
+
+	/// Destroy a proxy. This asserts if the id is invalid.
+	void DestroyProxy(int32 proxyId);
+
+	/// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB,
+	/// then the proxy is removed from the tree and re-inserted. Otherwise
+	/// the function returns immediately.
+	/// @return true if the proxy was re-inserted.
+	bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement);
+
+	/// Get proxy user data.
+	/// @return the proxy user data or 0 if the id is invalid.
+	void* GetUserData(int32 proxyId) const;
+
+	/// Get the fat AABB for a proxy.
+	const b2AABB& GetFatAABB(int32 proxyId) const;
+
+	/// Query an AABB for overlapping proxies. The callback class
+	/// is called for each proxy that overlaps the supplied AABB.
+	template <typename T>
+	void Query(T* callback, const b2AABB& aabb) const;
+
+	/// Ray-cast against the proxies in the tree. This relies on the callback
+	/// to perform a exact ray-cast in the case were the proxy contains a shape.
+	/// The callback also performs the any collision filtering. This has performance
+	/// roughly equal to k * log(n), where k is the number of collisions and n is the
+	/// number of proxies in the tree.
+	/// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
+	/// @param callback a callback class that is called for each proxy that is hit by the ray.
+	template <typename T>
+	void RayCast(T* callback, const b2RayCastInput& input) const;
+
+	/// Validate this tree. For testing.
+	void Validate() const;
+
+	/// Compute the height of the binary tree in O(N) time. Should not be
+	/// called often.
+	int32 GetHeight() const;
+
+	/// Get the maximum balance of an node in the tree. The balance is the difference
+	/// in height of the two children of a node.
+	int32 GetMaxBalance() const;
+
+	/// Get the ratio of the sum of the node areas to the root area.
+	float32 GetAreaRatio() const;
+
+	/// Build an optimal tree. Very expensive. For testing.
+	void RebuildBottomUp();
+
+	/// Shift the world origin. Useful for large worlds.
+	/// The shift formula is: position -= newOrigin
+	/// @param newOrigin the new origin with respect to the old origin
+	void ShiftOrigin(const b2Vec2& newOrigin);
+
+private:
+
+	int32 AllocateNode();
+	void FreeNode(int32 node);
+
+	void InsertLeaf(int32 node);
+	void RemoveLeaf(int32 node);
+
+	int32 Balance(int32 index);
+
+	int32 ComputeHeight() const;
+	int32 ComputeHeight(int32 nodeId) const;
+
+	void ValidateStructure(int32 index) const;
+	void ValidateMetrics(int32 index) const;
+
+	int32 m_root;
+
+	b2TreeNode* m_nodes;
+	int32 m_nodeCount;
+	int32 m_nodeCapacity;
+
+	int32 m_freeList;
+
+	/// This is used to incrementally traverse the tree for re-balancing.
+	uint32 m_path;
+
+	int32 m_insertionCount;
+};
+
+inline void* b2DynamicTree::GetUserData(int32 proxyId) const
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+	return m_nodes[proxyId].userData;
+}
+
+inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const
+{
+	b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);
+	return m_nodes[proxyId].aabb;
+}
+
+template <typename T>
+inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const
+{
+	b2GrowableStack<int32, 256> stack;
+	stack.Push(m_root);
+
+	while (stack.GetCount() > 0)
+	{
+		int32 nodeId = stack.Pop();
+		if (nodeId == b2_nullNode)
+		{
+			continue;
+		}
+
+		const b2TreeNode* node = m_nodes + nodeId;
+
+		if (b2TestOverlap(node->aabb, aabb))
+		{
+			if (node->IsLeaf())
+			{
+				bool proceed = callback->QueryCallback(nodeId);
+				if (proceed == false)
+				{
+					return;
+				}
+			}
+			else
+			{
+				stack.Push(node->child1);
+				stack.Push(node->child2);
+			}
+		}
+	}
+}
+
+template <typename T>
+inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const
+{
+	b2Vec2 p1 = input.p1;
+	b2Vec2 p2 = input.p2;
+	b2Vec2 r = p2 - p1;
+	b2Assert(r.LengthSquared() > 0.0f);
+	r.Normalize();
+
+	// v is perpendicular to the segment.
+	b2Vec2 v = b2Cross(1.0f, r);
+	b2Vec2 abs_v = b2Abs(v);
+
+	// Separating axis for segment (Gino, p80).
+	// |dot(v, p1 - c)| > dot(|v|, h)
+
+	float32 maxFraction = input.maxFraction;
+
+	// Build a bounding box for the segment.
+	b2AABB segmentAABB;
+	{
+		b2Vec2 t = p1 + maxFraction * (p2 - p1);
+		segmentAABB.lowerBound = b2Min(p1, t);
+		segmentAABB.upperBound = b2Max(p1, t);
+	}
+
+	b2GrowableStack<int32, 256> stack;
+	stack.Push(m_root);
+
+	while (stack.GetCount() > 0)
+	{
+		int32 nodeId = stack.Pop();
+		if (nodeId == b2_nullNode)
+		{
+			continue;
+		}
+
+		const b2TreeNode* node = m_nodes + nodeId;
+
+		if (b2TestOverlap(node->aabb, segmentAABB) == false)
+		{
+			continue;
+		}
+
+		// Separating axis for segment (Gino, p80).
+		// |dot(v, p1 - c)| > dot(|v|, h)
+		b2Vec2 c = node->aabb.GetCenter();
+		b2Vec2 h = node->aabb.GetExtents();
+		float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h);
+		if (separation > 0.0f)
+		{
+			continue;
+		}
+
+		if (node->IsLeaf())
+		{
+			b2RayCastInput subInput;
+			subInput.p1 = input.p1;
+			subInput.p2 = input.p2;
+			subInput.maxFraction = maxFraction;
+
+			float32 value = callback->RayCastCallback(subInput, nodeId);
+
+			if (value == 0.0f)
+			{
+				// The client has terminated the ray cast.
+				return;
+			}
+
+			if (value > 0.0f)
+			{
+				// Update segment bounding box.
+				maxFraction = value;
+				b2Vec2 t = p1 + maxFraction * (p2 - p1);
+				segmentAABB.lowerBound = b2Min(p1, t);
+				segmentAABB.upperBound = b2Max(p1, t);
+			}
+		}
+		else
+		{
+			stack.Push(node->child1);
+			stack.Push(node->child2);
+		}
+	}
+}
+
+#endif

+ 487 - 476
engine/source/Box2D/Collision/b2TimeOfImpact.cpp

@@ -1,476 +1,487 @@
-/*
-* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Collision/b2Collision.h>
-#include <Box2D/Collision/b2Distance.h>
-#include <Box2D/Collision/b2TimeOfImpact.h>
-#include <Box2D/Collision/Shapes/b2CircleShape.h>
-#include <Box2D/Collision/Shapes/b2PolygonShape.h>
-
-#include <cstdio>
-using namespace std;
-
-int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters;
-int32 b2_toiRootIters, b2_toiMaxRootIters;
-
-struct b2SeparationFunction
-{
-	enum Type
-	{
-		e_points,
-		e_faceA,
-		e_faceB
-	};
-
-	// TODO_ERIN might not need to return the separation
-
-	float32 Initialize(const b2SimplexCache* cache,
-		const b2DistanceProxy* proxyA, const b2Sweep& sweepA,
-		const b2DistanceProxy* proxyB, const b2Sweep& sweepB,
-		float32 t1)
-	{
-		m_proxyA = proxyA;
-		m_proxyB = proxyB;
-		int32 count = cache->count;
-		b2Assert(0 < count && count < 3);
-
-		m_sweepA = sweepA;
-		m_sweepB = sweepB;
-
-		b2Transform xfA, xfB;
-		m_sweepA.GetTransform(&xfA, t1);
-		m_sweepB.GetTransform(&xfB, t1);
-
-		if (count == 1)
-		{
-			m_type = e_points;
-			b2Vec2 localPointA = m_proxyA->GetVertex(cache->indexA[0]);
-			b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);
-			b2Vec2 pointA = b2Mul(xfA, localPointA);
-			b2Vec2 pointB = b2Mul(xfB, localPointB);
-			m_axis = pointB - pointA;
-			float32 s = m_axis.Normalize();
-			return s;
-		}
-		else if (cache->indexA[0] == cache->indexA[1])
-		{
-			// Two points on B and one on A.
-			m_type = e_faceB;
-			b2Vec2 localPointB1 = proxyB->GetVertex(cache->indexB[0]);
-			b2Vec2 localPointB2 = proxyB->GetVertex(cache->indexB[1]);
-
-			m_axis = b2Cross(localPointB2 - localPointB1, 1.0f);
-			m_axis.Normalize();
-			b2Vec2 normal = b2Mul(xfB.q, m_axis);
-
-			m_localPoint = 0.5f * (localPointB1 + localPointB2);
-			b2Vec2 pointB = b2Mul(xfB, m_localPoint);
-
-			b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]);
-			b2Vec2 pointA = b2Mul(xfA, localPointA);
-
-			float32 s = b2Dot(pointA - pointB, normal);
-			if (s < 0.0f)
-			{
-				m_axis = -m_axis;
-				s = -s;
-			}
-			return s;
-		}
-		else
-		{
-			// Two points on A and one or two points on B.
-			m_type = e_faceA;
-			b2Vec2 localPointA1 = m_proxyA->GetVertex(cache->indexA[0]);
-			b2Vec2 localPointA2 = m_proxyA->GetVertex(cache->indexA[1]);
-			
-			m_axis = b2Cross(localPointA2 - localPointA1, 1.0f);
-			m_axis.Normalize();
-			b2Vec2 normal = b2Mul(xfA.q, m_axis);
-
-			m_localPoint = 0.5f * (localPointA1 + localPointA2);
-			b2Vec2 pointA = b2Mul(xfA, m_localPoint);
-
-			b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);
-			b2Vec2 pointB = b2Mul(xfB, localPointB);
-
-			float32 s = b2Dot(pointB - pointA, normal);
-			if (s < 0.0f)
-			{
-				m_axis = -m_axis;
-				s = -s;
-			}
-			return s;
-		}
-	}
-
-	float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const
-	{
-		b2Transform xfA, xfB;
-		m_sweepA.GetTransform(&xfA, t);
-		m_sweepB.GetTransform(&xfB, t);
-
-		switch (m_type)
-		{
-		case e_points:
-			{
-				b2Vec2 axisA = b2MulT(xfA.q,  m_axis);
-				b2Vec2 axisB = b2MulT(xfB.q, -m_axis);
-
-				*indexA = m_proxyA->GetSupport(axisA);
-				*indexB = m_proxyB->GetSupport(axisB);
-
-				b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);
-				b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);
-				
-				b2Vec2 pointA = b2Mul(xfA, localPointA);
-				b2Vec2 pointB = b2Mul(xfB, localPointB);
-
-				float32 separation = b2Dot(pointB - pointA, m_axis);
-				return separation;
-			}
-
-		case e_faceA:
-			{
-				b2Vec2 normal = b2Mul(xfA.q, m_axis);
-				b2Vec2 pointA = b2Mul(xfA, m_localPoint);
-
-				b2Vec2 axisB = b2MulT(xfB.q, -normal);
-				
-				*indexA = -1;
-				*indexB = m_proxyB->GetSupport(axisB);
-
-				b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);
-				b2Vec2 pointB = b2Mul(xfB, localPointB);
-
-				float32 separation = b2Dot(pointB - pointA, normal);
-				return separation;
-			}
-
-		case e_faceB:
-			{
-				b2Vec2 normal = b2Mul(xfB.q, m_axis);
-				b2Vec2 pointB = b2Mul(xfB, m_localPoint);
-
-				b2Vec2 axisA = b2MulT(xfA.q, -normal);
-
-				*indexB = -1;
-				*indexA = m_proxyA->GetSupport(axisA);
-
-				b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);
-				b2Vec2 pointA = b2Mul(xfA, localPointA);
-
-				float32 separation = b2Dot(pointA - pointB, normal);
-				return separation;
-			}
-
-		default:
-			b2Assert(false);
-			*indexA = -1;
-			*indexB = -1;
-			return 0.0f;
-		}
-	}
-
-	float32 Evaluate(int32 indexA, int32 indexB, float32 t) const
-	{
-		b2Transform xfA, xfB;
-		m_sweepA.GetTransform(&xfA, t);
-		m_sweepB.GetTransform(&xfB, t);
-
-		switch (m_type)
-		{
-		case e_points:
-			{
-				b2Vec2 localPointA = m_proxyA->GetVertex(indexA);
-				b2Vec2 localPointB = m_proxyB->GetVertex(indexB);
-
-				b2Vec2 pointA = b2Mul(xfA, localPointA);
-				b2Vec2 pointB = b2Mul(xfB, localPointB);
-				float32 separation = b2Dot(pointB - pointA, m_axis);
-
-				return separation;
-			}
-
-		case e_faceA:
-			{
-				b2Vec2 normal = b2Mul(xfA.q, m_axis);
-				b2Vec2 pointA = b2Mul(xfA, m_localPoint);
-
-				b2Vec2 localPointB = m_proxyB->GetVertex(indexB);
-				b2Vec2 pointB = b2Mul(xfB, localPointB);
-
-				float32 separation = b2Dot(pointB - pointA, normal);
-				return separation;
-			}
-
-		case e_faceB:
-			{
-				b2Vec2 normal = b2Mul(xfB.q, m_axis);
-				b2Vec2 pointB = b2Mul(xfB, m_localPoint);
-
-				b2Vec2 localPointA = m_proxyA->GetVertex(indexA);
-				b2Vec2 pointA = b2Mul(xfA, localPointA);
-
-				float32 separation = b2Dot(pointA - pointB, normal);
-				return separation;
-			}
-
-		default:
-			b2Assert(false);
-			return 0.0f;
-		}
-	}
-
-	const b2DistanceProxy* m_proxyA;
-	const b2DistanceProxy* m_proxyB;
-	b2Sweep m_sweepA, m_sweepB;
-	Type m_type;
-	b2Vec2 m_localPoint;
-	b2Vec2 m_axis;
-};
-
-// CCD via the local separating axis method. This seeks progression
-// by computing the largest time at which separation is maintained.
-void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input)
-{
-	++b2_toiCalls;
-
-	output->state = b2TOIOutput::e_unknown;
-	output->t = input->tMax;
-
-	const b2DistanceProxy* proxyA = &input->proxyA;
-	const b2DistanceProxy* proxyB = &input->proxyB;
-
-	b2Sweep sweepA = input->sweepA;
-	b2Sweep sweepB = input->sweepB;
-
-	// Large rotations can make the root finder fail, so we normalize the
-	// sweep angles.
-	sweepA.Normalize();
-	sweepB.Normalize();
-
-	float32 tMax = input->tMax;
-
-	float32 totalRadius = proxyA->m_radius + proxyB->m_radius;
-	float32 target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop);
-	float32 tolerance = 0.25f * b2_linearSlop;
-	b2Assert(target > tolerance);
-
-	float32 t1 = 0.0f;
-	const int32 k_maxIterations = 20;	// TODO_ERIN b2Settings
-	int32 iter = 0;
-
-	// Prepare input for distance query.
-	b2SimplexCache cache;
-	cache.count = 0;
-	b2DistanceInput distanceInput;
-	distanceInput.proxyA = input->proxyA;
-	distanceInput.proxyB = input->proxyB;
-	distanceInput.useRadii = false;
-
-	// The outer loop progressively attempts to compute new separating axes.
-	// This loop terminates when an axis is repeated (no progress is made).
-	for(;;)
-	{
-		b2Transform xfA, xfB;
-		sweepA.GetTransform(&xfA, t1);
-		sweepB.GetTransform(&xfB, t1);
-
-		// Get the distance between shapes. We can also use the results
-		// to get a separating axis.
-		distanceInput.transformA = xfA;
-		distanceInput.transformB = xfB;
-		b2DistanceOutput distanceOutput;
-		b2Distance(&distanceOutput, &cache, &distanceInput);
-
-		// If the shapes are overlapped, we give up on continuous collision.
-		if (distanceOutput.distance <= 0.0f)
-		{
-			// Failure!
-			output->state = b2TOIOutput::e_overlapped;
-			output->t = 0.0f;
-			break;
-		}
-
-		if (distanceOutput.distance < target + tolerance)
-		{
-			// Victory!
-			output->state = b2TOIOutput::e_touching;
-			output->t = t1;
-			break;
-		}
-
-		// Initialize the separating axis.
-		b2SeparationFunction fcn;
-		fcn.Initialize(&cache, proxyA, sweepA, proxyB, sweepB, t1);
-#if 0
-		// Dump the curve seen by the root finder
-		{
-			const int32 N = 100;
-			float32 dx = 1.0f / N;
-			float32 xs[N+1];
-			float32 fs[N+1];
-
-			float32 x = 0.0f;
-
-			for (int32 i = 0; i <= N; ++i)
-			{
-				sweepA.GetTransform(&xfA, x);
-				sweepB.GetTransform(&xfB, x);
-				float32 f = fcn.Evaluate(xfA, xfB) - target;
-
-				printf("%g %g\n", x, f);
-
-				xs[i] = x;
-				fs[i] = f;
-
-				x += dx;
-			}
-		}
-#endif
-
-		// Compute the TOI on the separating axis. We do this by successively
-		// resolving the deepest point. This loop is bounded by the number of vertices.
-		bool done = false;
-		float32 t2 = tMax;
-		int32 pushBackIter = 0;
-		for (;;)
-		{
-			// Find the deepest point at t2. Store the witness point indices.
-			int32 indexA, indexB;
-			float32 s2 = fcn.FindMinSeparation(&indexA, &indexB, t2);
-
-			// Is the final configuration separated?
-			if (s2 > target + tolerance)
-			{
-				// Victory!
-				output->state = b2TOIOutput::e_separated;
-				output->t = tMax;
-				done = true;
-				break;
-			}
-
-			// Has the separation reached tolerance?
-			if (s2 > target - tolerance)
-			{
-				// Advance the sweeps
-				t1 = t2;
-				break;
-			}
-
-			// Compute the initial separation of the witness points.
-			float32 s1 = fcn.Evaluate(indexA, indexB, t1);
-
-			// Check for initial overlap. This might happen if the root finder
-			// runs out of iterations.
-			if (s1 < target - tolerance)
-			{
-				output->state = b2TOIOutput::e_failed;
-				output->t = t1;
-				done = true;
-				break;
-			}
-
-			// Check for touching
-			if (s1 <= target + tolerance)
-			{
-				// Victory! t1 should hold the TOI (could be 0.0).
-				output->state = b2TOIOutput::e_touching;
-				output->t = t1;
-				done = true;
-				break;
-			}
-
-			// Compute 1D root of: f(x) - target = 0
-			int32 rootIterCount = 0;
-			float32 a1 = t1, a2 = t2;
-			for (;;)
-			{
-				// Use a mix of the secant rule and bisection.
-				float32 t;
-				if (rootIterCount & 1)
-				{
-					// Secant rule to improve convergence.
-					t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);
-				}
-				else
-				{
-					// Bisection to guarantee progress.
-					t = 0.5f * (a1 + a2);
-				}
-
-				float32 s = fcn.Evaluate(indexA, indexB, t);
-
-				if (b2Abs(s - target) < tolerance)
-				{
-					// t2 holds a tentative value for t1
-					t2 = t;
-					break;
-				}
-
-				// Ensure we continue to bracket the root.
-				if (s > target)
-				{
-					a1 = t;
-					s1 = s;
-				}
-				else
-				{
-					a2 = t;
-					s2 = s;
-				}
-
-				++rootIterCount;
-				++b2_toiRootIters;
-
-				if (rootIterCount == 50)
-				{
-					break;
-				}
-			}
-
-			b2_toiMaxRootIters = b2Max(b2_toiMaxRootIters, rootIterCount);
-
-			++pushBackIter;
-
-			if (pushBackIter == b2_maxPolygonVertices)
-			{
-				break;
-			}
-		}
-
-		++iter;
-		++b2_toiIters;
-
-		if (done)
-		{
-			break;
-		}
-
-		if (iter == k_maxIterations)
-		{
-			// Root finder got stuck. Semi-victory.
-			output->state = b2TOIOutput::e_failed;
-			output->t = t1;
-			break;
-		}
-	}
-
-	b2_toiMaxIters = b2Max(b2_toiMaxIters, iter);
-}
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Collision/b2Collision.h>
+#include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+#include <Box2D/Collision/Shapes/b2CircleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+#include <Box2D/Common/b2Timer.h>
+
+#include <stdio.h>
+
+float32 b2_toiTime, b2_toiMaxTime;
+int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters;
+int32 b2_toiRootIters, b2_toiMaxRootIters;
+
+//
+struct b2SeparationFunction
+{
+	enum Type
+	{
+		e_points,
+		e_faceA,
+		e_faceB
+	};
+
+	// TODO_ERIN might not need to return the separation
+
+	float32 Initialize(const b2SimplexCache* cache,
+		const b2DistanceProxy* proxyA, const b2Sweep& sweepA,
+		const b2DistanceProxy* proxyB, const b2Sweep& sweepB,
+		float32 t1)
+	{
+		m_proxyA = proxyA;
+		m_proxyB = proxyB;
+		int32 count = cache->count;
+		b2Assert(0 < count && count < 3);
+
+		m_sweepA = sweepA;
+		m_sweepB = sweepB;
+
+		b2Transform xfA, xfB;
+		m_sweepA.GetTransform(&xfA, t1);
+		m_sweepB.GetTransform(&xfB, t1);
+
+		if (count == 1)
+		{
+			m_type = e_points;
+			b2Vec2 localPointA = m_proxyA->GetVertex(cache->indexA[0]);
+			b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);
+			b2Vec2 pointA = b2Mul(xfA, localPointA);
+			b2Vec2 pointB = b2Mul(xfB, localPointB);
+			m_axis = pointB - pointA;
+			float32 s = m_axis.Normalize();
+			m_localPoint = b2Vec2_zero;
+			return s;
+		}
+		else if (cache->indexA[0] == cache->indexA[1])
+		{
+			// Two points on B and one on A.
+			m_type = e_faceB;
+			b2Vec2 localPointB1 = proxyB->GetVertex(cache->indexB[0]);
+			b2Vec2 localPointB2 = proxyB->GetVertex(cache->indexB[1]);
+
+			m_axis = b2Cross(localPointB2 - localPointB1, 1.0f);
+			m_axis.Normalize();
+			b2Vec2 normal = b2Mul(xfB.q, m_axis);
+
+			m_localPoint = 0.5f * (localPointB1 + localPointB2);
+			b2Vec2 pointB = b2Mul(xfB, m_localPoint);
+
+			b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]);
+			b2Vec2 pointA = b2Mul(xfA, localPointA);
+
+			float32 s = b2Dot(pointA - pointB, normal);
+			if (s < 0.0f)
+			{
+				m_axis = -m_axis;
+				s = -s;
+			}
+			return s;
+		}
+		else
+		{
+			// Two points on A and one or two points on B.
+			m_type = e_faceA;
+			b2Vec2 localPointA1 = m_proxyA->GetVertex(cache->indexA[0]);
+			b2Vec2 localPointA2 = m_proxyA->GetVertex(cache->indexA[1]);
+			
+			m_axis = b2Cross(localPointA2 - localPointA1, 1.0f);
+			m_axis.Normalize();
+			b2Vec2 normal = b2Mul(xfA.q, m_axis);
+
+			m_localPoint = 0.5f * (localPointA1 + localPointA2);
+			b2Vec2 pointA = b2Mul(xfA, m_localPoint);
+
+			b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);
+			b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+			float32 s = b2Dot(pointB - pointA, normal);
+			if (s < 0.0f)
+			{
+				m_axis = -m_axis;
+				s = -s;
+			}
+			return s;
+		}
+	}
+
+	//
+	float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const
+	{
+		b2Transform xfA, xfB;
+		m_sweepA.GetTransform(&xfA, t);
+		m_sweepB.GetTransform(&xfB, t);
+
+		switch (m_type)
+		{
+		case e_points:
+			{
+				b2Vec2 axisA = b2MulT(xfA.q,  m_axis);
+				b2Vec2 axisB = b2MulT(xfB.q, -m_axis);
+
+				*indexA = m_proxyA->GetSupport(axisA);
+				*indexB = m_proxyB->GetSupport(axisB);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);
+				b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);
+				
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+				float32 separation = b2Dot(pointB - pointA, m_axis);
+				return separation;
+			}
+
+		case e_faceA:
+			{
+				b2Vec2 normal = b2Mul(xfA.q, m_axis);
+				b2Vec2 pointA = b2Mul(xfA, m_localPoint);
+
+				b2Vec2 axisB = b2MulT(xfB.q, -normal);
+				
+				*indexA = -1;
+				*indexB = m_proxyB->GetSupport(axisB);
+
+				b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+				float32 separation = b2Dot(pointB - pointA, normal);
+				return separation;
+			}
+
+		case e_faceB:
+			{
+				b2Vec2 normal = b2Mul(xfB.q, m_axis);
+				b2Vec2 pointB = b2Mul(xfB, m_localPoint);
+
+				b2Vec2 axisA = b2MulT(xfA.q, -normal);
+
+				*indexB = -1;
+				*indexA = m_proxyA->GetSupport(axisA);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+
+				float32 separation = b2Dot(pointA - pointB, normal);
+				return separation;
+			}
+
+		default:
+			b2Assert(false);
+			*indexA = -1;
+			*indexB = -1;
+			return 0.0f;
+		}
+	}
+
+	//
+	float32 Evaluate(int32 indexA, int32 indexB, float32 t) const
+	{
+		b2Transform xfA, xfB;
+		m_sweepA.GetTransform(&xfA, t);
+		m_sweepB.GetTransform(&xfB, t);
+
+		switch (m_type)
+		{
+		case e_points:
+			{
+				b2Vec2 localPointA = m_proxyA->GetVertex(indexA);
+				b2Vec2 localPointB = m_proxyB->GetVertex(indexB);
+
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+				float32 separation = b2Dot(pointB - pointA, m_axis);
+
+				return separation;
+			}
+
+		case e_faceA:
+			{
+				b2Vec2 normal = b2Mul(xfA.q, m_axis);
+				b2Vec2 pointA = b2Mul(xfA, m_localPoint);
+
+				b2Vec2 localPointB = m_proxyB->GetVertex(indexB);
+				b2Vec2 pointB = b2Mul(xfB, localPointB);
+
+				float32 separation = b2Dot(pointB - pointA, normal);
+				return separation;
+			}
+
+		case e_faceB:
+			{
+				b2Vec2 normal = b2Mul(xfB.q, m_axis);
+				b2Vec2 pointB = b2Mul(xfB, m_localPoint);
+
+				b2Vec2 localPointA = m_proxyA->GetVertex(indexA);
+				b2Vec2 pointA = b2Mul(xfA, localPointA);
+
+				float32 separation = b2Dot(pointA - pointB, normal);
+				return separation;
+			}
+
+		default:
+			b2Assert(false);
+			return 0.0f;
+		}
+	}
+
+	const b2DistanceProxy* m_proxyA;
+	const b2DistanceProxy* m_proxyB;
+	b2Sweep m_sweepA, m_sweepB;
+	Type m_type;
+	b2Vec2 m_localPoint;
+	b2Vec2 m_axis;
+};
+
+// CCD via the local separating axis method. This seeks progression
+// by computing the largest time at which separation is maintained.
+void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input)
+{
+	b2Timer timer;
+
+	++b2_toiCalls;
+
+	output->state = b2TOIOutput::e_unknown;
+	output->t = input->tMax;
+
+	const b2DistanceProxy* proxyA = &input->proxyA;
+	const b2DistanceProxy* proxyB = &input->proxyB;
+
+	b2Sweep sweepA = input->sweepA;
+	b2Sweep sweepB = input->sweepB;
+
+	// Large rotations can make the root finder fail, so we normalize the
+	// sweep angles.
+	sweepA.Normalize();
+	sweepB.Normalize();
+
+	float32 tMax = input->tMax;
+
+	float32 totalRadius = proxyA->m_radius + proxyB->m_radius;
+	float32 target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop);
+	float32 tolerance = 0.25f * b2_linearSlop;
+	b2Assert(target > tolerance);
+
+	float32 t1 = 0.0f;
+	const int32 k_maxIterations = 20;	// TODO_ERIN b2Settings
+	int32 iter = 0;
+
+	// Prepare input for distance query.
+	b2SimplexCache cache;
+	cache.count = 0;
+	b2DistanceInput distanceInput;
+	distanceInput.proxyA = input->proxyA;
+	distanceInput.proxyB = input->proxyB;
+	distanceInput.useRadii = false;
+
+	// The outer loop progressively attempts to compute new separating axes.
+	// This loop terminates when an axis is repeated (no progress is made).
+	for(;;)
+	{
+		b2Transform xfA, xfB;
+		sweepA.GetTransform(&xfA, t1);
+		sweepB.GetTransform(&xfB, t1);
+
+		// Get the distance between shapes. We can also use the results
+		// to get a separating axis.
+		distanceInput.transformA = xfA;
+		distanceInput.transformB = xfB;
+		b2DistanceOutput distanceOutput;
+		b2Distance(&distanceOutput, &cache, &distanceInput);
+
+		// If the shapes are overlapped, we give up on continuous collision.
+		if (distanceOutput.distance <= 0.0f)
+		{
+			// Failure!
+			output->state = b2TOIOutput::e_overlapped;
+			output->t = 0.0f;
+			break;
+		}
+
+		if (distanceOutput.distance < target + tolerance)
+		{
+			// Victory!
+			output->state = b2TOIOutput::e_touching;
+			output->t = t1;
+			break;
+		}
+
+		// Initialize the separating axis.
+		b2SeparationFunction fcn;
+		fcn.Initialize(&cache, proxyA, sweepA, proxyB, sweepB, t1);
+#if 0
+		// Dump the curve seen by the root finder
+		{
+			const int32 N = 100;
+			float32 dx = 1.0f / N;
+			float32 xs[N+1];
+			float32 fs[N+1];
+
+			float32 x = 0.0f;
+
+			for (int32 i = 0; i <= N; ++i)
+			{
+				sweepA.GetTransform(&xfA, x);
+				sweepB.GetTransform(&xfB, x);
+				float32 f = fcn.Evaluate(xfA, xfB) - target;
+
+				printf("%g %g\n", x, f);
+
+				xs[i] = x;
+				fs[i] = f;
+
+				x += dx;
+			}
+		}
+#endif
+
+		// Compute the TOI on the separating axis. We do this by successively
+		// resolving the deepest point. This loop is bounded by the number of vertices.
+		bool done = false;
+		float32 t2 = tMax;
+		int32 pushBackIter = 0;
+		for (;;)
+		{
+			// Find the deepest point at t2. Store the witness point indices.
+			int32 indexA, indexB;
+			float32 s2 = fcn.FindMinSeparation(&indexA, &indexB, t2);
+
+			// Is the final configuration separated?
+			if (s2 > target + tolerance)
+			{
+				// Victory!
+				output->state = b2TOIOutput::e_separated;
+				output->t = tMax;
+				done = true;
+				break;
+			}
+
+			// Has the separation reached tolerance?
+			if (s2 > target - tolerance)
+			{
+				// Advance the sweeps
+				t1 = t2;
+				break;
+			}
+
+			// Compute the initial separation of the witness points.
+			float32 s1 = fcn.Evaluate(indexA, indexB, t1);
+
+			// Check for initial overlap. This might happen if the root finder
+			// runs out of iterations.
+			if (s1 < target - tolerance)
+			{
+				output->state = b2TOIOutput::e_failed;
+				output->t = t1;
+				done = true;
+				break;
+			}
+
+			// Check for touching
+			if (s1 <= target + tolerance)
+			{
+				// Victory! t1 should hold the TOI (could be 0.0).
+				output->state = b2TOIOutput::e_touching;
+				output->t = t1;
+				done = true;
+				break;
+			}
+
+			// Compute 1D root of: f(x) - target = 0
+			int32 rootIterCount = 0;
+			float32 a1 = t1, a2 = t2;
+			for (;;)
+			{
+				// Use a mix of the secant rule and bisection.
+				float32 t;
+				if (rootIterCount & 1)
+				{
+					// Secant rule to improve convergence.
+					t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);
+				}
+				else
+				{
+					// Bisection to guarantee progress.
+					t = 0.5f * (a1 + a2);
+				}
+
+				++rootIterCount;
+				++b2_toiRootIters;
+
+				float32 s = fcn.Evaluate(indexA, indexB, t);
+
+				if (b2Abs(s - target) < tolerance)
+				{
+					// t2 holds a tentative value for t1
+					t2 = t;
+					break;
+				}
+
+				// Ensure we continue to bracket the root.
+				if (s > target)
+				{
+					a1 = t;
+					s1 = s;
+				}
+				else
+				{
+					a2 = t;
+					s2 = s;
+				}
+				
+				if (rootIterCount == 50)
+				{
+					break;
+				}
+			}
+
+			b2_toiMaxRootIters = b2Max(b2_toiMaxRootIters, rootIterCount);
+
+			++pushBackIter;
+
+			if (pushBackIter == b2_maxPolygonVertices)
+			{
+				break;
+			}
+		}
+
+		++iter;
+		++b2_toiIters;
+
+		if (done)
+		{
+			break;
+		}
+
+		if (iter == k_maxIterations)
+		{
+			// Root finder got stuck. Semi-victory.
+			output->state = b2TOIOutput::e_failed;
+			output->t = t1;
+			break;
+		}
+	}
+
+	b2_toiMaxIters = b2Max(b2_toiMaxIters, iter);
+
+	float32 time = timer.GetMilliseconds();
+	b2_toiMaxTime = b2Max(b2_toiMaxTime, time);
+	b2_toiTime += time;
+}

+ 58 - 58
engine/source/Box2D/Collision/b2TimeOfImpact.h

@@ -1,58 +1,58 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_TIME_OF_IMPACT_H
-#define B2_TIME_OF_IMPACT_H
-
-#include <Box2D/Common/b2Math.h>
-#include <Box2D/Collision/b2Distance.h>
-
-/// Input parameters for b2TimeOfImpact
-struct b2TOIInput
-{
-	b2DistanceProxy proxyA;
-	b2DistanceProxy proxyB;
-	b2Sweep sweepA;
-	b2Sweep sweepB;
-	float32 tMax;		// defines sweep interval [0, tMax]
-};
-
-// Output parameters for b2TimeOfImpact.
-struct b2TOIOutput
-{
-	enum State
-	{
-		e_unknown,
-		e_failed,
-		e_overlapped,
-		e_touching,
-		e_separated
-	};
-
-	State state;
-	float32 t;
-};
-
-/// Compute the upper bound on time before two shapes penetrate. Time is represented as
-/// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate,
-/// non-tunneling collision. If you change the time interval, you should call this function
-/// again.
-/// Note: use b2Distance to compute the contact point and normal at the time of impact.
-void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input);
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_TIME_OF_IMPACT_H
+#define B2_TIME_OF_IMPACT_H
+
+#include <Box2D/Common/b2Math.h>
+#include <Box2D/Collision/b2Distance.h>
+
+/// Input parameters for b2TimeOfImpact
+struct b2TOIInput
+{
+	b2DistanceProxy proxyA;
+	b2DistanceProxy proxyB;
+	b2Sweep sweepA;
+	b2Sweep sweepB;
+	float32 tMax;		// defines sweep interval [0, tMax]
+};
+
+// Output parameters for b2TimeOfImpact.
+struct b2TOIOutput
+{
+	enum State
+	{
+		e_unknown,
+		e_failed,
+		e_overlapped,
+		e_touching,
+		e_separated
+	};
+
+	State state;
+	float32 t;
+};
+
+/// Compute the upper bound on time before two shapes penetrate. Time is represented as
+/// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate,
+/// non-tunneling collision. If you change the time interval, you should call this function
+/// again.
+/// Note: use b2Distance to compute the contact point and normal at the time of impact.
+void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input);
+
+#endif

+ 225 - 217
engine/source/Box2D/Common/b2BlockAllocator.cpp

@@ -1,217 +1,225 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Common/b2BlockAllocator.h>
-#include <cstdlib>
-#include <climits>
-#include <cstring>
-#include <memory>
-using namespace std;
-
-int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] = 
-{
-	16,		// 0
-	32,		// 1
-	64,		// 2
-	96,		// 3
-	128,	// 4
-	160,	// 5
-	192,	// 6
-	224,	// 7
-	256,	// 8
-	320,	// 9
-	384,	// 10
-	448,	// 11
-	512,	// 12
-	640,	// 13
-};
-uint8 b2BlockAllocator::s_blockSizeLookup[b2_maxBlockSize + 1];
-bool b2BlockAllocator::s_blockSizeLookupInitialized;
-
-struct b2Chunk
-{
-	int32 blockSize;
-	b2Block* blocks;
-};
-
-struct b2Block
-{
-	b2Block* next;
-};
-
-b2BlockAllocator::b2BlockAllocator()
-{
-	b2Assert(b2_blockSizes < UCHAR_MAX);
-
-	m_chunkSpace = b2_chunkArrayIncrement;
-	m_chunkCount = 0;
-	m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk));
-	
-	memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk));
-	memset(m_freeLists, 0, sizeof(m_freeLists));
-
-	if (s_blockSizeLookupInitialized == false)
-	{
-		int32 j = 0;
-		for (int32 i = 1; i <= b2_maxBlockSize; ++i)
-		{
-			b2Assert(j < b2_blockSizes);
-			if (i <= s_blockSizes[j])
-			{
-				s_blockSizeLookup[i] = (uint8)j;
-			}
-			else
-			{
-				++j;
-				s_blockSizeLookup[i] = (uint8)j;
-			}
-		}
-
-		s_blockSizeLookupInitialized = true;
-	}
-}
-
-b2BlockAllocator::~b2BlockAllocator()
-{
-	for (int32 i = 0; i < m_chunkCount; ++i)
-	{
-		b2Free(m_chunks[i].blocks);
-	}
-
-	b2Free(m_chunks);
-}
-
-void* b2BlockAllocator::Allocate(int32 size)
-{
-	if (size == 0)
-		return NULL;
-
-	b2Assert(0 < size);
-
-	if (size > b2_maxBlockSize)
-	{
-		return b2Alloc(size);
-	}
-
-	int32 index = s_blockSizeLookup[size];
-	b2Assert(0 <= index && index < b2_blockSizes);
-
-	if (m_freeLists[index])
-	{
-		b2Block* block = m_freeLists[index];
-		m_freeLists[index] = block->next;
-		return block;
-	}
-	else
-	{
-		if (m_chunkCount == m_chunkSpace)
-		{
-			b2Chunk* oldChunks = m_chunks;
-			m_chunkSpace += b2_chunkArrayIncrement;
-			m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk));
-			memcpy(m_chunks, oldChunks, m_chunkCount * sizeof(b2Chunk));
-			memset(m_chunks + m_chunkCount, 0, b2_chunkArrayIncrement * sizeof(b2Chunk));
-			b2Free(oldChunks);
-		}
-
-		b2Chunk* chunk = m_chunks + m_chunkCount;
-		chunk->blocks = (b2Block*)b2Alloc(b2_chunkSize);
-#if defined(_DEBUG)
-		memset(chunk->blocks, 0xcd, b2_chunkSize);
-#endif
-		int32 blockSize = s_blockSizes[index];
-		chunk->blockSize = blockSize;
-		int32 blockCount = b2_chunkSize / blockSize;
-		b2Assert(blockCount * blockSize <= b2_chunkSize);
-		for (int32 i = 0; i < blockCount - 1; ++i)
-		{
-			b2Block* block = (b2Block*)((int8*)chunk->blocks + blockSize * i);
-			b2Block* next = (b2Block*)((int8*)chunk->blocks + blockSize * (i + 1));
-			block->next = next;
-		}
-		b2Block* last = (b2Block*)((int8*)chunk->blocks + blockSize * (blockCount - 1));
-		last->next = NULL;
-
-		m_freeLists[index] = chunk->blocks->next;
-		++m_chunkCount;
-
-		return chunk->blocks;
-	}
-}
-
-void b2BlockAllocator::Free(void* p, int32 size)
-{
-	if (size == 0)
-	{
-		return;
-	}
-
-	b2Assert(0 < size);
-
-	if (size > b2_maxBlockSize)
-	{
-		b2Free(p);
-		return;
-	}
-
-	int32 index = s_blockSizeLookup[size];
-	b2Assert(0 <= index && index < b2_blockSizes);
-
-#ifdef _DEBUG
-	// Verify the memory address and size is valid.
-	int32 blockSize = s_blockSizes[index];
-	bool found = false;
-	for (int32 i = 0; i < m_chunkCount; ++i)
-	{
-		b2Chunk* chunk = m_chunks + i;
-		if (chunk->blockSize != blockSize)
-		{
-			b2Assert(	(int8*)p + blockSize <= (int8*)chunk->blocks ||
-						(int8*)chunk->blocks + b2_chunkSize <= (int8*)p);
-		}
-		else
-		{
-			if ((int8*)chunk->blocks <= (int8*)p && (int8*)p + blockSize <= (int8*)chunk->blocks + b2_chunkSize)
-			{
-				found = true;
-			}
-		}
-	}
-
-	b2Assert(found);
-
-	memset(p, 0xfd, blockSize);
-#endif
-
-	b2Block* block = (b2Block*)p;
-	block->next = m_freeLists[index];
-	m_freeLists[index] = block;
-}
-
-void b2BlockAllocator::Clear()
-{
-	for (int32 i = 0; i < m_chunkCount; ++i)
-	{
-		b2Free(m_chunks[i].blocks);
-	}
-
-	m_chunkCount = 0;
-	memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk));
-
-	memset(m_freeLists, 0, sizeof(m_freeLists));
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <limits.h>
+#include <memory.h>
+#include <stddef.h>
+#include <string.h>
+#include <new> // For placement new
+
+int32 b2BlockAllocator::s_blockSizes[b2_blockSizes] =
+{
+	16,		// 0
+	32,		// 1
+	64,		// 2
+	96,		// 3
+	128,	// 4
+	160,	// 5
+	192,	// 6
+	224,	// 7
+	256,	// 8
+	320,	// 9
+	384,	// 10
+	448,	// 11
+	512,	// 12
+	640,	// 13
+};
+uint8 b2BlockAllocator::s_blockSizeLookup[b2_maxBlockSize + 1];
+bool b2BlockAllocator::s_blockSizeLookupInitialized;
+
+struct b2Chunk
+{
+	int32 blockSize;
+	b2Block* blocks;
+};
+
+struct b2Block
+{
+	b2Block* next;
+};
+
+b2BlockAllocator::b2BlockAllocator()
+{
+	b2Assert((uint32)b2_blockSizes < UCHAR_MAX);
+
+	m_chunkSpace = b2_chunkArrayIncrement;
+	m_chunkCount = 0;
+	m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk));
+
+	memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk));
+	memset(m_freeLists, 0, sizeof(m_freeLists));
+
+	if (s_blockSizeLookupInitialized == false)
+	{
+		int32 j = 0;
+		for (int32 i = 1; i <= b2_maxBlockSize; ++i)
+		{
+			b2Assert(j < b2_blockSizes);
+			if (i <= s_blockSizes[j])
+			{
+				s_blockSizeLookup[i] = (uint8)j;
+			}
+			else
+			{
+				++j;
+				s_blockSizeLookup[i] = (uint8)j;
+			}
+		}
+
+		s_blockSizeLookupInitialized = true;
+	}
+}
+
+b2BlockAllocator::~b2BlockAllocator()
+{
+	for (int32 i = 0; i < m_chunkCount; ++i)
+	{
+		b2Free(m_chunks[i].blocks);
+	}
+
+	b2Free(m_chunks);
+}
+
+uint32 b2BlockAllocator::GetNumGiantAllocations() const
+{
+	return m_giants.GetList().GetLength();
+}
+
+void* b2BlockAllocator::Allocate(int32 size)
+{
+	if (size == 0)
+		return NULL;
+
+	b2Assert(0 < size);
+
+	if (size > b2_maxBlockSize)
+	{
+		return m_giants.Allocate(size);
+	}
+
+	int32 index = s_blockSizeLookup[size];
+	b2Assert(0 <= index && index < b2_blockSizes);
+
+	if (m_freeLists[index])
+	{
+		b2Block* block = m_freeLists[index];
+		m_freeLists[index] = block->next;
+		return block;
+	}
+	else
+	{
+		if (m_chunkCount == m_chunkSpace)
+		{
+			b2Chunk* oldChunks = m_chunks;
+			m_chunkSpace += b2_chunkArrayIncrement;
+			m_chunks = (b2Chunk*)b2Alloc(m_chunkSpace * sizeof(b2Chunk));
+			memcpy(m_chunks, oldChunks, m_chunkCount * sizeof(b2Chunk));
+			memset(m_chunks + m_chunkCount, 0, b2_chunkArrayIncrement * sizeof(b2Chunk));
+			b2Free(oldChunks);
+		}
+
+		b2Chunk* chunk = m_chunks + m_chunkCount;
+		chunk->blocks = (b2Block*)b2Alloc(b2_chunkSize);
+#if DEBUG
+		memset(chunk->blocks, 0xcd, b2_chunkSize);
+#endif
+		int32 blockSize = s_blockSizes[index];
+		chunk->blockSize = blockSize;
+		int32 blockCount = b2_chunkSize / blockSize;
+		b2Assert(blockCount * blockSize <= b2_chunkSize);
+		for (int32 i = 0; i < blockCount - 1; ++i)
+		{
+			b2Block* block = (b2Block*)((int8*)chunk->blocks + blockSize * i);
+			b2Block* next = (b2Block*)((int8*)chunk->blocks + blockSize * (i + 1));
+			block->next = next;
+		}
+		b2Block* last = (b2Block*)((int8*)chunk->blocks + blockSize * (blockCount - 1));
+		last->next = NULL;
+
+		m_freeLists[index] = chunk->blocks->next;
+		++m_chunkCount;
+
+		return chunk->blocks;
+	}
+}
+
+void b2BlockAllocator::Free(void* p, int32 size)
+{
+	if (size == 0)
+	{
+		return;
+	}
+
+	b2Assert(0 < size);
+
+	if (size > b2_maxBlockSize)
+	{
+		m_giants.Free(p);
+		return;
+	}
+
+	int32 index = s_blockSizeLookup[size];
+	b2Assert(0 <= index && index < b2_blockSizes);
+
+#if B2_ASSERT_ENABLED
+	// Verify the memory address and size is valid.
+	int32 blockSize = s_blockSizes[index];
+	bool found = false;
+	for (int32 i = 0; i < m_chunkCount; ++i)
+	{
+		b2Chunk* chunk = m_chunks + i;
+		if (chunk->blockSize != blockSize)
+		{
+			b2Assert(	(int8*)p + blockSize <= (int8*)chunk->blocks ||
+						(int8*)chunk->blocks + b2_chunkSize <= (int8*)p);
+		}
+		else
+		{
+			if ((int8*)chunk->blocks <= (int8*)p && (int8*)p + blockSize <= (int8*)chunk->blocks + b2_chunkSize)
+			{
+				found = true;
+			}
+		}
+	}
+
+	b2Assert(found);
+#endif // B2_ASSERT_ENABLED
+
+#if DEBUG
+	memset(p, 0xfd, s_blockSizes[index]);
+#endif
+
+	b2Block* block = (b2Block*)p;
+	block->next = m_freeLists[index];
+	m_freeLists[index] = block;
+}
+
+void b2BlockAllocator::Clear()
+{
+	for (int32 i = 0; i < m_chunkCount; ++i)
+	{
+		b2Free(m_chunks[i].blocks);
+	}
+
+	m_chunkCount = 0;
+	memset(m_chunks, 0, m_chunkSpace * sizeof(b2Chunk));
+
+	memset(m_freeLists, 0, sizeof(m_freeLists));
+}

+ 68 - 62
engine/source/Box2D/Common/b2BlockAllocator.h

@@ -1,62 +1,68 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_BLOCK_ALLOCATOR_H
-#define B2_BLOCK_ALLOCATOR_H
-
-#include <Box2D/Common/b2Settings.h>
-
-const int32 b2_chunkSize = 16 * 1024;
-const int32 b2_maxBlockSize = 640;
-const int32 b2_blockSizes = 14;
-const int32 b2_chunkArrayIncrement = 128;
-
-struct b2Block;
-struct b2Chunk;
-
-/// This is a small object allocator used for allocating small
-/// objects that persist for more than one time step.
-/// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp
-class b2BlockAllocator
-{
-public:
-	b2BlockAllocator();
-	~b2BlockAllocator();
-
-	/// Allocate memory. This will use b2Alloc if the size is larger than b2_maxBlockSize.
-	void* Allocate(int32 size);
-
-	/// Free memory. This will use b2Free if the size is larger than b2_maxBlockSize.
-	void Free(void* p, int32 size);
-
-	void Clear();
-
-private:
-
-	b2Chunk* m_chunks;
-	int32 m_chunkCount;
-	int32 m_chunkSpace;
-
-	b2Block* m_freeLists[b2_blockSizes];
-
-	static int32 s_blockSizes[b2_blockSizes];
-	static uint8 s_blockSizeLookup[b2_maxBlockSize + 1];
-	static bool s_blockSizeLookupInitialized;
-};
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_BLOCK_ALLOCATOR_H
+#define B2_BLOCK_ALLOCATOR_H
+
+#include <Box2D/Common/b2Settings.h>
+#include <Box2D/Common/b2TrackedBlock.h>
+
+const int32 b2_chunkSize = 16 * 1024;
+const int32 b2_maxBlockSize = 640;
+const int32 b2_blockSizes = 14;
+const int32 b2_chunkArrayIncrement = 128;
+
+struct b2Block;
+struct b2Chunk;
+
+/// This is a small object allocator used for allocating small
+/// objects that persist for more than one time step.
+/// See: http://www.codeproject.com/useritems/Small_Block_Allocator.asp
+class b2BlockAllocator
+{
+public:
+	b2BlockAllocator();
+	~b2BlockAllocator();
+
+	/// Allocate memory. This uses b2Alloc if the size is larger than b2_maxBlockSize.
+	void* Allocate(int32 size);
+
+	/// Free memory. This uses b2Free if the size is larger than b2_maxBlockSize.
+	void Free(void* p, int32 size);
+
+	void Clear();
+
+	/// Returns the number of allocations larger than the max block size.
+	uint32 GetNumGiantAllocations() const;
+
+private:
+	b2Chunk* m_chunks;
+	int32 m_chunkCount;
+	int32 m_chunkSpace;
+
+	b2Block* m_freeLists[b2_blockSizes];
+
+	// Record giant allocations--ones bigger than the max block size
+	b2TrackedBlockAllocator m_giants;
+
+	static int32 s_blockSizes[b2_blockSizes];
+	static uint8 s_blockSizeLookup[b2_maxBlockSize + 1];
+	static bool s_blockSizeLookupInitialized;
+};
+
+#endif

+ 44 - 44
engine/source/Box2D/Common/b2Draw.cpp

@@ -1,44 +1,44 @@
-/*
-* Copyright (c) 2011 Erin Catto http://box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Common/b2Draw.h>
-
-b2Draw::b2Draw()
-{
-	m_drawFlags = 0;
-}
-
-void b2Draw::SetFlags(uint32 flags)
-{
-	m_drawFlags = flags;
-}
-
-uint32 b2Draw::GetFlags() const
-{
-	return m_drawFlags;
-}
-
-void b2Draw::AppendFlags(uint32 flags)
-{
-	m_drawFlags |= flags;
-}
-
-void b2Draw::ClearFlags(uint32 flags)
-{
-	m_drawFlags &= ~flags;
-}
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Draw.h>
+
+b2Draw::b2Draw()
+{
+	m_drawFlags = 0;
+}
+
+void b2Draw::SetFlags(uint32 flags)
+{
+	m_drawFlags = flags;
+}
+
+uint32 b2Draw::GetFlags() const
+{
+	return m_drawFlags;
+}
+
+void b2Draw::AppendFlags(uint32 flags)
+{
+	m_drawFlags |= flags;
+}
+
+void b2Draw::ClearFlags(uint32 flags)
+{
+	m_drawFlags &= ~flags;
+}

+ 92 - 86
engine/source/Box2D/Common/b2Draw.h

@@ -1,86 +1,92 @@
-/*
-* Copyright (c) 2011 Erin Catto http://box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_DRAW_H
-#define B2_DRAW_H
-
-#include <Box2D/Common/b2Math.h>
-
-/// Color for debug drawing. Each value has the range [0,1].
-struct b2Color
-{
-	b2Color() {}
-	b2Color(float32 r, float32 g, float32 b) : r(r), g(g), b(b) {}
-	void Set(float32 ri, float32 gi, float32 bi) { r = ri; g = gi; b = bi; }
-	float32 r, g, b;
-};
-
-/// Implement and register this class with a b2World to provide debug drawing of physics
-/// entities in your game.
-class b2Draw
-{
-public:
-	b2Draw();
-
-	virtual ~b2Draw() {}
-
-	enum
-	{
-		e_shapeBit				= 0x0001,	///< draw shapes
-		e_jointBit				= 0x0002,	///< draw joint connections
-		e_aabbBit				= 0x0004,	///< draw axis aligned bounding boxes
-		e_pairBit				= 0x0008,	///< draw broad-phase pairs
-		e_centerOfMassBit		= 0x0010	///< draw center of mass frame
-	};
-
-	/// Set the drawing flags.
-	void SetFlags(uint32 flags);
-
-	/// Get the drawing flags.
-	uint32 GetFlags() const;
-	
-	/// Append flags to the current flags.
-	void AppendFlags(uint32 flags);
-
-	/// Clear flags from the current flags.
-	void ClearFlags(uint32 flags);
-
-	/// Draw a closed polygon provided in CCW order.
-	virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
-
-	/// Draw a solid closed polygon provided in CCW order.
-	virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
-
-	/// Draw a circle.
-	virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0;
-	
-	/// Draw a solid circle.
-	virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0;
-	
-	/// Draw a line segment.
-	virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0;
-
-	/// Draw a transform. Choose your own length scale.
-	/// @param xf a transform.
-	virtual void DrawTransform(const b2Transform& xf) = 0;
-
-protected:
-	uint32 m_drawFlags;
-};
-
-#endif
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_DRAW_H
+#define B2_DRAW_H
+
+#include <Box2D/Common/b2Math.h>
+#include <Box2D/Particle/b2Particle.h>
+
+/// Color for debug drawing. Each value has the range [0,1].
+struct b2Color
+{
+	b2Color() {}
+	b2Color(float32 r, float32 g, float32 b) : r(r), g(g), b(b) {}
+	void Set(float32 ri, float32 gi, float32 bi) { r = ri; g = gi; b = bi; }
+	float32 r, g, b;
+};
+
+/// Implement and register this class with a b2World to provide debug drawing of physics
+/// entities in your game.
+class b2Draw
+{
+public:
+	b2Draw();
+
+	virtual ~b2Draw() {}
+
+	enum
+	{
+		e_shapeBit				= 0x0001,	///< draw shapes
+		e_jointBit				= 0x0002,	///< draw joint connections
+		e_aabbBit				= 0x0004,	///< draw axis aligned bounding boxes
+		e_pairBit				= 0x0008,	///< draw broad-phase pairs
+		e_centerOfMassBit			= 0x0010,	///< draw center of mass frame
+		e_particleBit				= 0x0020  ///< draw particles
+	};
+
+	/// Set the drawing flags.
+	void SetFlags(uint32 flags);
+
+	/// Get the drawing flags.
+	uint32 GetFlags() const;
+
+	/// Append flags to the current flags.
+	void AppendFlags(uint32 flags);
+
+	/// Clear flags from the current flags.
+	void ClearFlags(uint32 flags);
+
+	/// Draw a closed polygon provided in CCW order.
+	virtual void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
+
+	/// Draw a solid closed polygon provided in CCW order.
+	virtual void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) = 0;
+
+	/// Draw a circle.
+	virtual void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) = 0;
+
+	/// Draw a solid circle.
+	virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0;
+
+	/// Draw a particle array
+	virtual void DrawParticles(const b2Vec2 *centers, float32 radius, const b2ParticleColor *colors, int32 count) = 0;
+
+	/// Draw a line segment.
+	virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0;
+
+	/// Draw a transform. Choose your own length scale.
+	/// @param xf a transform.
+	virtual void DrawTransform(const b2Transform& xf) = 0;
+
+protected:
+	uint32 m_drawFlags;
+};
+
+#endif

+ 57 - 0
engine/source/Box2D/Common/b2FreeList.cpp

@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#include <Box2D/Common/b2FreeList.h>
+#include <Box2D/Common/b2IntrusiveList.h>
+#include <Box2D/Common/b2Settings.h>
+
+/// Allocate an item from the freelist.
+b2IntrusiveListNode* b2FreeList::Allocate()
+{
+	if (m_free.IsEmpty()) return NULL;
+	b2IntrusiveListNode * const node = m_free.GetNext();
+	node->Remove();
+	m_allocated.InsertBefore(node);
+	return node;
+}
+
+void b2FreeList::Free(b2IntrusiveListNode* node)
+{
+	b2Assert(node);
+#if B2_FREE_LIST_CHECK_ALLOCATED_ON_FREE
+	b2Assert(m_allocated.FindNodeInList(node));
+#endif // B2_FREE_LIST_CHECK_ALLOCATED_ON_FREE
+	node->Remove();
+	m_free.InsertAfter(node);
+}
+
+void b2FreeList::AddToFreeList(b2IntrusiveListNode* node)
+{
+	b2Assert(node);
+	b2Assert(!node->InList());
+	m_free.InsertBefore(node);
+}
+
+void b2FreeList::RemoveAll()
+{
+	while (!m_allocated.IsEmpty()) {
+		m_allocated.GetNext()->Remove();
+	}
+	while (!m_free.IsEmpty()) {
+		m_free.GetNext()->Remove();
+	}
+}

+ 113 - 0
engine/source/Box2D/Common/b2FreeList.h

@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef B2_FREE_LIST_H
+#define B2_FREE_LIST_H
+
+#include <Box2D/Common/b2IntrusiveList.h>
+#include <Box2D/Common/b2Settings.h>
+
+/// When B2_FREE_LIST_CHECK_ALLOCATED_ON_FREE is 1, b2FreeList::Free() will
+/// check that the deallocated node was allocated from the freelist.
+#ifndef B2_FREE_LIST_CHECK_ALLOCATED_ON_FREE
+#define B2_FREE_LIST_CHECK_ALLOCATED_ON_FREE 0
+#endif // B2_FREE_LIST_CHECK_ALLOCATED_ON_FREE
+
+
+/// Fast - O(1) - list based allocator for items that can be inserted into
+/// b2IntrusiveListNode lists.
+class b2FreeList
+{
+public:
+	/// Construct the free list.
+	b2FreeList() { }
+
+	/// Destroy the free list.
+	~b2FreeList() { }
+
+	/// Allocate an item from the freelist.
+	b2IntrusiveListNode* Allocate();
+
+	/// Free an item from the freelist.
+	void Free(b2IntrusiveListNode* node);
+
+	/// Add an item to the freelist so that it can be allocated using
+	/// b2FreeList::Allocate().
+	void AddToFreeList(b2IntrusiveListNode* node);
+
+	/// Remove all items (allocated and free) from the freelist.
+	void RemoveAll();
+
+	/// Get the list which tracks allocated items.
+	const b2IntrusiveListNode& GetAllocatedList() const {
+		return m_allocated;
+	}
+
+	/// Get the list which tracks free items.
+	const b2IntrusiveListNode& GetFreeList() const {
+		return m_free;
+	}
+
+protected:
+	/// List of allocated items.
+	b2IntrusiveListNode m_allocated;
+	/// List of free items.
+	b2IntrusiveListNode m_free;
+};
+
+
+/// Typed b2FreeList which manages items of type T assuming T implements
+/// the GetInstanceFromListNode() and GetListNode() methods.
+template<typename T>
+class b2TypedFreeList {
+public:
+	/// Construct the free list.
+	b2TypedFreeList() { }
+
+	/// Destroy the free list.
+	~b2TypedFreeList() { }
+
+	/// Allocate an item from the free list.
+	T* Allocate() {
+		b2IntrusiveListNode* const node = m_freeList.Allocate();
+		if (!node) return NULL;
+		return T::GetInstanceFromListNode(node);
+	}
+
+	/// Free an item.
+	void Free(T* instance) {
+		b2Assert(instance);
+		m_freeList.Free(instance->GetListNode());
+	}
+
+	/// Add an item to the freelist so that it can be allocated with
+	/// b2TypedFreeList::Allocate().
+	void AddToFreeList(T* instance)
+	{
+		b2Assert(instance);
+		m_freeList.AddToFreeList(instance->GetListNode());
+	}
+
+	// Get the underlying b2FreeList.
+	b2FreeList* GetFreeList() { return &m_freeList; }
+	const b2FreeList* GetFreeList() const { return &m_freeList; }
+
+protected:
+	b2FreeList m_freeList;
+};
+
+#endif  // B2_FREE_LIST_H

+ 200 - 0
engine/source/Box2D/Common/b2GrowableBuffer.h

@@ -0,0 +1,200 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef B2_GROWABLE_BUFFER_H
+#define B2_GROWABLE_BUFFER_H
+
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <string.h>
+#include <memory.h>
+#include <algorithm>
+
+
+/// A simple array-like container, similar to std::vector.
+/// If we ever start using stl, we should replace this with std::vector.
+template <typename T>
+class b2GrowableBuffer
+{
+public:
+	b2GrowableBuffer(b2BlockAllocator& allocator) :
+		data(NULL),
+		count(0),
+		capacity(0),
+		allocator(&allocator)
+	{
+	#if defined(LIQUIDFUN_SIMD_NEON)
+		// b2ParticleAssemply.neon.s assumes these values are at fixed offsets.
+        // If this assert fails, be sure to update the assembly offsets!
+		// ldr r3, [r9, #0] @ r3 = out = contacts.data
+        // ldr r6, [r9, #8] @ r6 = contacts.capacity
+		b2Assert((intptr_t)&data - (intptr_t)(this) == 0
+			  && (intptr_t)&capacity - (intptr_t)(this) == 8);
+	#endif // defined(LIQUIDFUN_SIMD_NEON)
+	}
+
+	b2GrowableBuffer(const b2GrowableBuffer<T>& rhs) :
+		data(NULL),
+		count(rhs.count),
+		capacity(rhs.capacity),
+		allocator(rhs.allocator)
+	{
+		if (rhs.data != NULL)
+		{
+			data = (T*) allocator->Allocate(sizeof(T) * capacity);
+			memcpy(data, rhs.data, sizeof(T) * count);
+		}
+	}
+
+	~b2GrowableBuffer()
+	{
+		Free();
+	}
+
+	T& Append()
+	{
+		if (count >= capacity)
+		{
+			Grow();
+		}
+		return data[count++];
+	}
+
+	void Reserve(int32 newCapacity)
+	{
+		if (capacity >= newCapacity)
+			return;
+
+		// Reallocate and copy.
+		T* newData = (T*) allocator->Allocate(sizeof(T) * newCapacity);
+		if (data)
+		{
+			memcpy(newData, data, sizeof(T) * count);
+			allocator->Free(data, sizeof(T) * capacity);
+		}
+
+		// Update pointer and capacity.
+		capacity = newCapacity;
+		data = newData;
+	}
+
+	void Grow()
+	{
+		// Double the capacity.
+		int32 newCapacity = capacity ? 2 * capacity
+						  : b2_minParticleSystemBufferCapacity;
+		b2Assert(newCapacity > capacity);
+		Reserve(newCapacity);
+	}
+
+	void Free()
+	{
+		if (data == NULL)
+			return;
+
+		allocator->Free(data, sizeof(data[0]) * capacity);
+		data = NULL;
+		capacity = 0;
+		count = 0;
+	}
+
+	void Shorten(const T* newEnd)
+	{
+		b2Assert(newEnd >= data);
+		count = (int32) (newEnd - data);
+	}
+
+	T& operator[](int i)
+	{
+		return data[i];
+	}
+
+	const T& operator[](int i) const
+	{
+		return data[i];
+	}
+
+	T* Data()
+	{
+		return data;
+	}
+
+	const T* Data() const
+	{
+		return data;
+	}
+
+	T* Begin()
+	{
+		return data;
+	}
+
+	const T* Begin() const
+	{
+		return data;
+	}
+
+	T* End()
+	{
+		return &data[count];
+	}
+
+	const T* End() const
+	{
+		return &data[count];
+	}
+
+	int32 GetCount() const
+	{
+		return count;
+	}
+
+	void SetCount(int32 newCount)
+	{
+		b2Assert(0 <= newCount && newCount <= capacity);
+		count = newCount;
+	}
+
+	int32 GetCapacity() const
+	{
+		return capacity;
+	}
+
+	template<class UnaryPredicate>
+	T* RemoveIf(UnaryPredicate pred)
+	{
+		T* newEnd = std::remove_if(data, data + count, pred);
+		Shorten(newEnd);
+		return newEnd;
+	}
+
+	template<class BinaryPredicate>
+	T* Unique(BinaryPredicate pred)
+	{
+		T* newEnd = std::unique(data, data + count, pred);
+		Shorten(newEnd);
+		return newEnd;
+	}
+
+private:
+	T* data;
+	int32 count;
+	int32 capacity;
+	b2BlockAllocator* allocator;
+};
+
+#endif // B2_GROWABLE_BUFFER_H
+

+ 87 - 85
engine/source/Box2D/Common/b2GrowableStack.h

@@ -1,85 +1,87 @@
-/*
-* Copyright (c) 2010 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_GROWABLE_STACK_H
-#define B2_GROWABLE_STACK_H
-#include <Box2D/Common/b2Settings.h>
-#include <cstring>
-
-/// This is a growable LIFO stack with an initial capacity of N.
-/// If the stack size exceeds the initial capacity, the heap is used
-/// to increase the size of the stack.
-template <typename T, int32 N>
-class b2GrowableStack
-{
-public:
-	b2GrowableStack()
-	{
-		m_stack = m_array;
-		m_count = 0;
-		m_capacity = N;
-	}
-
-	~b2GrowableStack()
-	{
-		if (m_stack != m_array)
-		{
-			b2Free(m_stack);
-			m_stack = NULL;
-		}
-	}
-
-	void Push(const T& element)
-	{
-		if (m_count == m_capacity)
-		{
-			T* old = m_stack;
-			m_capacity *= 2;
-			m_stack = (T*)b2Alloc(m_capacity * sizeof(T));
-			std::memcpy(m_stack, old, m_count * sizeof(T));
-			if (old != m_array)
-			{
-				b2Free(old);
-			}
-		}
-
-		m_stack[m_count] = element;
-		++m_count;
-	}
-
-	T Pop()
-	{
-		b2Assert(m_count > 0);
-		--m_count;
-		return m_stack[m_count];
-	}
-
-	int32 GetCount()
-	{
-		return m_count;
-	}
-
-private:
-	T* m_stack;
-	T m_array[N];
-	int32 m_count;
-	int32 m_capacity;
-};
-
-
-#endif
+/*
+* Copyright (c) 2010 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_GROWABLE_STACK_H
+#define B2_GROWABLE_STACK_H
+
+#include <Box2D/Common/b2Settings.h>
+#include <string.h>
+#include <memory.h>
+
+/// This is a growable LIFO stack with an initial capacity of N.
+/// If the stack size exceeds the initial capacity, the heap is used
+/// to increase the size of the stack.
+template <typename T, int32 N>
+class b2GrowableStack
+{
+public:
+	b2GrowableStack()
+	{
+		m_stack = m_array;
+		m_count = 0;
+		m_capacity = N;
+	}
+
+	~b2GrowableStack()
+	{
+		if (m_stack != m_array)
+		{
+			b2Free(m_stack);
+			m_stack = NULL;
+		}
+	}
+
+	void Push(const T& element)
+	{
+		if (m_count == m_capacity)
+		{
+			T* old = m_stack;
+			m_capacity *= 2;
+			m_stack = (T*)b2Alloc(m_capacity * sizeof(T));
+			memcpy(m_stack, old, m_count * sizeof(T));
+			if (old != m_array)
+			{
+				b2Free(old);
+			}
+		}
+
+		m_stack[m_count] = element;
+		++m_count;
+	}
+
+	T Pop()
+	{
+		b2Assert(m_count > 0);
+		--m_count;
+		return m_stack[m_count];
+	}
+
+	int32 GetCount()
+	{
+		return m_count;
+	}
+
+private:
+	T* m_stack;
+	T m_array[N];
+	int32 m_count;
+	int32 m_capacity;
+};
+
+
+#endif

+ 369 - 0
engine/source/Box2D/Common/b2IntrusiveList.h

@@ -0,0 +1,369 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef B2_INTRUSIVE_LIST
+#define B2_INTRUSIVE_LIST
+
+#include <Box2D/Common/b2Settings.h>
+
+// Whether to enable b2IntrusiveList::ValidateList().
+// Be careful when enabling this since this changes the size of
+// b2IntrusiveListNode so make sure *all* projects that include Box2D.h
+// also define this value in the same way to avoid data corruption.
+#ifndef B2_INTRUSIVE_LIST_VALIDATE
+#define B2_INTRUSIVE_LIST_VALIDATE 0
+#endif  // B2_INTRUSIVE_LIST_VALIDATE
+
+/// b2IntrusiveListNode is used to implement an intrusive doubly-linked
+/// list.
+///
+/// For example:
+///
+/// class MyClass {
+/// public:
+/// 	MyClass(const char *msg) : m_msg(msg) {}
+/// 	const char* GetMessage() const { return m_msg; }
+/// 	B2_INTRUSIVE_LIST_GET_NODE(m_node);
+/// 	B2_INTRUSIVE_LIST_NODE_GET_CLASS(MyClass, m_node);
+/// private:
+/// 	b2IntrusiveListNode m_node;
+/// 	const char *m_msg;
+/// };
+///
+/// int main(int argc, char *argv[]) {
+/// 	b2IntrusiveListNode list; // NOTE: type is NOT MyClass
+/// 	MyClass a("this");
+/// 	MyClass b("is");
+/// 	MyClass c("a");
+/// 	MyClass d("test");
+/// 	list.InsertBefore(a.GetListNode());
+/// 	list.InsertBefore(b.GetListNode());
+/// 	list.InsertBefore(c.GetListNode());
+/// 	list.InsertBefore(d.GetListNode());
+/// 	for (b2IntrusiveListNode* node = list.GetNext();
+/// 		 node != list.GetTerminator(); node = node->GetNext()) {
+/// 		MyClass *cls = MyClass::GetInstanceFromListNode(node);
+/// 		printf("%s\n", cls->GetMessage());
+/// 	}
+/// 	return 0;
+/// }
+class b2IntrusiveListNode
+{
+public:
+	/// Initialize the node.
+	b2IntrusiveListNode()
+	{
+		Initialize();
+#if B2_INTRUSIVE_LIST_VALIDATE
+		m_magic = k_magic;
+#endif // B2_INTRUSIVE_LIST_VALIDATE
+	}
+
+	/// If the node is in a list, remove it from the list.
+	~b2IntrusiveListNode()
+	{
+		Remove();
+#if B2_INTRUSIVE_LIST_VALIDATE
+		m_magic = 0;
+#endif // B2_INTRUSIVE_LIST_VALIDATE
+	}
+
+	/// Insert this node after the specified node.
+	void InsertAfter(b2IntrusiveListNode* const node)
+	{
+		b2Assert(!node->InList());
+		node->m_next = m_next;
+		node->m_prev = this;
+		m_next->m_prev = node;
+		m_next = node;
+	}
+
+	/// Insert this node before the specified node.
+	void InsertBefore(b2IntrusiveListNode* const node)
+	{
+		b2Assert(!node->InList());
+		node->m_next = this;
+		node->m_prev = m_prev;
+		m_prev->m_next = node;
+		m_prev = node;
+	}
+
+	/// Get the terminator of the list.
+	const b2IntrusiveListNode* GetTerminator() const
+	{
+		return this;
+	}
+
+	/// Remove this node from the list it's currently in.
+	b2IntrusiveListNode* Remove()
+	{
+		m_prev->m_next = m_next;
+		m_next->m_prev = m_prev;
+		Initialize();
+		return this;
+	}
+
+	/// Determine whether this list is empty or the node isn't in a list.
+	bool IsEmpty() const
+	{
+	  return GetNext() == this;
+	}
+
+	/// Determine whether this node is in a list or the list contains nodes.
+	bool InList() const
+	{
+	  return !IsEmpty();
+	}
+
+	/// Calculate the length of the list.
+	uint32 GetLength() const
+	{
+		uint32 length = 0;
+		const b2IntrusiveListNode * const terminator = GetTerminator();
+		for (const b2IntrusiveListNode* node = GetNext();
+			 node != terminator; node = node->GetNext())
+		{
+			length++;
+		}
+		return length;
+	}
+
+	/// Get the next node in the list.
+	b2IntrusiveListNode* GetNext() const
+	{
+		return m_next;
+	}
+
+	/// Get the previous node in the list.
+	b2IntrusiveListNode* GetPrevious() const
+	{
+		return m_prev;
+	}
+
+	/// If B2_INTRUSIVE_LIST_VALIDATE is 1 perform a very rough validation
+	/// of all nodes in the list.
+	bool ValidateList() const
+	{
+#if B2_INTRUSIVE_LIST_VALIDATE
+	  if (m_magic != k_magic) return false;
+	  const b2IntrusiveListNode * const terminator = GetTerminator();
+	  for (b2IntrusiveListNode *node = GetNext(); node != terminator;
+		   node = node->GetNext()) {
+		if (node->m_magic != k_magic) return false;
+	  }
+#endif  // B2_INTRUSIVE_LIST_VALIDATE
+	  return true;
+	}
+
+	/// Determine whether the specified node is present in this list.
+	bool FindNodeInList(b2IntrusiveListNode* const nodeToFind) const
+	{
+		const b2IntrusiveListNode * const terminator = GetTerminator();
+		for (b2IntrusiveListNode *node = GetNext(); node != terminator;
+			 node = node->GetNext())
+		{
+			if (nodeToFind == node) return true;
+		}
+		return false;
+	}
+
+private:
+	/// Initialize the list node.
+	void Initialize()
+	{
+		m_next = this;
+		m_prev = this;
+	}
+
+private:
+#if B2_INTRUSIVE_LIST_VALIDATE
+	uint32 m_magic;
+#endif  // B2_INTRUSIVE_LIST_VALIDATE
+	/// The next node in the list.
+	b2IntrusiveListNode *m_prev;
+	/// The previous node in the list.
+	b2IntrusiveListNode *m_next;
+
+private:
+#if B2_INTRUSIVE_LIST_VALIDATE
+	static const uint32 k_magic = 0x7157ac01;
+#endif  // B2_INTRUSIVE_LIST_VALIDATE
+};
+
+/// Declares the member function GetListNode() of Class to retrieve a pointer
+/// to NodeMemberName.
+/// See #B2_INTRUSIVE_LIST_NODE_GET_CLASS_ACCESSOR()
+#define B2_INTRUSIVE_LIST_GET_NODE(NodeMemberName) \
+	b2IntrusiveListNode* GetListNode() { return &NodeMemberName; } \
+	const b2IntrusiveListNode* GetListNode() const { return &NodeMemberName; }
+
+/// Declares the member function FunctionName of Class to retrieve a pointer
+/// to a Class instance from a list node pointer.   NodeMemberName references
+/// the name of the b2IntrusiveListNode member of Class.
+#define B2_INTRUSIVE_LIST_NODE_GET_CLASS_ACCESSOR( \
+	Class, NodeMemberName, FunctionName) \
+	static Class* FunctionName(b2IntrusiveListNode *node) \
+	{ \
+		Class *cls = NULL; \
+		/* This effectively performs offsetof(Class, NodeMemberName) */ \
+		/* which ends up in the undefined behavior realm of C++ but in */ \
+		/* practice this works with most compilers. */ \
+		return reinterpret_cast<Class*>((uint8*)(node) - \
+										(uint8*)(&cls->NodeMemberName)); \
+	} \
+	\
+	static const Class* FunctionName(const b2IntrusiveListNode *node) \
+	{ \
+		return FunctionName(const_cast<b2IntrusiveListNode*>(node)); \
+	}
+
+/// Declares the member function GetInstanceFromListNode() of Class to retrieve
+/// a pointer to a Class instance from a list node pointer.  NodeMemberName
+/// reference the name of the b2IntrusiveListNode member of Class.
+#define B2_INTRUSIVE_LIST_NODE_GET_CLASS(Class, NodeMemberName) \
+	B2_INTRUSIVE_LIST_NODE_GET_CLASS_ACCESSOR(Class, NodeMemberName, \
+											  GetInstanceFromListNode)
+
+/// b2TypedIntrusiveListNode which supports inserting an object into a single
+/// doubly linked list.  For objects that need to be inserted in multiple
+/// doubly linked lists, use b2IntrusiveListNode.
+///
+/// For example:
+///
+/// class IntegerItem : public b2TypedIntrusiveListNode<IntegerItem>
+/// {
+/// public:
+/// 	IntegerItem(int32 value) : m_value(value) { }
+/// 	~IntegerItem() { }
+/// 	int32 GetValue() const { return m_value; }
+/// private:
+/// 	int32 m_value;
+/// };
+///
+/// int main(int argc, const char *arvg[]) {
+/// 	b2TypedIntrusiveListNode<IntegerItem> list;
+/// 	IntegerItem a(1);
+/// 	IntegerItem b(2);
+/// 	IntegerItem c(3);
+/// 	list.InsertBefore(&a);
+/// 	list.InsertBefore(&b);
+/// 	list.InsertBefore(&c);
+/// 	for (IntegerItem* item = list.GetNext();
+/// 		 item != list.GetTerminator(); item = item->GetNext())
+/// 	{
+/// 		printf("%d\n", item->GetValue());
+/// 	}
+/// }
+template<typename T>
+class b2TypedIntrusiveListNode
+{
+public:
+	b2TypedIntrusiveListNode() { }
+	~b2TypedIntrusiveListNode() { }
+
+	/// Insert this object after the specified object.
+	void InsertAfter(T* const obj)
+	{
+		b2Assert(obj);
+		GetListNode()->InsertAfter(obj->GetListNode());
+	}
+
+	/// Insert this object before the specified object.
+	void InsertBefore(T* const obj)
+	{
+		b2Assert(obj);
+		GetListNode()->InsertBefore(obj->GetListNode());
+	}
+
+	/// Get the next object in the list.
+	/// Check against GetTerminator() before deferencing the object.
+	T* GetNext() const
+	{
+		return GetInstanceFromListNode(GetListNode()->GetNext());
+	}
+
+	/// Get the previous object in the list.
+	/// Check against GetTerminator() before deferencing the object.
+	T* GetPrevious() const
+	{
+		return GetInstanceFromListNode(GetListNode()->GetPrevious());
+	}
+
+	/// Get the terminator of the list.
+	/// This should not be dereferenced as it is a pointer to
+	/// b2TypedIntrusiveListNode<T> *not* T.
+	T* GetTerminator() const
+	{
+		return (T*)GetListNode();
+	}
+
+	/// Remove this object from the list it's currently in.
+	T* Remove()
+	{
+		GetListNode()->Remove();
+		return GetInstanceFromListNode(GetListNode());
+	}
+
+	/// Determine whether this object is in a list.
+	bool InList() const
+	{
+		return GetListNode()->InList();
+	}
+
+	// Determine whether this list is empty.
+	bool IsEmpty() const
+	{
+		return GetListNode()->IsEmpty();
+	}
+
+	/// Calculate the length of the list.
+	uint32 GetLength() const
+	{
+		return GetListNode()->GetLength();
+	}
+
+	B2_INTRUSIVE_LIST_GET_NODE(m_node);
+
+private:
+	// Node within an intrusive list.
+	b2IntrusiveListNode m_node;
+
+public:
+	/// Get a pointer to the instance of T that contains "node".
+	static T* GetInstanceFromListNode(b2IntrusiveListNode* const node)
+	{
+		b2Assert(node);
+		// Calculate the pointer to T from the offset.
+		return (T*)((uint8*)node - GetNodeOffset(node));
+	}
+
+private:
+	// Get the offset of m_node within this class.
+	static int32 GetNodeOffset(b2IntrusiveListNode* const node)
+	{
+		b2Assert(node);
+		// Perform some type punning to calculate the offset of m_node in T.
+		// WARNING: This could result in undefined behavior with some C++
+		// compilers.
+		T* obj = (T*)node;
+		int32 nodeOffset = (int32)((uint8*)&obj->m_node - (uint8*)obj);
+		return nodeOffset;
+	}
+};
+
+#endif // B2_INTRUSIVE_LIST
+

+ 94 - 94
engine/source/Box2D/Common/b2Math.cpp

@@ -1,94 +1,94 @@
-/*
-* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Common/b2Math.h>
-
-const b2Vec2 b2Vec2_zero(0.0f, 0.0f);
-
-/// Solve A * x = b, where b is a column vector. This is more efficient
-/// than computing the inverse in one-shot cases.
-b2Vec3 b2Mat33::Solve33(const b2Vec3& b) const
-{
-	float32 det = b2Dot(ex, b2Cross(ey, ez));
-	if (det != 0.0f)
-	{
-		det = 1.0f / det;
-	}
-	b2Vec3 x;
-	x.x = det * b2Dot(b, b2Cross(ey, ez));
-	x.y = det * b2Dot(ex, b2Cross(b, ez));
-	x.z = det * b2Dot(ex, b2Cross(ey, b));
-	return x;
-}
-
-/// Solve A * x = b, where b is a column vector. This is more efficient
-/// than computing the inverse in one-shot cases.
-b2Vec2 b2Mat33::Solve22(const b2Vec2& b) const
-{
-	float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
-	float32 det = a11 * a22 - a12 * a21;
-	if (det != 0.0f)
-	{
-		det = 1.0f / det;
-	}
-	b2Vec2 x;
-	x.x = det * (a22 * b.x - a12 * b.y);
-	x.y = det * (a11 * b.y - a21 * b.x);
-	return x;
-}
-
-///
-void b2Mat33::GetInverse22(b2Mat33* M) const
-{
-	float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y;
-	float32 det = a * d - b * c;
-	if (det != 0.0f)
-	{
-		det = 1.0f / det;
-	}
-
-	M->ex.x =  det * d;	M->ey.x = -det * b; M->ex.z = 0.0f;
-	M->ex.y = -det * c;	M->ey.y =  det * a; M->ey.z = 0.0f;
-	M->ez.x = 0.0f; M->ez.y = 0.0f; M->ez.z = 0.0f;
-}
-
-/// Returns the zero matrix if singular.
-void b2Mat33::GetSymInverse33(b2Mat33* M) const
-{
-	float32 det = b2Dot(ex, b2Cross(ey, ez));
-	if (det != 0.0f)
-	{
-		det = 1.0f / det;
-	}
-
-	float32 a11 = ex.x, a12 = ey.x, a13 = ez.x;
-	float32 a22 = ey.y, a23 = ez.y;
-	float32 a33 = ez.z;
-
-	M->ex.x = det * (a22 * a33 - a23 * a23);
-	M->ex.y = det * (a13 * a23 - a12 * a33);
-	M->ex.z = det * (a12 * a23 - a13 * a22);
-
-	M->ey.x = M->ex.y;
-	M->ey.y = det * (a11 * a33 - a13 * a13);
-	M->ey.z = det * (a13 * a12 - a11 * a23);
-
-	M->ez.x = M->ex.z;
-	M->ez.y = M->ey.z;
-	M->ez.z = det * (a11 * a22 - a12 * a12);
-}
+/*
+* Copyright (c) 2007-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Math.h>
+
+const b2Vec2 b2Vec2_zero(0.0f, 0.0f);
+
+/// Solve A * x = b, where b is a column vector. This is more efficient
+/// than computing the inverse in one-shot cases.
+b2Vec3 b2Mat33::Solve33(const b2Vec3& b) const
+{
+	float32 det = b2Dot(ex, b2Cross(ey, ez));
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+	b2Vec3 x;
+	x.x = det * b2Dot(b, b2Cross(ey, ez));
+	x.y = det * b2Dot(ex, b2Cross(b, ez));
+	x.z = det * b2Dot(ex, b2Cross(ey, b));
+	return x;
+}
+
+/// Solve A * x = b, where b is a column vector. This is more efficient
+/// than computing the inverse in one-shot cases.
+b2Vec2 b2Mat33::Solve22(const b2Vec2& b) const
+{
+	float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
+	float32 det = a11 * a22 - a12 * a21;
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+	b2Vec2 x;
+	x.x = det * (a22 * b.x - a12 * b.y);
+	x.y = det * (a11 * b.y - a21 * b.x);
+	return x;
+}
+
+///
+void b2Mat33::GetInverse22(b2Mat33* M) const
+{
+	float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y;
+	float32 det = a * d - b * c;
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+
+	M->ex.x =  det * d;	M->ey.x = -det * b; M->ex.z = 0.0f;
+	M->ex.y = -det * c;	M->ey.y =  det * a; M->ey.z = 0.0f;
+	M->ez.x = 0.0f; M->ez.y = 0.0f; M->ez.z = 0.0f;
+}
+
+/// Returns the zero matrix if singular.
+void b2Mat33::GetSymInverse33(b2Mat33* M) const
+{
+	float32 det = b2Dot(ex, b2Cross(ey, ez));
+	if (det != 0.0f)
+	{
+		det = 1.0f / det;
+	}
+
+	float32 a11 = ex.x, a12 = ey.x, a13 = ez.x;
+	float32 a22 = ey.y, a23 = ez.y;
+	float32 a33 = ez.z;
+
+	M->ex.x = det * (a22 * a33 - a23 * a23);
+	M->ex.y = det * (a13 * a23 - a12 * a33);
+	M->ex.z = det * (a12 * a23 - a13 * a22);
+
+	M->ey.x = M->ex.y;
+	M->ey.y = det * (a11 * a33 - a13 * a13);
+	M->ey.z = det * (a13 * a12 - a11 * a23);
+
+	M->ez.x = M->ex.z;
+	M->ez.y = M->ey.z;
+	M->ez.z = det * (a11 * a22 - a12 * a12);
+}

+ 800 - 731
engine/source/Box2D/Common/b2Math.h

@@ -1,731 +1,800 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_MATH_H
-#define B2_MATH_H
-
-#include <Box2D/Common/b2Settings.h>
-
-#include <cmath>
-#include <cfloat>
-#include <cstddef>
-#include <limits>
-
-/// This function is used to ensure that a floating point number is
-/// not a NaN or infinity.
-inline bool b2IsValid(float32 x)
-{
-	if (x != x)
-	{
-		// NaN.
-		return false;
-	}
-
-	float32 infinity = std::numeric_limits<float32>::infinity();
-	return -infinity < x && x < infinity;
-}
-
-/// This is a approximate yet fast inverse square-root.
-inline float32 b2InvSqrt(float32 x)
-{
-	union
-	{
-		float32 x;
-		int32 i;
-	} convert;
-
-	convert.x = x;
-	float32 xhalf = 0.5f * x;
-	convert.i = 0x5f3759df - (convert.i >> 1);
-	x = convert.x;
-	x = x * (1.5f - xhalf * x * x);
-	return x;
-}
-
-#define	b2Sqrt(x)	std::sqrt(x)
-#define	b2Atan2(y, x)	std::atan2(y, x)
-
-/// A 2D column vector.
-struct b2Vec2
-{
-	/// Default constructor does nothing (for performance).
-	b2Vec2() {}
-
-	/// Construct using coordinates.
-	b2Vec2(float32 x, float32 y) : x(x), y(y) {}
-
-	/// Set this vector to all zeros.
-	void SetZero() { x = 0.0f; y = 0.0f; }
-
-	/// Set this vector to some specified coordinates.
-	void Set(float32 x_, float32 y_) { x = x_; y = y_; }
-
-	/// Negate this vector.
-	b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; }
-	
-	/// Read from and indexed element.
-	float32 operator () (int32 i) const
-	{
-		return (&x)[i];
-	}
-
-	/// Write to an indexed element.
-	float32& operator () (int32 i)
-	{
-		return (&x)[i];
-	}
-
-	/// Add a vector to this vector.
-	void operator += (const b2Vec2& v)
-	{
-		x += v.x; y += v.y;
-	}
-	
-	/// Subtract a vector from this vector.
-	void operator -= (const b2Vec2& v)
-	{
-		x -= v.x; y -= v.y;
-	}
-
-	/// Multiply this vector by a scalar.
-	void operator *= (float32 a)
-	{
-		x *= a; y *= a;
-	}
-
-	/// Get the length of this vector (the norm).
-	float32 Length() const
-	{
-		return b2Sqrt(x * x + y * y);
-	}
-
-	/// Get the length squared. For performance, use this instead of
-	/// b2Vec2::Length (if possible).
-	float32 LengthSquared() const
-	{
-		return x * x + y * y;
-	}
-
-	/// Convert this vector into a unit vector. Returns the length.
-	float32 Normalize()
-	{
-		float32 length = Length();
-		if (length < b2_epsilon)
-		{
-			return 0.0f;
-		}
-		float32 invLength = 1.0f / length;
-		x *= invLength;
-		y *= invLength;
-
-		return length;
-	}
-
-	/// Does this vector contain finite coordinates?
-	bool IsValid() const
-	{
-		return b2IsValid(x) && b2IsValid(y);
-	}
-
-	/// Get the skew vector such that dot(skew_vec, other) == cross(vec, other)
-	b2Vec2 Skew() const
-	{
-		return b2Vec2(-y, x);
-	}
-
-	float32 x, y;
-};
-
-/// A 2D column vector with 3 elements.
-struct b2Vec3
-{
-	/// Default constructor does nothing (for performance).
-	b2Vec3() {}
-
-	/// Construct using coordinates.
-	b2Vec3(float32 x, float32 y, float32 z) : x(x), y(y), z(z) {}
-
-	/// Set this vector to all zeros.
-	void SetZero() { x = 0.0f; y = 0.0f; z = 0.0f; }
-
-	/// Set this vector to some specified coordinates.
-	void Set(float32 x_, float32 y_, float32 z_) { x = x_; y = y_; z = z_; }
-
-	/// Negate this vector.
-	b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; }
-
-	/// Add a vector to this vector.
-	void operator += (const b2Vec3& v)
-	{
-		x += v.x; y += v.y; z += v.z;
-	}
-
-	/// Subtract a vector from this vector.
-	void operator -= (const b2Vec3& v)
-	{
-		x -= v.x; y -= v.y; z -= v.z;
-	}
-
-	/// Multiply this vector by a scalar.
-	void operator *= (float32 s)
-	{
-		x *= s; y *= s; z *= s;
-	}
-
-	float32 x, y, z;
-};
-
-/// A 2-by-2 matrix. Stored in column-major order.
-struct b2Mat22
-{
-	/// The default constructor does nothing (for performance).
-	b2Mat22() {}
-
-	/// Construct this matrix using columns.
-	b2Mat22(const b2Vec2& c1, const b2Vec2& c2)
-	{
-		ex = c1;
-		ey = c2;
-	}
-
-	/// Construct this matrix using scalars.
-	b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22)
-	{
-		ex.x = a11; ex.y = a21;
-		ey.x = a12; ey.y = a22;
-	}
-
-	/// Initialize this matrix using columns.
-	void Set(const b2Vec2& c1, const b2Vec2& c2)
-	{
-		ex = c1;
-		ey = c2;
-	}
-
-	/// Set this to the identity matrix.
-	void SetIdentity()
-	{
-		ex.x = 1.0f; ey.x = 0.0f;
-		ex.y = 0.0f; ey.y = 1.0f;
-	}
-
-	/// Set this matrix to all zeros.
-	void SetZero()
-	{
-		ex.x = 0.0f; ey.x = 0.0f;
-		ex.y = 0.0f; ey.y = 0.0f;
-	}
-
-	b2Mat22 GetInverse() const
-	{
-		float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y;
-		b2Mat22 B;
-		float32 det = a * d - b * c;
-		if (det != 0.0f)
-		{
-			det = 1.0f / det;
-		}
-		B.ex.x =  det * d;	B.ey.x = -det * b;
-		B.ex.y = -det * c;	B.ey.y =  det * a;
-		return B;
-	}
-
-	/// Solve A * x = b, where b is a column vector. This is more efficient
-	/// than computing the inverse in one-shot cases.
-	b2Vec2 Solve(const b2Vec2& b) const
-	{
-		float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
-		float32 det = a11 * a22 - a12 * a21;
-		if (det != 0.0f)
-		{
-			det = 1.0f / det;
-		}
-		b2Vec2 x;
-		x.x = det * (a22 * b.x - a12 * b.y);
-		x.y = det * (a11 * b.y - a21 * b.x);
-		return x;
-	}
-
-	b2Vec2 ex, ey;
-};
-
-/// A 3-by-3 matrix. Stored in column-major order.
-struct b2Mat33
-{
-	/// The default constructor does nothing (for performance).
-	b2Mat33() {}
-
-	/// Construct this matrix using columns.
-	b2Mat33(const b2Vec3& c1, const b2Vec3& c2, const b2Vec3& c3)
-	{
-		ex = c1;
-		ey = c2;
-		ez = c3;
-	}
-
-	/// Set this matrix to all zeros.
-	void SetZero()
-	{
-		ex.SetZero();
-		ey.SetZero();
-		ez.SetZero();
-	}
-
-	/// Solve A * x = b, where b is a column vector. This is more efficient
-	/// than computing the inverse in one-shot cases.
-	b2Vec3 Solve33(const b2Vec3& b) const;
-
-	/// Solve A * x = b, where b is a column vector. This is more efficient
-	/// than computing the inverse in one-shot cases. Solve only the upper
-	/// 2-by-2 matrix equation.
-	b2Vec2 Solve22(const b2Vec2& b) const;
-
-	/// Get the inverse of this matrix as a 2-by-2.
-	/// Returns the zero matrix if singular.
-	void GetInverse22(b2Mat33* M) const;
-
-	/// Get the symmetric inverse of this matrix as a 3-by-3.
-	/// Returns the zero matrix if singular.
-	void GetSymInverse33(b2Mat33* M) const;
-
-	b2Vec3 ex, ey, ez;
-};
-
-/// Rotation
-struct b2Rot
-{
-	b2Rot() {}
-
-	/// Initialize from an angle in radians
-	explicit b2Rot(float32 angle)
-	{
-		/// TODO_ERIN optimize
-		s = sinf(angle);
-		c = cosf(angle);
-	}
-
-	/// Set using an angle in radians.
-	void Set(float32 angle)
-	{
-		/// TODO_ERIN optimize
-		s = sinf(angle);
-		c = cosf(angle);
-	}
-
-	/// Set to the identity rotation
-	void SetIdentity()
-	{
-		s = 0.0f;
-		c = 1.0f;
-	}
-
-	/// Get the angle in radians
-	float32 GetAngle() const
-	{
-		return b2Atan2(s, c);
-	}
-
-	/// Get the x-axis
-	b2Vec2 GetXAxis() const
-	{
-		return b2Vec2(c, s);
-	}
-
-	/// Get the u-axis
-	b2Vec2 GetYAxis() const
-	{
-		return b2Vec2(-s, c);
-	}
-
-	/// Sine and cosine
-	float32 s, c;
-};
-
-/// A transform contains translation and rotation. It is used to represent
-/// the position and orientation of rigid frames.
-struct b2Transform
-{
-	/// The default constructor does nothing.
-	b2Transform() {}
-
-	/// Initialize using a position vector and a rotation.
-	b2Transform(const b2Vec2& position, const b2Rot& rotation) : p(position), q(rotation) {}
-
-	/// Set this to the identity transform.
-	void SetIdentity()
-	{
-		p.SetZero();
-		q.SetIdentity();
-	}
-
-	/// Set this based on the position and angle.
-	void Set(const b2Vec2& position, float32 angle)
-	{
-		p = position;
-		q.Set(angle);
-	}
-
-	b2Vec2 p;
-	b2Rot q;
-};
-
-/// This describes the motion of a body/shape for TOI computation.
-/// Shapes are defined with respect to the body origin, which may
-/// no coincide with the center of mass. However, to support dynamics
-/// we must interpolate the center of mass position.
-struct b2Sweep
-{
-	/// Get the interpolated transform at a specific time.
-	/// @param beta is a factor in [0,1], where 0 indicates alpha0.
-	void GetTransform(b2Transform* xfb, float32 beta) const;
-
-	/// Advance the sweep forward, yielding a new initial state.
-	/// @param alpha the new initial time.
-	void Advance(float32 alpha);
-
-	/// Normalize the angles.
-	void Normalize();
-
-	b2Vec2 localCenter;	///< local center of mass position
-	b2Vec2 c0, c;		///< center world positions
-	float32 a0, a;		///< world angles
-
-	/// Fraction of the current time step in the range [0,1]
-	/// c0 and a0 are the positions at alpha0.
-	float32 alpha0;
-};
-
-/// Useful constant
-extern const b2Vec2 b2Vec2_zero;
-
-/// Perform the dot product on two vectors.
-inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b)
-{
-	return a.x * b.x + a.y * b.y;
-}
-
-/// Perform the cross product on two vectors. In 2D this produces a scalar.
-inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b)
-{
-	return a.x * b.y - a.y * b.x;
-}
-
-/// Perform the cross product on a vector and a scalar. In 2D this produces
-/// a vector.
-inline b2Vec2 b2Cross(const b2Vec2& a, float32 s)
-{
-	return b2Vec2(s * a.y, -s * a.x);
-}
-
-/// Perform the cross product on a scalar and a vector. In 2D this produces
-/// a vector.
-inline b2Vec2 b2Cross(float32 s, const b2Vec2& a)
-{
-	return b2Vec2(-s * a.y, s * a.x);
-}
-
-/// Multiply a matrix times a vector. If a rotation matrix is provided,
-/// then this transforms the vector from one frame to another.
-inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v)
-{
-	return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y);
-}
-
-/// Multiply a matrix transpose times a vector. If a rotation matrix is provided,
-/// then this transforms the vector from one frame to another (inverse transform).
-inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v)
-{
-	return b2Vec2(b2Dot(v, A.ex), b2Dot(v, A.ey));
-}
-
-/// Add two vectors component-wise.
-inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b)
-{
-	return b2Vec2(a.x + b.x, a.y + b.y);
-}
-
-/// Subtract two vectors component-wise.
-inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b)
-{
-	return b2Vec2(a.x - b.x, a.y - b.y);
-}
-
-inline b2Vec2 operator * (float32 s, const b2Vec2& a)
-{
-	return b2Vec2(s * a.x, s * a.y);
-}
-
-inline bool operator == (const b2Vec2& a, const b2Vec2& b)
-{
-	return a.x == b.x && a.y == b.y;
-}
-
-inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b)
-{
-	b2Vec2 c = a - b;
-	return c.Length();
-}
-
-inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b)
-{
-	b2Vec2 c = a - b;
-	return b2Dot(c, c);
-}
-
-inline b2Vec3 operator * (float32 s, const b2Vec3& a)
-{
-	return b2Vec3(s * a.x, s * a.y, s * a.z);
-}
-
-/// Add two vectors component-wise.
-inline b2Vec3 operator + (const b2Vec3& a, const b2Vec3& b)
-{
-	return b2Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
-}
-
-/// Subtract two vectors component-wise.
-inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b)
-{
-	return b2Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
-}
-
-/// Perform the dot product on two vectors.
-inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b)
-{
-	return a.x * b.x + a.y * b.y + a.z * b.z;
-}
-
-/// Perform the cross product on two vectors.
-inline b2Vec3 b2Cross(const b2Vec3& a, const b2Vec3& b)
-{
-	return b2Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
-}
-
-inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B)
-{
-	return b2Mat22(A.ex + B.ex, A.ey + B.ey);
-}
-
-// A * B
-inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B)
-{
-	return b2Mat22(b2Mul(A, B.ex), b2Mul(A, B.ey));
-}
-
-// A^T * B
-inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B)
-{
-	b2Vec2 c1(b2Dot(A.ex, B.ex), b2Dot(A.ey, B.ex));
-	b2Vec2 c2(b2Dot(A.ex, B.ey), b2Dot(A.ey, B.ey));
-	return b2Mat22(c1, c2);
-}
-
-/// Multiply a matrix times a vector.
-inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v)
-{
-	return v.x * A.ex + v.y * A.ey + v.z * A.ez;
-}
-
-/// Multiply a matrix times a vector.
-inline b2Vec2 b2Mul22(const b2Mat33& A, const b2Vec2& v)
-{
-	return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y);
-}
-
-/// Multiply two rotations: q * r
-inline b2Rot b2Mul(const b2Rot& q, const b2Rot& r)
-{
-	// [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
-	// [qs  qc]   [rs  rc]   [qs*rc+qc*rs -qs*rs+qc*rc]
-	// s = qs * rc + qc * rs
-	// c = qc * rc - qs * rs
-	b2Rot qr;
-	qr.s = q.s * r.c + q.c * r.s;
-	qr.c = q.c * r.c - q.s * r.s;
-	return qr;
-}
-
-/// Transpose multiply two rotations: qT * r
-inline b2Rot b2MulT(const b2Rot& q, const b2Rot& r)
-{
-	// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
-	// [-qs qc]   [rs  rc]   [-qs*rc+qc*rs qs*rs+qc*rc]
-	// s = qc * rs - qs * rc
-	// c = qc * rc + qs * rs
-	b2Rot qr;
-	qr.s = q.c * r.s - q.s * r.c;
-	qr.c = q.c * r.c + q.s * r.s;
-	return qr;
-}
-
-/// Rotate a vector
-inline b2Vec2 b2Mul(const b2Rot& q, const b2Vec2& v)
-{
-	return b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);
-}
-
-/// Inverse rotate a vector
-inline b2Vec2 b2MulT(const b2Rot& q, const b2Vec2& v)
-{
-	return b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);
-}
-
-inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v)
-{
-	float32 x = (T.q.c * v.x - T.q.s * v.y) + T.p.x;
-	float32 y = (T.q.s * v.x + T.q.c * v.y) + T.p.y;
-
-	return b2Vec2(x, y);
-}
-
-inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v)
-{
-	float32 px = v.x - T.p.x;
-	float32 py = v.y - T.p.y;
-	float32 x = (T.q.c * px + T.q.s * py);
-	float32 y = (-T.q.s * px + T.q.c * py);
-
-	return b2Vec2(x, y);
-}
-
-// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p
-//    = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p
-inline b2Transform b2Mul(const b2Transform& A, const b2Transform& B)
-{
-	b2Transform C;
-	C.q = b2Mul(A.q, B.q);
-	C.p = b2Mul(A.q, B.p) + A.p;
-	return C;
-}
-
-// v2 = A.q' * (B.q * v1 + B.p - A.p)
-//    = A.q' * B.q * v1 + A.q' * (B.p - A.p)
-inline b2Transform b2MulT(const b2Transform& A, const b2Transform& B)
-{
-	b2Transform C;
-	C.q = b2MulT(A.q, B.q);
-	C.p = b2MulT(A.q, B.p - A.p);
-	return C;
-}
-
-template <typename T>
-inline T b2Abs(T a)
-{
-	return a > T(0) ? a : -a;
-}
-
-inline b2Vec2 b2Abs(const b2Vec2& a)
-{
-	return b2Vec2(b2Abs(a.x), b2Abs(a.y));
-}
-
-inline b2Mat22 b2Abs(const b2Mat22& A)
-{
-	return b2Mat22(b2Abs(A.ex), b2Abs(A.ey));
-}
-
-template <typename T>
-inline T b2Min(T a, T b)
-{
-	return a < b ? a : b;
-}
-
-inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b)
-{
-	return b2Vec2(b2Min(a.x, b.x), b2Min(a.y, b.y));
-}
-
-template <typename T>
-inline T b2Max(T a, T b)
-{
-	return a > b ? a : b;
-}
-
-inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b)
-{
-	return b2Vec2(b2Max(a.x, b.x), b2Max(a.y, b.y));
-}
-
-template <typename T>
-inline T b2Clamp(T a, T low, T high)
-{
-	return b2Max(low, b2Min(a, high));
-}
-
-inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high)
-{
-	return b2Max(low, b2Min(a, high));
-}
-
-template<typename T> inline void b2Swap(T& a, T& b)
-{
-	T tmp = a;
-	a = b;
-	b = tmp;
-}
-
-/// "Next Largest Power of 2
-/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
-/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
-/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
-/// largest power of 2. For a 32-bit value:"
-inline uint32 b2NextPowerOfTwo(uint32 x)
-{
-	x |= (x >> 1);
-	x |= (x >> 2);
-	x |= (x >> 4);
-	x |= (x >> 8);
-	x |= (x >> 16);
-	return x + 1;
-}
-
-inline bool b2IsPowerOfTwo(uint32 x)
-{
-	bool result = x > 0 && (x & (x - 1)) == 0;
-	return result;
-}
-
-inline void b2Sweep::GetTransform(b2Transform* xf, float32 beta) const
-{
-	xf->p = (1.0f - beta) * c0 + beta * c;
-	float32 angle = (1.0f - beta) * a0 + beta * a;
-	xf->q.Set(angle);
-
-	// Shift to origin
-	xf->p -= b2Mul(xf->q, localCenter);
-}
-
-inline void b2Sweep::Advance(float32 alpha)
-{
-	b2Assert(alpha0 < 1.0f);
-	float32 beta = (alpha - alpha0) / (1.0f - alpha0);
-	c0 = (1.0f - beta) * c0 + beta * c;
-	a0 = (1.0f - beta) * a0 + beta * a;
-	alpha0 = alpha;
-}
-
-/// Normalize an angle in radians to be between -pi and pi
-inline void b2Sweep::Normalize()
-{
-	float32 twoPi = 2.0f * b2_pi;
-	float32 d =  twoPi * floorf(a0 / twoPi);
-	a0 -= d;
-	a -= d;
-}
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_MATH_H
+#define B2_MATH_H
+
+#include <Box2D/Common/b2Settings.h>
+#include <math.h>
+
+/// This function is used to ensure that a floating point number is not a NaN or infinity.
+inline bool b2IsValid(float32 x)
+{
+	union {
+		float32 f;
+		int32 i;
+	} v = { x };
+	return (v.i & 0x7f800000) != 0x7f800000;
+}
+
+/// This is a approximate yet fast inverse square-root.
+inline float32 b2InvSqrt(float32 x)
+{
+	union
+	{
+		float32 x;
+		int32 i;
+	} convert;
+
+	convert.x = x;
+	float32 xhalf = 0.5f * x;
+	convert.i = 0x5f3759df - (convert.i >> 1);
+	x = convert.x;
+	x = x * (1.5f - xhalf * x * x);
+	return x;
+}
+
+#define	b2Sqrt(x)	sqrtf(x)
+#define	b2Atan2(y, x)	atan2f(y, x)
+
+/// A 2D column vector.
+struct b2Vec2
+{
+	/// Default constructor does nothing (for performance).
+	b2Vec2() {}
+
+	/// Construct using coordinates.
+	b2Vec2(float32 x, float32 y) : x(x), y(y) {}
+
+	/// Set this vector to all zeros.
+	void SetZero() { x = 0.0f; y = 0.0f; }
+
+	/// Set this vector to some specified coordinates.
+	void Set(float32 x_, float32 y_) { x = x_; y = y_; }
+
+	/// Negate this vector.
+	b2Vec2 operator -() const { b2Vec2 v; v.Set(-x, -y); return v; }
+
+	/// Read from and indexed element.
+	float32 operator () (int32 i) const
+	{
+		return (&x)[i];
+	}
+
+	/// Write to an indexed element.
+	float32& operator () (int32 i)
+	{
+		return (&x)[i];
+	}
+
+	/// Add a vector to this vector.
+	void operator += (const b2Vec2& v)
+	{
+		x += v.x; y += v.y;
+	}
+
+	/// Subtract a vector from this vector.
+	void operator -= (const b2Vec2& v)
+	{
+		x -= v.x; y -= v.y;
+	}
+
+	/// Multiply this vector by a scalar.
+	void operator *= (float32 a)
+	{
+		x *= a; y *= a;
+	}
+
+	/// Get the length of this vector (the norm).
+	float32 Length() const
+	{
+		return b2Sqrt(x * x + y * y);
+	}
+
+	/// Get the length squared. For performance, use this instead of
+	/// b2Vec2::Length (if possible).
+	float32 LengthSquared() const
+	{
+		return x * x + y * y;
+	}
+
+	/// Convert this vector into a unit vector. Returns the length.
+	float32 Normalize()
+	{
+		float32 length = Length();
+		if (length < b2_epsilon)
+		{
+			return 0.0f;
+		}
+		float32 invLength = 1.0f / length;
+		x *= invLength;
+		y *= invLength;
+
+		return length;
+	}
+
+	/// Does this vector contain finite coordinates?
+	bool IsValid() const
+	{
+		return b2IsValid(x) && b2IsValid(y);
+	}
+
+	/// Get the skew vector such that dot(skew_vec, other) == cross(vec, other)
+	b2Vec2 Skew() const
+	{
+		return b2Vec2(-y, x);
+	}
+
+	float32 x, y;
+};
+
+/// Add a float to a vector.
+inline b2Vec2 operator + (const b2Vec2& v, float f)
+{
+	return b2Vec2(v.x + f, v.y + f);
+}
+
+/// Substract a float from a vector.
+inline b2Vec2 operator - (const b2Vec2& v, float f)
+{
+	return b2Vec2(v.x - f, v.y - f);
+}
+
+/// Multiply a float with a vector.
+inline b2Vec2 operator * (const b2Vec2& v, float f)
+{
+	return b2Vec2(v.x * f, v.y * f);
+}
+
+/// Divide a vector by a float.
+inline b2Vec2 operator / (const b2Vec2& v, float f)
+{
+	return b2Vec2(v.x / f, v.y / f);
+}
+
+/// A 3D column vector with 3 elements.
+struct b2Vec3
+{
+	/// Default constructor does nothing (for performance).
+	b2Vec3() {}
+
+	/// Construct using coordinates.
+	b2Vec3(float32 x, float32 y, float32 z) : x(x), y(y), z(z) {}
+
+	/// Set this vector to all zeros.
+	void SetZero() { x = 0.0f; y = 0.0f; z = 0.0f; }
+
+	/// Set this vector to some specified coordinates.
+	void Set(float32 x_, float32 y_, float32 z_) { x = x_; y = y_; z = z_; }
+
+	/// Negate this vector.
+	b2Vec3 operator -() const { b2Vec3 v; v.Set(-x, -y, -z); return v; }
+
+	/// Add a vector to this vector.
+	void operator += (const b2Vec3& v)
+	{
+		x += v.x; y += v.y; z += v.z;
+	}
+
+	/// Subtract a vector from this vector.
+	void operator -= (const b2Vec3& v)
+	{
+		x -= v.x; y -= v.y; z -= v.z;
+	}
+
+	/// Multiply this vector by a scalar.
+	void operator *= (float32 s)
+	{
+		x *= s; y *= s; z *= s;
+	}
+
+		/// Get the length of this vector (the norm).
+	float32 Length() const
+	{
+		return b2Sqrt(x * x + y * y + z * z);
+	}
+
+	/// Convert this vector into a unit vector. Returns the length.
+	float32 Normalize()
+	{
+		float32 length = Length();
+		if (length < b2_epsilon)
+		{
+			return 0.0f;
+		}
+		float32 invLength = 1.0f / length;
+		x *= invLength;
+		y *= invLength;
+		z *= invLength;
+
+		return length;
+	}
+
+	float32 x, y, z;
+};
+
+/// A 4D column vector with 4 elements.
+struct b2Vec4
+{
+	/// Default constructor does nothing (for performance).
+	b2Vec4() {}
+
+	/// Construct using coordinates.
+	b2Vec4(float32 x, float32 y, float32 z, float32 w) : x(x), y(y), z(z), w(w) {}
+
+	float32 x, y, z, w;
+};
+
+/// A 2-by-2 matrix. Stored in column-major order.
+struct b2Mat22
+{
+	/// The default constructor does nothing (for performance).
+	b2Mat22() {}
+
+	/// Construct this matrix using columns.
+	b2Mat22(const b2Vec2& c1, const b2Vec2& c2)
+	{
+		ex = c1;
+		ey = c2;
+	}
+
+	/// Construct this matrix using scalars.
+	b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22)
+	{
+		ex.x = a11; ex.y = a21;
+		ey.x = a12; ey.y = a22;
+	}
+
+	/// Initialize this matrix using columns.
+	void Set(const b2Vec2& c1, const b2Vec2& c2)
+	{
+		ex = c1;
+		ey = c2;
+	}
+
+	/// Set this to the identity matrix.
+	void SetIdentity()
+	{
+		ex.x = 1.0f; ey.x = 0.0f;
+		ex.y = 0.0f; ey.y = 1.0f;
+	}
+
+	/// Set this matrix to all zeros.
+	void SetZero()
+	{
+		ex.x = 0.0f; ey.x = 0.0f;
+		ex.y = 0.0f; ey.y = 0.0f;
+	}
+
+	b2Mat22 GetInverse() const
+	{
+		float32 a = ex.x, b = ey.x, c = ex.y, d = ey.y;
+		b2Mat22 B;
+		float32 det = a * d - b * c;
+		if (det != 0.0f)
+		{
+			det = 1.0f / det;
+		}
+		B.ex.x =  det * d;	B.ey.x = -det * b;
+		B.ex.y = -det * c;	B.ey.y =  det * a;
+		return B;
+	}
+
+	/// Solve A * x = b, where b is a column vector. This is more efficient
+	/// than computing the inverse in one-shot cases.
+	b2Vec2 Solve(const b2Vec2& b) const
+	{
+		float32 a11 = ex.x, a12 = ey.x, a21 = ex.y, a22 = ey.y;
+		float32 det = a11 * a22 - a12 * a21;
+		if (det != 0.0f)
+		{
+			det = 1.0f / det;
+		}
+		b2Vec2 x;
+		x.x = det * (a22 * b.x - a12 * b.y);
+		x.y = det * (a11 * b.y - a21 * b.x);
+		return x;
+	}
+
+	b2Vec2 ex, ey;
+};
+
+/// A 3-by-3 matrix. Stored in column-major order.
+struct b2Mat33
+{
+	/// The default constructor does nothing (for performance).
+	b2Mat33() {}
+
+	/// Construct this matrix using columns.
+	b2Mat33(const b2Vec3& c1, const b2Vec3& c2, const b2Vec3& c3)
+	{
+		ex = c1;
+		ey = c2;
+		ez = c3;
+	}
+
+	/// Set this matrix to all zeros.
+	void SetZero()
+	{
+		ex.SetZero();
+		ey.SetZero();
+		ez.SetZero();
+	}
+
+	/// Solve A * x = b, where b is a column vector. This is more efficient
+	/// than computing the inverse in one-shot cases.
+	b2Vec3 Solve33(const b2Vec3& b) const;
+
+	/// Solve A * x = b, where b is a column vector. This is more efficient
+	/// than computing the inverse in one-shot cases. Solve only the upper
+	/// 2-by-2 matrix equation.
+	b2Vec2 Solve22(const b2Vec2& b) const;
+
+	/// Get the inverse of this matrix as a 2-by-2.
+	/// Returns the zero matrix if singular.
+	void GetInverse22(b2Mat33* M) const;
+
+	/// Get the symmetric inverse of this matrix as a 3-by-3.
+	/// Returns the zero matrix if singular.
+	void GetSymInverse33(b2Mat33* M) const;
+
+	b2Vec3 ex, ey, ez;
+};
+
+/// Rotation
+struct b2Rot
+{
+	b2Rot() {}
+
+	/// Initialize from an angle in radians
+	explicit b2Rot(float32 angle)
+	{
+		/// TODO_ERIN optimize
+		s = sinf(angle);
+		c = cosf(angle);
+	}
+
+	/// Set using an angle in radians.
+	void Set(float32 angle)
+	{
+		/// TODO_ERIN optimize
+		s = sinf(angle);
+		c = cosf(angle);
+	}
+
+	/// Set to the identity rotation
+	void SetIdentity()
+	{
+		s = 0.0f;
+		c = 1.0f;
+	}
+
+	/// Get the angle in radians
+	float32 GetAngle() const
+	{
+		return b2Atan2(s, c);
+	}
+
+	/// Get the x-axis
+	b2Vec2 GetXAxis() const
+	{
+		return b2Vec2(c, s);
+	}
+
+	/// Get the u-axis
+	b2Vec2 GetYAxis() const
+	{
+		return b2Vec2(-s, c);
+	}
+
+	/// Sine and cosine
+	float32 s, c;
+};
+
+/// A transform contains translation and rotation. It is used to represent
+/// the position and orientation of rigid frames.
+struct b2Transform
+{
+	/// The default constructor does nothing.
+	b2Transform() {}
+
+	/// Initialize using a position vector and a rotation.
+	b2Transform(const b2Vec2& position, const b2Rot& rotation) : p(position), q(rotation) {}
+
+	/// Set this to the identity transform.
+	void SetIdentity()
+	{
+		p.SetZero();
+		q.SetIdentity();
+	}
+
+	/// Set this based on the position and angle.
+	void Set(const b2Vec2& position, float32 angle)
+	{
+		p = position;
+		q.Set(angle);
+	}
+
+#if LIQUIDFUN_EXTERNAL_LANGUAGE_API
+	/// Get x-coordinate of p.
+	float32 GetPositionX() const { return p.x; }
+
+	/// Get y-coordinate of p.
+	float32 GetPositionY() const { return p.y; }
+
+	/// Get sine-component of q.
+	float32 GetRotationSin() const { return q.s; }
+
+	/// Get cosine-component of q.
+	float32 GetRotationCos() const { return q.c; }
+#endif // LIQUIDFUN_EXTERNAL_LANGUAGE_API
+
+	b2Vec2 p;
+	b2Rot q;
+};
+
+/// This describes the motion of a body/shape for TOI computation.
+/// Shapes are defined with respect to the body origin, which may
+/// no coincide with the center of mass. However, to support dynamics
+/// we must interpolate the center of mass position.
+struct b2Sweep
+{
+	/// Get the interpolated transform at a specific time.
+	/// @param beta is a factor in [0,1], where 0 indicates alpha0.
+	void GetTransform(b2Transform* xfb, float32 beta) const;
+
+	/// Advance the sweep forward, yielding a new initial state.
+	/// @param alpha the new initial time.
+	void Advance(float32 alpha);
+
+	/// Normalize the angles.
+	void Normalize();
+
+	b2Vec2 localCenter;	///< local center of mass position
+	b2Vec2 c0, c;		///< center world positions
+	float32 a0, a;		///< world angles
+
+	/// Fraction of the current time step in the range [0,1]
+	/// c0 and a0 are the positions at alpha0.
+	float32 alpha0;
+};
+
+/// Useful constant
+extern const b2Vec2 b2Vec2_zero;
+
+/// Perform the dot product on two vectors.
+inline float32 b2Dot(const b2Vec2& a, const b2Vec2& b)
+{
+	return a.x * b.x + a.y * b.y;
+}
+
+/// Perform the cross product on two vectors. In 2D this produces a scalar.
+inline float32 b2Cross(const b2Vec2& a, const b2Vec2& b)
+{
+	return a.x * b.y - a.y * b.x;
+}
+
+/// Perform the cross product on a vector and a scalar. In 2D this produces
+/// a vector.
+inline b2Vec2 b2Cross(const b2Vec2& a, float32 s)
+{
+	return b2Vec2(s * a.y, -s * a.x);
+}
+
+/// Perform the cross product on a scalar and a vector. In 2D this produces
+/// a vector.
+inline b2Vec2 b2Cross(float32 s, const b2Vec2& a)
+{
+	return b2Vec2(-s * a.y, s * a.x);
+}
+
+/// Multiply a matrix times a vector. If a rotation matrix is provided,
+/// then this transforms the vector from one frame to another.
+inline b2Vec2 b2Mul(const b2Mat22& A, const b2Vec2& v)
+{
+	return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y);
+}
+
+/// Multiply a matrix transpose times a vector. If a rotation matrix is provided,
+/// then this transforms the vector from one frame to another (inverse transform).
+inline b2Vec2 b2MulT(const b2Mat22& A, const b2Vec2& v)
+{
+	return b2Vec2(b2Dot(v, A.ex), b2Dot(v, A.ey));
+}
+
+/// Add two vectors component-wise.
+inline b2Vec2 operator + (const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(a.x + b.x, a.y + b.y);
+}
+
+/// Subtract two vectors component-wise.
+inline b2Vec2 operator - (const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(a.x - b.x, a.y - b.y);
+}
+
+inline b2Vec2 operator * (float32 s, const b2Vec2& a)
+{
+	return b2Vec2(s * a.x, s * a.y);
+}
+
+inline bool operator == (const b2Vec2& a, const b2Vec2& b)
+{
+	return a.x == b.x && a.y == b.y;
+}
+
+inline bool operator != (const b2Vec2& a, const b2Vec2& b)
+{
+	return !operator==(a, b);
+}
+
+inline float32 b2Distance(const b2Vec2& a, const b2Vec2& b)
+{
+	b2Vec2 c = a - b;
+	return c.Length();
+}
+
+inline float32 b2DistanceSquared(const b2Vec2& a, const b2Vec2& b)
+{
+	b2Vec2 c = a - b;
+	return b2Dot(c, c);
+}
+
+inline b2Vec3 operator * (float32 s, const b2Vec3& a)
+{
+	return b2Vec3(s * a.x, s * a.y, s * a.z);
+}
+
+/// Add two vectors component-wise.
+inline b2Vec3 operator + (const b2Vec3& a, const b2Vec3& b)
+{
+	return b2Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+
+/// Subtract two vectors component-wise.
+inline b2Vec3 operator - (const b2Vec3& a, const b2Vec3& b)
+{
+	return b2Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+
+/// Perform the dot product on two vectors.
+inline float32 b2Dot(const b2Vec3& a, const b2Vec3& b)
+{
+	return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+
+/// Perform the cross product on two vectors.
+inline b2Vec3 b2Cross(const b2Vec3& a, const b2Vec3& b)
+{
+	return b2Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
+}
+
+inline b2Mat22 operator + (const b2Mat22& A, const b2Mat22& B)
+{
+	return b2Mat22(A.ex + B.ex, A.ey + B.ey);
+}
+
+// A * B
+inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B)
+{
+	return b2Mat22(b2Mul(A, B.ex), b2Mul(A, B.ey));
+}
+
+// A^T * B
+inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B)
+{
+	b2Vec2 c1(b2Dot(A.ex, B.ex), b2Dot(A.ey, B.ex));
+	b2Vec2 c2(b2Dot(A.ex, B.ey), b2Dot(A.ey, B.ey));
+	return b2Mat22(c1, c2);
+}
+
+/// Multiply a matrix times a vector.
+inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v)
+{
+	return v.x * A.ex + v.y * A.ey + v.z * A.ez;
+}
+
+/// Multiply a matrix times a vector.
+inline b2Vec2 b2Mul22(const b2Mat33& A, const b2Vec2& v)
+{
+	return b2Vec2(A.ex.x * v.x + A.ey.x * v.y, A.ex.y * v.x + A.ey.y * v.y);
+}
+
+/// Multiply two rotations: q * r
+inline b2Rot b2Mul(const b2Rot& q, const b2Rot& r)
+{
+	// [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
+	// [qs  qc]   [rs  rc]   [qs*rc+qc*rs -qs*rs+qc*rc]
+	// s = qs * rc + qc * rs
+	// c = qc * rc - qs * rs
+	b2Rot qr;
+	qr.s = q.s * r.c + q.c * r.s;
+	qr.c = q.c * r.c - q.s * r.s;
+	return qr;
+}
+
+/// Transpose multiply two rotations: qT * r
+inline b2Rot b2MulT(const b2Rot& q, const b2Rot& r)
+{
+	// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
+	// [-qs qc]   [rs  rc]   [-qs*rc+qc*rs qs*rs+qc*rc]
+	// s = qc * rs - qs * rc
+	// c = qc * rc + qs * rs
+	b2Rot qr;
+	qr.s = q.c * r.s - q.s * r.c;
+	qr.c = q.c * r.c + q.s * r.s;
+	return qr;
+}
+
+/// Rotate a vector
+inline b2Vec2 b2Mul(const b2Rot& q, const b2Vec2& v)
+{
+	return b2Vec2(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);
+}
+
+/// Inverse rotate a vector
+inline b2Vec2 b2MulT(const b2Rot& q, const b2Vec2& v)
+{
+	return b2Vec2(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);
+}
+
+inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v)
+{
+	float32 x = (T.q.c * v.x - T.q.s * v.y) + T.p.x;
+	float32 y = (T.q.s * v.x + T.q.c * v.y) + T.p.y;
+
+	return b2Vec2(x, y);
+}
+
+inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v)
+{
+	float32 px = v.x - T.p.x;
+	float32 py = v.y - T.p.y;
+	float32 x = (T.q.c * px + T.q.s * py);
+	float32 y = (-T.q.s * px + T.q.c * py);
+
+	return b2Vec2(x, y);
+}
+
+// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p
+//    = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p
+inline b2Transform b2Mul(const b2Transform& A, const b2Transform& B)
+{
+	b2Transform C;
+	C.q = b2Mul(A.q, B.q);
+	C.p = b2Mul(A.q, B.p) + A.p;
+	return C;
+}
+
+// v2 = A.q' * (B.q * v1 + B.p - A.p)
+//    = A.q' * B.q * v1 + A.q' * (B.p - A.p)
+inline b2Transform b2MulT(const b2Transform& A, const b2Transform& B)
+{
+	b2Transform C;
+	C.q = b2MulT(A.q, B.q);
+	C.p = b2MulT(A.q, B.p - A.p);
+	return C;
+}
+
+template <typename T>
+inline T b2Abs(T a)
+{
+	return a > T(0) ? a : -a;
+}
+
+inline b2Vec2 b2Abs(const b2Vec2& a)
+{
+	return b2Vec2(b2Abs(a.x), b2Abs(a.y));
+}
+
+inline b2Mat22 b2Abs(const b2Mat22& A)
+{
+	return b2Mat22(b2Abs(A.ex), b2Abs(A.ey));
+}
+
+template <typename T>
+inline T b2Min(T a, T b)
+{
+	return a < b ? a : b;
+}
+
+inline b2Vec2 b2Min(const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(b2Min(a.x, b.x), b2Min(a.y, b.y));
+}
+
+template <typename T>
+inline T b2Max(T a, T b)
+{
+	return a > b ? a : b;
+}
+
+inline b2Vec2 b2Max(const b2Vec2& a, const b2Vec2& b)
+{
+	return b2Vec2(b2Max(a.x, b.x), b2Max(a.y, b.y));
+}
+
+template <typename T>
+inline T b2Clamp(T a, T low, T high)
+{
+	return b2Max(low, b2Min(a, high));
+}
+
+inline b2Vec2 b2Clamp(const b2Vec2& a, const b2Vec2& low, const b2Vec2& high)
+{
+	return b2Max(low, b2Min(a, high));
+}
+
+template<typename T> inline void b2Swap(T& a, T& b)
+{
+	T tmp = a;
+	a = b;
+	b = tmp;
+}
+
+/// "Next Largest Power of 2
+/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
+/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
+/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
+/// largest power of 2. For a 32-bit value:"
+inline uint32 b2NextPowerOfTwo(uint32 x)
+{
+	x |= (x >> 1);
+	x |= (x >> 2);
+	x |= (x >> 4);
+	x |= (x >> 8);
+	x |= (x >> 16);
+	return x + 1;
+}
+
+inline bool b2IsPowerOfTwo(uint32 x)
+{
+	bool result = x > 0 && (x & (x - 1)) == 0;
+	return result;
+}
+
+inline void b2Sweep::GetTransform(b2Transform* xf, float32 beta) const
+{
+	xf->p = (1.0f - beta) * c0 + beta * c;
+	float32 angle = (1.0f - beta) * a0 + beta * a;
+	xf->q.Set(angle);
+
+	// Shift to origin
+	xf->p -= b2Mul(xf->q, localCenter);
+}
+
+inline void b2Sweep::Advance(float32 alpha)
+{
+	b2Assert(alpha0 < 1.0f);
+	float32 beta = (alpha - alpha0) / (1.0f - alpha0);
+	c0 += beta * (c - c0);
+	a0 += beta * (a - a0);
+	alpha0 = alpha;
+}
+
+/// Normalize an angle in radians to be between -pi and pi
+inline void b2Sweep::Normalize()
+{
+	float32 twoPi = 2.0f * b2_pi;
+	float32 d =  twoPi * floorf(a0 / twoPi);
+	a0 -= d;
+	a -= d;
+}
+
+#endif

+ 136 - 44
engine/source/Box2D/Common/b2Settings.cpp

@@ -1,44 +1,136 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Common/b2Settings.h>
-#include <cstdlib>
-#include <cstdio>
-#include <cstdarg>
-
-b2Version b2_version = {2, 3, 0};
-
-// Memory allocators. Modify these to use your own allocator.
-void* b2Alloc(int32 size)
-{
-	return malloc(size);
-}
-
-void b2Free(void* mem)
-{
-	free(mem);
-}
-
-// You can modify this to use your logging facility.
-void b2Log(const char* string, ...)
-{
-	va_list args;
-	va_start(args, string);
-	vprintf(string, args);
-	va_end(args);
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Settings.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+b2Version b2_version = {2, 3, 0};
+
+#define LIQUIDFUN_VERSION_MAJOR 1
+#define LIQUIDFUN_VERSION_MINOR 1
+#define LIQUIDFUN_VERSION_REVISION 0
+#define LIQUIDFUN_STRING_EXPAND(X) #X
+#define LIQUIDFUN_STRING(X) LIQUIDFUN_STRING_EXPAND(X)
+
+static void* b2AllocDefault(int32 size, void* callbackData);
+static void b2FreeDefault(void* mem, void* callbackData);
+
+const b2Version b2_liquidFunVersion = {
+	LIQUIDFUN_VERSION_MAJOR, LIQUIDFUN_VERSION_MINOR,
+	LIQUIDFUN_VERSION_REVISION,
+};
+
+const char *b2_liquidFunVersionString =
+	"LiquidFun "
+	LIQUIDFUN_STRING(LIQUIDFUN_VERSION_MAJOR) "."
+	LIQUIDFUN_STRING(LIQUIDFUN_VERSION_MINOR) "."
+	LIQUIDFUN_STRING(LIQUIDFUN_VERSION_REVISION);
+
+static int32 b2_numAllocs = 0;
+
+// Initialize default allocator.
+static b2AllocFunction b2_allocCallback = b2AllocDefault;
+static b2FreeFunction b2_freeCallback = b2FreeDefault;
+static void *b2_callbackData = NULL;
+
+// Default implementation of b2AllocFunction.
+static void* b2AllocDefault(int32 size, void* callbackData)
+{
+	B2_NOT_USED(callbackData);
+	return malloc(size);
+}
+
+// Default implementation of b2FreeFunction.
+static void b2FreeDefault(void* mem, void* callbackData)
+{
+	B2_NOT_USED(callbackData);
+	free(mem);
+}
+
+/// Set alloc and free callbacks to override the default behavior of using
+/// malloc() and free() for dynamic memory allocation.
+/// Set allocCallback and freeCallback to NULL to restore the default
+/// allocator (malloc / free).
+void b2SetAllocFreeCallbacks(b2AllocFunction allocCallback,
+							 b2FreeFunction freeCallback, void* callbackData)
+{
+	b2Assert((allocCallback && freeCallback) ||
+			 (!allocCallback && !freeCallback));
+	b2Assert(0 == b2GetNumAllocs());
+	if (allocCallback && freeCallback)
+	{
+		b2_allocCallback = allocCallback;
+		b2_freeCallback = freeCallback;
+		b2_callbackData = callbackData;
+	}
+	else
+	{
+		b2_allocCallback = b2AllocDefault;
+		b2_freeCallback = b2FreeDefault;
+		b2_callbackData = NULL;
+	}
+}
+
+// Memory allocators. Modify these to use your own allocator.
+void* b2Alloc(int32 size)
+{
+	b2_numAllocs++;
+	return b2_allocCallback(size, b2_callbackData);
+}
+
+void b2Free(void* mem)
+{
+	b2_numAllocs--;
+	b2_freeCallback(mem, b2_callbackData);
+}
+
+void b2SetNumAllocs(const int32 numAllocs)
+{
+	b2_numAllocs = numAllocs;
+}
+
+int32 b2GetNumAllocs()
+{
+	return b2_numAllocs;
+}
+
+// You can modify this to use your logging facility.
+void b2Log(const char* string, ...)
+{
+#if DEBUG
+	va_list args;
+	va_start(args, string);
+	vprintf(string, args);
+	va_end(args);
+#else
+	B2_NOT_USED(string);
+#endif
+}
+
+class Validator
+{
+public:
+	Validator()
+	{
+		b2Assert(sizeof(uint64)==8);
+		b2Assert(sizeof(int64)==8);
+	}
+} validate;

+ 267 - 150
engine/source/Box2D/Common/b2Settings.h

@@ -1,150 +1,267 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_SETTINGS_H
-#define B2_SETTINGS_H
-
-#include <cassert>
-#include <cmath>
-
-#define B2_NOT_USED(x) ((void)(x))
-#define b2Assert(A) assert(A)
-
-typedef signed char	int8;
-typedef signed short int16;
-typedef signed int int32;
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-typedef float float32;
-typedef double float64;
-
-#define	b2_maxFloat		FLT_MAX
-#define	b2_epsilon		FLT_EPSILON
-#define b2_pi			3.14159265359f
-
-/// @file
-/// Global tuning constants based on meters-kilograms-seconds (MKS) units.
-///
-
-// Collision
-
-/// The maximum number of contact points between two convex shapes. Do
-/// not change this value.
-#define b2_maxManifoldPoints	2
-
-/// The maximum number of vertices on a convex polygon. You cannot increase
-/// this too much because b2BlockAllocator has a maximum object size.
-#define b2_maxPolygonVertices	8
-
-/// This is used to fatten AABBs in the dynamic tree. This allows proxies
-/// to move by a small amount without triggering a tree adjustment.
-/// This is in meters.
-#define b2_aabbExtension		0.1f
-
-/// This is used to fatten AABBs in the dynamic tree. This is used to predict
-/// the future position based on the current displacement.
-/// This is a dimensionless multiplier.
-#define b2_aabbMultiplier		2.0f
-
-/// A small length used as a collision and constraint tolerance. Usually it is
-/// chosen to be numerically significant, but visually insignificant.
-#define b2_linearSlop			0.005f
-
-/// A small angle used as a collision and constraint tolerance. Usually it is
-/// chosen to be numerically significant, but visually insignificant.
-#define b2_angularSlop			(2.0f / 180.0f * b2_pi)
-
-/// The radius of the polygon/edge shape skin. This should not be modified. Making
-/// this smaller means polygons will have an insufficient buffer for continuous collision.
-/// Making it larger may create artifacts for vertex collision.
-#define b2_polygonRadius		(2.0f * b2_linearSlop)
-
-/// Maximum number of sub-steps per contact in continuous physics simulation.
-#define b2_maxSubSteps			8
-
-
-// Dynamics
-
-/// Maximum number of contacts to be handled to solve a TOI impact.
-#define b2_maxTOIContacts			32
-
-/// A velocity threshold for elastic collisions. Any collision with a relative linear
-/// velocity below this threshold will be treated as inelastic.
-#define b2_velocityThreshold		1.0f
-
-/// The maximum linear position correction used when solving constraints. This helps to
-/// prevent overshoot.
-#define b2_maxLinearCorrection		0.2f
-
-/// The maximum angular position correction used when solving constraints. This helps to
-/// prevent overshoot.
-#define b2_maxAngularCorrection		(8.0f / 180.0f * b2_pi)
-
-/// The maximum linear velocity of a body. This limit is very large and is used
-/// to prevent numerical problems. You shouldn't need to adjust this.
-#define b2_maxTranslation			2.0f
-#define b2_maxTranslationSquared	(b2_maxTranslation * b2_maxTranslation)
-
-/// The maximum angular velocity of a body. This limit is very large and is used
-/// to prevent numerical problems. You shouldn't need to adjust this.
-#define b2_maxRotation				(0.5f * b2_pi)
-#define b2_maxRotationSquared		(b2_maxRotation * b2_maxRotation)
-
-/// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
-/// that overlap is removed in one time step. However using values close to 1 often lead
-/// to overshoot.
-#define b2_baumgarte				0.2f
-#define b2_toiBaugarte				0.75f
-
-
-// Sleep
-
-/// The time that a body must be still before it will go to sleep.
-#define b2_timeToSleep				0.5f
-
-/// A body cannot sleep if its linear velocity is above this tolerance.
-#define b2_linearSleepTolerance		0.01f
-
-/// A body cannot sleep if its angular velocity is above this tolerance.
-#define b2_angularSleepTolerance	(2.0f / 180.0f * b2_pi)
-
-// Memory Allocation
-
-/// Implement this function to use your own memory allocator.
-void* b2Alloc(int32 size);
-
-/// If you implement b2Alloc, you should also implement this function.
-void b2Free(void* mem);
-
-/// Logging function.
-void b2Log(const char* string, ...);
-
-/// Version numbering scheme.
-/// See http://en.wikipedia.org/wiki/Software_versioning
-struct b2Version
-{
-	int32 major;		///< significant changes
-	int32 minor;		///< incremental changes
-	int32 revision;		///< bug fixes
-};
-
-/// Current version.
-extern b2Version b2_version;
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_SETTINGS_H
+#define B2_SETTINGS_H
+
+#include <stddef.h>
+#include <assert.h>
+#include <float.h>
+
+#define B2_NOT_USED(x) ((void)(x))
+#if DEBUG && !defined(NDEBUG)
+#define b2Assert(A) assert(A)
+#define B2_ASSERT_ENABLED 1
+#else
+#define b2Assert(A)
+#define B2_ASSERT_ENABLED 0
+#endif
+
+// Statement which is compiled out when DEBUG isn't defined.
+#if DEBUG
+#define B2_DEBUG_STATEMENT(A) A
+#else
+#define B2_DEBUG_STATEMENT(A)
+#endif  // DEBUG
+
+// Calculate the size of a static array.
+#define B2_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+typedef signed char	int8;
+typedef signed short int16;
+typedef signed int int32;
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef float float32;
+typedef double float64;
+
+#ifdef WIN32
+typedef __int64   int64;
+typedef unsigned __int64   uint64;
+#else // !WIN32
+typedef long long int64;
+typedef unsigned long long uint64;
+#endif
+
+#define	b2_maxFloat		FLT_MAX
+#define	b2_epsilon		FLT_EPSILON
+#define b2_pi			3.14159265359f
+
+#if !defined(b2Inline)
+#if defined(__GNUC__)
+#define b2Inline __attribute__((always_inline))
+#else
+#define b2Inline inline
+#endif // defined(__GNUC__)
+#endif // !defined(b2Inline)
+
+// We expand the API so that other languages (e.g. Java) can call into
+// our C++ more easily. Only set if when the flag is not externally defined.
+#if !defined(LIQUIDFUN_EXTERNAL_LANGUAGE_API)
+#if SWIG || LIQUIDFUN_UNIT_TESTS
+#define LIQUIDFUN_EXTERNAL_LANGUAGE_API 1
+#else
+#define LIQUIDFUN_EXTERNAL_LANGUAGE_API 0
+#endif
+#endif
+
+/// @file
+/// Global tuning constants based on meters-kilograms-seconds (MKS) units.
+///
+
+// Collision
+
+/// The maximum number of contact points between two convex shapes. Do
+/// not change this value.
+#define b2_maxManifoldPoints	2
+
+/// The maximum number of vertices on a convex polygon. You cannot increase
+/// this too much because b2BlockAllocator has a maximum object size.
+#define b2_maxPolygonVertices	8
+
+/// This is used to fatten AABBs in the dynamic tree. This allows proxies
+/// to move by a small amount without triggering a tree adjustment.
+/// This is in meters.
+#define b2_aabbExtension		0.1f
+
+/// This is used to fatten AABBs in the dynamic tree. This is used to predict
+/// the future position based on the current displacement.
+/// This is a dimensionless multiplier.
+#define b2_aabbMultiplier		2.0f
+
+/// A small length used as a collision and constraint tolerance. Usually it is
+/// chosen to be numerically significant, but visually insignificant.
+#define b2_linearSlop			0.005f
+
+/// A small angle used as a collision and constraint tolerance. Usually it is
+/// chosen to be numerically significant, but visually insignificant.
+#define b2_angularSlop			(2.0f / 180.0f * b2_pi)
+
+/// The radius of the polygon/edge shape skin. This should not be modified. Making
+/// this smaller means polygons will have an insufficient buffer for continuous collision.
+/// Making it larger may create artifacts for vertex collision.
+#define b2_polygonRadius		(2.0f * b2_linearSlop)
+
+/// Maximum number of sub-steps per contact in continuous physics simulation.
+#define b2_maxSubSteps			8
+
+
+// Dynamics
+
+/// Maximum number of contacts to be handled to solve a TOI impact.
+#define b2_maxTOIContacts			32
+
+/// A velocity threshold for elastic collisions. Any collision with a relative linear
+/// velocity below this threshold will be treated as inelastic.
+#define b2_velocityThreshold		1.0f
+
+/// The maximum linear position correction used when solving constraints. This helps to
+/// prevent overshoot.
+#define b2_maxLinearCorrection		0.2f
+
+/// The maximum angular position correction used when solving constraints. This helps to
+/// prevent overshoot.
+#define b2_maxAngularCorrection		(8.0f / 180.0f * b2_pi)
+
+/// The maximum linear velocity of a body. This limit is very large and is used
+/// to prevent numerical problems. You shouldn't need to adjust this.
+#define b2_maxTranslation			2.0f
+#define b2_maxTranslationSquared	(b2_maxTranslation * b2_maxTranslation)
+
+/// The maximum angular velocity of a body. This limit is very large and is used
+/// to prevent numerical problems. You shouldn't need to adjust this.
+#define b2_maxRotation				(0.5f * b2_pi)
+#define b2_maxRotationSquared		(b2_maxRotation * b2_maxRotation)
+
+/// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
+/// that overlap is removed in one time step. However using values close to 1 often lead
+/// to overshoot.
+#define b2_baumgarte				0.2f
+#define b2_toiBaugarte				0.75f
+
+
+// Particle
+
+/// NEON SIMD requires 16-bit particle indices
+#if !defined(B2_USE_16_BIT_PARTICLE_INDICES) && defined(LIQUIDFUN_SIMD_NEON)
+#define B2_USE_16_BIT_PARTICLE_INDICES
+#endif
+
+/// A symbolic constant that stands for particle allocation error.
+#define b2_invalidParticleIndex		(-1)
+
+#ifdef B2_USE_16_BIT_PARTICLE_INDICES
+#define b2_maxParticleIndex			0x7FFF
+#else
+#define b2_maxParticleIndex			0x7FFFFFFF
+#endif
+
+/// The default distance between particles, multiplied by the particle diameter.
+#define b2_particleStride			0.75f
+
+/// The minimum particle weight that produces pressure.
+#define b2_minParticleWeight			1.0f
+
+/// The upper limit for particle pressure.
+#define b2_maxParticlePressure		0.25f
+
+/// The upper limit for force between particles.
+#define b2_maxParticleForce		0.5f
+
+/// The maximum distance between particles in a triad, multiplied by the
+/// particle diameter.
+#define b2_maxTriadDistance			2
+#define b2_maxTriadDistanceSquared		(b2_maxTriadDistance * b2_maxTriadDistance)
+
+/// The initial size of particle data buffers.
+#define b2_minParticleSystemBufferCapacity	256
+
+/// The time into the future that collisions against barrier particles will be detected.
+#define b2_barrierCollisionTime 2.5f
+
+// Sleep
+
+/// The time that a body must be still before it will go to sleep.
+#define b2_timeToSleep				0.5f
+
+/// A body cannot sleep if its linear velocity is above this tolerance.
+#define b2_linearSleepTolerance		0.01f
+
+/// A body cannot sleep if its angular velocity is above this tolerance.
+#define b2_angularSleepTolerance	(2.0f / 180.0f * b2_pi)
+
+// Memory Allocation
+
+/// Implement this function to use your own memory allocator.
+void* b2Alloc(int32 size);
+
+/// If you implement b2Alloc, you should also implement this function.
+void b2Free(void* mem);
+
+/// Use this function to override b2Alloc() without recompiling this library.
+typedef void* (*b2AllocFunction)(int32 size, void* callbackData);
+/// Use this function to override b2Free() without recompiling this library.
+typedef void (*b2FreeFunction)(void* mem, void* callbackData);
+
+/// Set alloc and free callbacks to override the default behavior of using
+/// malloc() and free() for dynamic memory allocation.
+/// Set allocCallback and freeCallback to NULL to restore the default
+/// allocator (malloc / free).
+void b2SetAllocFreeCallbacks(b2AllocFunction allocCallback,
+							 b2FreeFunction freeCallback,
+							 void* callbackData);
+
+/// Set the number of calls to b2Alloc minus the number of calls to b2Free.
+/// This can be used to disable the empty heap check in
+/// b2SetAllocFreeCallbacks() which can be useful for testing.
+void b2SetNumAllocs(const int32 numAllocs);
+
+/// Get number of calls to b2Alloc minus number of calls to b2Free.
+int32 b2GetNumAllocs();
+
+/// Logging function.
+void b2Log(const char* string, ...);
+
+/// Version numbering scheme.
+/// See http://en.wikipedia.org/wiki/Software_versioning
+struct b2Version
+{
+	int32 major;		///< significant changes
+	int32 minor;		///< incremental changes
+	int32 revision;		///< bug fixes
+};
+
+/// Current version.
+/// Version of Box2D, LiquidFun is based upon.
+extern b2Version b2_version;
+
+/// Global variable is used to identify the version of LiquidFun.
+extern const b2Version b2_liquidFunVersion;
+/// String which identifies the current version of LiquidFun.
+/// b2_liquidFunVersionString is used by Google developers to identify which
+/// applications uploaded to Google Play are using this library.  This allows
+/// the development team at Google to determine the popularity of the library.
+/// How it works: Applications that are uploaded to the Google Play Store are
+/// scanned for this version string.  We track which applications are using it
+/// to measure popularity.  You are free to remove it (of course) but we would
+/// appreciate if you left it in.
+extern const char *b2_liquidFunVersionString;
+
+#endif

+ 244 - 0
engine/source/Box2D/Common/b2SlabAllocator.h

@@ -0,0 +1,244 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef B2_SLAB_ALLOCATOR_H
+#define B2_SLAB_ALLOCATOR_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <new>
+#include <Box2D/Common/b2IntrusiveList.h>
+#include <Box2D/Common/b2FreeList.h>
+#include <Box2D/Common/b2Settings.h>
+#include <Box2D/Common/b2TrackedBlock.h>
+
+/// Freelist based allocator for fixed sized items from slabs (memory
+/// preallocated from the heap).
+/// T should be a class which has a default constructor and implements the
+/// member function "b2IntrusiveList* GetListNode()".
+/// All objects in a slab are constructed when a slab is created and destructed
+/// when a slab is freed.
+template<typename T>
+class b2SlabAllocator
+{
+private:
+	// Information about a slab.
+	class Slab
+	{
+	public:
+		/// Initialize a slab with the number of items it contains.
+		Slab(uint32 numberOfItems) :
+			m_numberOfItems(numberOfItems)
+		{
+			B2_NOT_USED(m_padding);
+			// This assumes that this class is packed on at least a 4-byte
+			// boundary with no padding.  Verify the assumption.
+			b2Assert(sizeof(*this) == b2_mallocAlignment);
+		}
+
+		/// Empty destructor.
+		~Slab() { }
+
+		/// Get the number of items in this slab.
+		uint32 GetNumberOfItems() const { return m_numberOfItems; }
+
+		/// Get a pointer to the first item in the slab.
+		T* GetFirstItem() const
+		{
+			return (T*)((uint8*)(this + 1));
+		}
+
+		/// Get a pointer to the end of the slab.
+		/// NOTE: This is a pointer after the last byte of the slab not the
+		/// last item in the slab.
+		T* GetItemEnd() const { return GetFirstItem() + GetNumberOfItems(); }
+
+	private:
+		/// Number of items in the slab.
+		uint32 m_numberOfItems;
+		/// Padding to align the first item in the slab to b2_mallocAlignment.
+		uint8 m_padding[b2_mallocAlignment - sizeof(uint32)];
+	};
+
+public:
+	/// Initialize the allocator to allocate itemsPerSlab of type T for each
+	/// slab that is allocated.
+	b2SlabAllocator(const uint32 itemsPerSlab) :
+		m_itemsPerSlab(itemsPerSlab)
+	{
+	}
+
+	/// Free all allocated slabs.
+	~b2SlabAllocator()
+	{
+		FreeAllSlabs();
+	}
+
+	/// Set size of the next allocated slab using the number of items per
+	/// slab.  Setting this value to zero disables further slab allocation.
+	void SetItemsPerSlab(uint32 itemsPerSlab)
+	{
+		m_itemsPerSlab = itemsPerSlab;
+	}
+
+	// Get the size of the next allocated slab.
+	uint32 GetItemsPerSlab() const
+	{
+		return m_itemsPerSlab;
+	}
+
+	/// Allocate a item from the slab.
+	T* Allocate()
+	{
+		// Allocate a slab if needed here.
+		if (m_freeList.GetFreeList()->GetFreeList().IsEmpty() &&
+			!AllocateSlab())
+			return NULL;
+		return m_freeList.Allocate();
+	}
+
+	/// Free an item from the slab.
+	void Free(T *object)
+	{
+		m_freeList.Free(object);
+	}
+
+	/// Allocate a slab, construct instances of T and add them to the free
+	/// pool.
+	bool AllocateSlab()
+	{
+		if (!m_itemsPerSlab) return false;
+		const uint32 slabSize = sizeof(Slab) + (sizeof(T) * m_itemsPerSlab);
+		void* const memory = m_slabs.Allocate(slabSize);
+		if (!memory) return false;
+
+		Slab* const slab = new (BlockGetSlab(memory)) Slab(m_itemsPerSlab);
+		T* item = slab->GetFirstItem();
+		for (uint32 i = 0; i < m_itemsPerSlab; ++i, ++item)
+		{
+			m_freeList.AddToFreeList(new (item) T);
+		}
+		return true;
+	}
+
+	/// Free all slabs.
+	void FreeAllSlabs()
+	{
+		const b2TypedIntrusiveListNode<b2TrackedBlock>& slabList =
+			m_slabs.GetList();
+		while (!slabList.IsEmpty())
+		{
+			FreeSlab(BlockGetSlab(slabList.GetNext()->GetMemory()));
+		}
+	}
+
+	/// Free all empty slabs.
+	/// This method is slow - O(M^N) - since this class doesn't track
+	/// the association between each item and slab.
+	void FreeEmptySlabs()
+	{
+		const b2IntrusiveListNode& freeItemList =
+			m_freeList.GetFreeList()->GetFreeList();
+		const b2IntrusiveListNode* freeItemListTerminator =
+			freeItemList.GetTerminator();
+		const b2TypedIntrusiveListNode<b2TrackedBlock>& slabList =
+			m_slabs.GetList();
+		const b2TypedIntrusiveListNode<b2TrackedBlock>* slabListTerminator =
+			slabList.GetTerminator();
+		b2TrackedBlock* block = slabList.GetNext();
+		while (block != slabListTerminator)
+		{
+			// Get the Slab from the memory associated with the block.
+			Slab* const slab = BlockGetSlab(block->GetMemory());
+			block = block->GetNext();
+
+			// Determine the range of memory the Slab owns.
+			const uint8* const slabItemStart = (uint8*)slab->GetFirstItem();
+			const uint8* const slabItemEnd = (uint8*)slab->GetItemEnd();
+
+			// Count all free items that are owned by the current slab.
+			uint8 freeItems = 0;
+			bool empty = false;
+			for (b2IntrusiveListNode* itemNode = freeItemList.GetNext();
+				 itemNode != freeItemListTerminator;
+				 itemNode = itemNode->GetNext())
+			{
+				const uint8* itemNodeAddress = (uint8*)itemNode;
+				if (itemNodeAddress >= slabItemStart &&
+					itemNodeAddress <= slabItemEnd)
+				{
+					++freeItems;
+					if (slab->GetNumberOfItems() == freeItems)
+					{
+						empty = true;
+						break;
+					}
+				}
+			}
+			// If a slab is empty, free it.
+			if (empty)
+			{
+				FreeSlab(slab);
+			}
+		}
+	}
+
+	/// Get the item allocator freelist.
+	const b2TypedFreeList<T>& GetFreeList() const
+	{
+		return m_freeList;
+	}
+
+private:
+	/// Destroy all objects in a slab and free the slab.
+	void FreeSlab(Slab * const slab)
+	{
+		b2Assert(slab);
+		const uint32 numberOfItems = slab->GetNumberOfItems();
+		T* item = slab->GetFirstItem();
+		for (uint32 i = 0; i < numberOfItems; ++i, ++item)
+		{
+			item->~T();
+		}
+		slab->~Slab();
+		m_slabs.Free(slab);
+	}
+
+	/// Get a pointer to a Slab from a block of memory in m_slabs.
+	Slab* BlockGetSlab(void *memory)
+	{
+		return (Slab*)memory;
+	}
+
+	/// Get a pointer to the first item in the array of items referenced by a
+	/// Slab.
+	T* SlabGetFirstItem(Slab* slab)
+	{
+		return (T*)(slab + 1);
+	}
+
+private:
+	/// Contains a list of b2TrackedBlock instances where each b2TrackedBlock's
+	/// associated user memory contains a Slab followed by instances of T.
+	b2TrackedBlockAllocator m_slabs;
+	/// Number of items to allocate in the next allocated slab.
+	uint32 m_itemsPerSlab;
+	/// Freelist which contains instances of T.
+	b2TypedFreeList<T> m_freeList;
+};
+
+#endif  // B2_SLAB_ALLOCATOR_H

+ 120 - 83
engine/source/Box2D/Common/b2StackAllocator.cpp

@@ -1,83 +1,120 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Common/b2StackAllocator.h>
-#include <Box2D/Common/b2Math.h>
-
-b2StackAllocator::b2StackAllocator()
-{
-	m_index = 0;
-	m_allocation = 0;
-	m_maxAllocation = 0;
-	m_entryCount = 0;
-}
-
-b2StackAllocator::~b2StackAllocator()
-{
-	b2Assert(m_index == 0);
-	b2Assert(m_entryCount == 0);
-}
-
-void* b2StackAllocator::Allocate(int32 size)
-{
-	b2Assert(m_entryCount < b2_maxStackEntries);
-
-	b2StackEntry* entry = m_entries + m_entryCount;
-	entry->size = size;
-	if (m_index + size > b2_stackSize)
-	{
-		entry->data = (char*)b2Alloc(size);
-		entry->usedMalloc = true;
-	}
-	else
-	{
-		entry->data = m_data + m_index;
-		entry->usedMalloc = false;
-		m_index += size;
-	}
-
-	m_allocation += size;
-	m_maxAllocation = b2Max(m_maxAllocation, m_allocation);
-	++m_entryCount;
-
-	return entry->data;
-}
-
-void b2StackAllocator::Free(void* p)
-{
-	b2Assert(m_entryCount > 0);
-	b2StackEntry* entry = m_entries + m_entryCount - 1;
-	b2Assert(p == entry->data);
-	if (entry->usedMalloc)
-	{
-		b2Free(p);
-	}
-	else
-	{
-		m_index -= entry->size;
-	}
-	m_allocation -= entry->size;
-	--m_entryCount;
-
-	p = NULL;
-}
-
-int32 b2StackAllocator::GetMaxAllocation() const
-{
-	return m_maxAllocation;
-}
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2StackAllocator.h>
+#include <Box2D/Common/b2Math.h>
+#include <string.h>
+
+b2StackAllocator::b2StackAllocator()
+{
+	m_index = 0;
+	m_allocation = 0;
+	m_maxAllocation = 0;
+	m_entryCount = 0;
+}
+
+b2StackAllocator::~b2StackAllocator()
+{
+	b2Assert(m_index == 0);
+	b2Assert(m_entryCount == 0);
+}
+
+void* b2StackAllocator::Allocate(int32 size)
+{
+	b2Assert(m_entryCount < b2_maxStackEntries);
+	const int32 roundedSize = (size + ALIGN_MASK) & ~ALIGN_MASK;
+	b2StackEntry* entry = m_entries + m_entryCount;
+	entry->size = roundedSize;
+	if (m_index + roundedSize > b2_stackSize)
+	{
+		entry->data = (char*)b2Alloc(roundedSize);
+		entry->usedMalloc = true;
+	}
+	else
+	{
+		entry->data = m_data + m_index;
+		entry->usedMalloc = false;
+		m_index += roundedSize;
+	}
+
+	m_allocation += roundedSize;
+	m_maxAllocation = b2Max(m_maxAllocation, m_allocation);
+	++m_entryCount;
+
+	return entry->data;
+}
+
+void* b2StackAllocator::Reallocate(void* p, int32 size)
+{
+	b2Assert(m_entryCount > 0);
+	b2StackEntry* entry = m_entries + m_entryCount - 1;
+	b2Assert(p == entry->data);
+	B2_NOT_USED(p);
+	int32 incrementSize = size - entry->size;
+	if (incrementSize > 0)
+	{
+		if (entry->usedMalloc)
+		{
+			void* data = b2Alloc(size);
+			memcpy(data, entry->data, entry->size);
+			b2Free(entry->data);
+			entry->data = (char*)data;
+		}
+		else if (m_index + incrementSize > b2_stackSize)
+		{
+			void* data = b2Alloc(size);
+			memcpy(data, entry->data, entry->size);
+			m_index -= entry->size;
+			entry->data = (char*)data;
+			entry->usedMalloc = true;
+		}
+		else
+		{
+			m_index += incrementSize;
+			m_allocation += incrementSize;
+			m_maxAllocation = b2Max(m_maxAllocation, m_allocation);
+		}
+		entry->size = size;
+	}
+
+	return entry->data;
+}
+
+void b2StackAllocator::Free(void* p)
+{
+	b2Assert(m_entryCount > 0);
+	b2StackEntry* entry = m_entries + m_entryCount - 1;
+	b2Assert(p == entry->data);
+	if (entry->usedMalloc)
+	{
+		b2Free(p);
+	}
+	else
+	{
+		m_index -= entry->size;
+	}
+	m_allocation -= entry->size;
+	--m_entryCount;
+
+	p = NULL;
+}
+
+int32 b2StackAllocator::GetMaxAllocation() const
+{
+	return m_maxAllocation;
+}

+ 64 - 60
engine/source/Box2D/Common/b2StackAllocator.h

@@ -1,60 +1,64 @@
-/*
-* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_STACK_ALLOCATOR_H
-#define B2_STACK_ALLOCATOR_H
-
-#include <Box2D/Common/b2Settings.h>
-
-const int32 b2_stackSize = 100 * 1024;	// 100k
-const int32 b2_maxStackEntries = 32;
-
-struct b2StackEntry
-{
-	char* data;
-	int32 size;
-	bool usedMalloc;
-};
-
-// This is a stack allocator used for fast per step allocations.
-// You must nest allocate/free pairs. The code will assert
-// if you try to interleave multiple allocate/free pairs.
-class b2StackAllocator
-{
-public:
-	b2StackAllocator();
-	~b2StackAllocator();
-
-	void* Allocate(int32 size);
-	void Free(void* p);
-
-	int32 GetMaxAllocation() const;
-
-private:
-
-	char m_data[b2_stackSize];
-	int32 m_index;
-
-	int32 m_allocation;
-	int32 m_maxAllocation;
-
-	b2StackEntry m_entries[b2_maxStackEntries];
-	int32 m_entryCount;
-};
-
-#endif
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_STACK_ALLOCATOR_H
+#define B2_STACK_ALLOCATOR_H
+
+#include <Box2D/Common/b2Settings.h>
+
+const int32 b2_stackSize = 100 * 1024;	// 100k
+const int32 b2_maxStackEntries = 32;
+
+struct b2StackEntry
+{
+	char* data;
+	int32 size;
+	bool usedMalloc;
+};
+
+// This is a stack allocator used for fast per step allocations.
+// You must nest allocate/free pairs. The code will assert
+// if you try to interleave multiple allocate/free pairs.
+class b2StackAllocator
+{
+public:
+	enum { MIN_ALIGNMENT = sizeof(void*) }; // Must be a power of 2
+	enum { ALIGN_MASK = MIN_ALIGNMENT - 1 };
+
+	b2StackAllocator();
+	~b2StackAllocator();
+
+	void* Allocate(int32 size);
+	void* Reallocate(void* p, int32 size);
+	void Free(void* p);
+
+	int32 GetMaxAllocation() const;
+
+private:
+
+	char m_data[b2_stackSize];
+	int32 m_index;
+
+	int32 m_allocation;
+	int32 m_maxAllocation;
+
+	b2StackEntry m_entries[b2_maxStackEntries];
+	int32 m_entryCount;
+};
+
+#endif

+ 67 - 0
engine/source/Box2D/Common/b2Stat.cpp

@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "b2Stat.h"
+
+#include <algorithm>
+#include <cfloat>
+
+b2Stat::b2Stat()
+{
+	Clear();
+}
+
+void b2Stat::Record( float32 t )
+{
+	m_total += t;
+	m_min = std::min(m_min,t);
+	m_max = std::max(m_max,t);
+	m_count++;
+}
+
+int b2Stat::GetCount() const
+{
+	return m_count;
+}
+
+float32 b2Stat::GetMean() const
+{
+	if (m_count == 0)
+	{
+		return 0.0f;
+	}
+	return (float32)(m_total / m_count);
+}
+
+float32 b2Stat::GetMin() const
+{
+	return m_min;
+}
+
+float32 b2Stat::GetMax() const
+{
+	return m_max;
+}
+
+void b2Stat::Clear()
+{
+	m_count = 0;
+	m_total = 0;
+	m_min = FLT_MAX;
+	m_max = -FLT_MAX;
+}
+

+ 57 - 0
engine/source/Box2D/Common/b2Stat.h

@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2013 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef B2_STAT
+#define B2_STAT
+
+#include <Box2D/Common/b2Settings.h>
+
+/// Calculates min/max/mean of a set of samples
+class b2Stat
+{
+public:
+	b2Stat();
+
+	/// Record a sample
+	void Record( float32 t );
+
+	/// Returns the number of recorded samples
+	int GetCount() const;
+
+	/// Returns the mean of all recorded samples,
+	/// Returns 0 if there are no recorded samples
+	float32 GetMean() const;
+
+	/// Returns the min of all recorded samples,
+	/// FLT_MAX if there are no recorded samples
+	float32 GetMin() const;
+
+	/// Returns the max of all recorded samples,
+	/// -FLT_MAX if there are no recorded samples
+	float32 GetMax() const;
+
+	/// Erase all recorded samples
+	void Clear();
+private:
+
+	int m_count;
+	float64 m_total;
+	float32 m_min;
+	float32 m_max;
+};
+
+#endif

+ 134 - 100
engine/source/Box2D/Common/b2Timer.cpp

@@ -1,100 +1,134 @@
-/*
-* Copyright (c) 2011 Erin Catto http://box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#include <Box2D/Common/b2Timer.h>
-
-#if defined(_WIN32)
-
-float64 b2Timer::s_invFrequency = 0.0f;
-
-#include <windows.h>
-
-b2Timer::b2Timer()
-{
-	LARGE_INTEGER largeInteger;
-
-	if (s_invFrequency == 0.0f)
-	{
-		QueryPerformanceFrequency(&largeInteger);
-		s_invFrequency = float64(largeInteger.QuadPart);
-		if (s_invFrequency > 0.0f)
-		{
-			s_invFrequency = 1000.0f / s_invFrequency;
-		}
-	}
-
-	QueryPerformanceCounter(&largeInteger);
-	m_start = float64(largeInteger.QuadPart);
-}
-
-void b2Timer::Reset()
-{
-	LARGE_INTEGER largeInteger;
-	QueryPerformanceCounter(&largeInteger);
-	m_start = float64(largeInteger.QuadPart);
-}
-
-float32 b2Timer::GetMilliseconds() const
-{
-	LARGE_INTEGER largeInteger;
-	QueryPerformanceCounter(&largeInteger);
-	float64 count = float64(largeInteger.QuadPart);
-	float32 ms = float32(s_invFrequency * (count - m_start));
-	return ms;
-}
-
-#elif defined(__linux__) || defined (__APPLE__)
-
-#include <sys/time.h>
-
-b2Timer::b2Timer()
-{
-    Reset();
-}
-
-void b2Timer::Reset()
-{
-    timeval t;
-    gettimeofday(&t, 0);
-    m_start_sec = t.tv_sec;
-    m_start_msec = t.tv_usec * 0.001f;
-}
-
-float32 b2Timer::GetMilliseconds() const
-{
-    timeval t;
-    gettimeofday(&t, 0);
-    return (t.tv_sec - m_start_sec) * 1000 + t.tv_usec * 0.001f - m_start_msec;
-}
-
-#else
-
-b2Timer::b2Timer()
-{
-}
-
-void b2Timer::Reset()
-{
-}
-
-float32 b2Timer::GetMilliseconds() const
-{
-	return 0.0f;
-}
-
-#endif
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2Timer.h>
+
+#if defined(_WIN32)
+
+float64 b2Timer::s_invFrequency = 0.0f;
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+typedef BOOL (WINAPI *SystemGetTimeFunc)(_Out_ LARGE_INTEGER *lpFrequency);
+SystemGetTimeFunc systemGetTimeFunc = ::QueryPerformanceCounter;
+SystemGetTimeFunc systemGetFreqFunc = ::QueryPerformanceFrequency;
+
+int64 b2Timer::GetTicks()
+{
+	LARGE_INTEGER largeInteger;
+	systemGetTimeFunc(&largeInteger);
+	return largeInteger.QuadPart;
+}
+
+b2Timer::b2Timer()
+{
+	LARGE_INTEGER largeInteger;
+
+	if (s_invFrequency == 0.0f)
+	{
+		systemGetFreqFunc(&largeInteger);
+		s_invFrequency = float64(largeInteger.QuadPart);
+		if (s_invFrequency > 0.0f)
+		{
+			s_invFrequency = 1000.0f / s_invFrequency;
+		}
+	}
+
+	m_start = GetTicks();
+}
+
+void b2Timer::Reset()
+{
+	m_start = GetTicks();
+}
+
+float32 b2Timer::GetMilliseconds() const
+{
+	int64 elapsed = GetTicks() - m_start;
+	return (float32)(s_invFrequency * elapsed);
+}
+
+#elif defined(__linux__) || defined (__APPLE__)
+
+#include <sys/time.h>
+#include <time.h>
+
+// systemGetTimeFunc is defined with external linkage to allow unit
+// test to mock out the system time function
+
+#if defined(__linux__)
+
+typedef int (*SystemGetTimeFunc)(clockid_t clk_id, struct timespec *tp);
+SystemGetTimeFunc systemGetTimeFunc = ::clock_gettime;
+
+#elif defined(__APPLE__)
+
+typedef int (*SystemGetTimeFunc)(struct timeval * tp, void * tzp);
+SystemGetTimeFunc systemGetTimeFunc = ::gettimeofday;
+
+#endif
+
+int64 b2Timer::GetTicks()
+{
+	static const int NSEC_PER_SEC = 1000000000;
+
+#ifdef __linux__
+	timespec ts;
+	systemGetTimeFunc(CLOCK_MONOTONIC,&ts);
+	return ((int64)ts.tv_sec) * NSEC_PER_SEC + ts.tv_nsec;
+#else
+	timeval t;
+	systemGetTimeFunc(&t, 0);
+	return ((int64)t.tv_sec) * NSEC_PER_SEC + t.tv_usec * 1000;
+#endif
+}
+
+b2Timer::b2Timer()
+{
+	Reset();
+}
+
+void b2Timer::Reset()
+{
+	m_start = GetTicks();
+}
+
+float32 b2Timer::GetMilliseconds() const
+{
+	static const float32 kTicksToMs = 0.000001f;
+	return kTicksToMs * (float32)(GetTicks() - m_start);
+}
+
+#else
+
+b2Timer::b2Timer()
+{
+}
+
+void b2Timer::Reset()
+{
+}
+
+float32 b2Timer::GetMilliseconds() const
+{
+	return 0.0f;
+}
+
+#endif

+ 50 - 50
engine/source/Box2D/Common/b2Timer.h

@@ -1,50 +1,50 @@
-/*
-* Copyright (c) 2011 Erin Catto http://box2d.org
-*
-* This software is provided 'as-is', without any express or implied
-* warranty.  In no event will the authors be held liable for any damages
-* arising from the use of this software.
-* Permission is granted to anyone to use this software for any purpose,
-* including commercial applications, and to alter it and redistribute it
-* freely, subject to the following restrictions:
-* 1. The origin of this software must not be misrepresented; you must not
-* claim that you wrote the original software. If you use this software
-* in a product, an acknowledgment in the product documentation would be
-* appreciated but is not required.
-* 2. Altered source versions must be plainly marked as such, and must not be
-* misrepresented as being the original software.
-* 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef B2_TIMER_H
-#define B2_TIMER_H
-
-#include <Box2D/Common/b2Settings.h>
-
-/// Timer for profiling. This has platform specific code and may
-/// not work on every platform.
-class b2Timer
-{
-public:
-
-	/// Constructor
-	b2Timer();
-
-	/// Reset the timer.
-	void Reset();
-
-	/// Get the time since construction or the last reset.
-	float32 GetMilliseconds() const;
-
-private:
-
-#if defined(_WIN32)
-	float64 m_start;
-	static float64 s_invFrequency;
-#elif defined(__linux__) || defined (__APPLE__)
-	unsigned long m_start_sec;
-	unsigned long m_start_msec;
-#endif
-};
-
-#endif
+/*
+* Copyright (c) 2011 Erin Catto http://box2d.org
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_TIMER_H
+#define B2_TIMER_H
+
+#include <Box2D/Common/b2Settings.h>
+
+/// Timer for profiling. This has platform specific code and may
+/// not work on every platform.
+class b2Timer
+{
+public:
+
+	/// Constructor
+	b2Timer();
+
+	/// Reset the timer.
+	void Reset();
+
+	/// Get the time since construction or the last reset.
+	float32 GetMilliseconds() const;
+
+private:
+	/// Get platform specific tick count
+	static int64 GetTicks();
+
+#if defined(_WIN32)
+	static float64 s_invFrequency;
+#endif
+	int64 m_start;
+};
+
+#endif

+ 111 - 0
engine/source/Box2D/Common/b2TrackedBlock.cpp

@@ -0,0 +1,111 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include <Box2D/Common/b2TrackedBlock.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <new>
+
+// Initialize this block with a reference to "this".
+b2TrackedBlock::b2TrackedBlock()
+{
+	b2TrackedBlock** pointerToThis =
+		(b2TrackedBlock**)((uint8*)GetMemory() - sizeof(b2TrackedBlock**));
+	*pointerToThis = this;
+}
+
+/// Get the allocated memory associated with this block.
+void* b2TrackedBlock::GetMemory() const
+{
+	// The size of data in this without padding.
+	static const uint32 kSizeOfThisWithNoPadding =
+		sizeof(*this) - sizeof(m_padding) + sizeof(b2TrackedBlock**);
+
+	// Make sure b2_mallocAlignment is base2.
+	b2Assert(((b2_mallocAlignment - 1) & b2_mallocAlignment) == 0);
+
+	// Round the pointer following data in this to b2_mallocAlignment.
+	uint8* const aligned = (uint8*)(
+		((uintptr_t)this + kSizeOfThisWithNoPadding + b2_mallocAlignment - 1) &
+		~((uintptr_t)b2_mallocAlignment - 1));
+	// Verify offset doesn't overlap data in this.
+	b2Assert((uintptr_t)aligned - (uintptr_t)this >= kSizeOfThisWithNoPadding);
+	return aligned;
+}
+
+/// Allocate a b2TrackedBlock returning a pointer to memory of size
+/// bytes that can be used by the caller.
+void* b2TrackedBlock::Allocate(uint32 size)
+{
+	void* memory = (b2TrackedBlock*)b2Alloc(sizeof(b2TrackedBlock) +
+											size);
+	if (!memory)
+	{
+		return NULL;
+	}
+	return (new(memory) b2TrackedBlock)->GetMemory();
+}
+
+/// Get a b2TrackedBlock from a pointer to memory returned by
+/// b2TrackedBlock::Allocate().
+b2TrackedBlock* b2TrackedBlock::GetFromMemory(void *memory)
+{
+	uint8* const aligned = (uint8*)memory;
+	b2Assert(memory);
+	b2TrackedBlock **blockPtr = (b2TrackedBlock**)(aligned -
+												   sizeof(b2TrackedBlock**));
+	b2Assert(*blockPtr);
+	return *blockPtr;
+}
+
+/// Free a block of memory returned by b2TrackedBlock::Allocate()
+void b2TrackedBlock::Free(void *memory)
+{
+	Free(GetFromMemory(memory));
+}
+
+/// Free a b2TrackedBlock.
+void b2TrackedBlock::Free(b2TrackedBlock *block)
+{
+	b2Assert(block);
+	block->~b2TrackedBlock();
+	b2Free(block);
+}
+
+/// Allocate a block of size bytes using b2TrackedBlock::Allocate().
+void* b2TrackedBlockAllocator::Allocate(uint32 size)
+{
+	void *memory = b2TrackedBlock::Allocate(size);
+	m_blocks.InsertBefore(b2TrackedBlock::GetFromMemory(memory));
+	return memory;
+}
+
+/// Free a block returned by Allocate().
+void b2TrackedBlockAllocator::Free(void *memory)
+{
+	b2TrackedBlock::Free(memory);
+}
+
+/// Free all allocated blocks.
+void b2TrackedBlockAllocator::FreeAll()
+{
+	while (!m_blocks.IsEmpty())
+	{
+		b2TrackedBlock::Free(m_blocks.GetNext());
+	}
+}

+ 92 - 0
engine/source/Box2D/Common/b2TrackedBlock.h

@@ -0,0 +1,92 @@
+/*
+* Copyright (c) 2014 Google, Inc.
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef B2_TRACKED_BLOCK_H
+#define B2_TRACKED_BLOCK_H
+
+#include <Box2D/Common/b2IntrusiveList.h>
+#include <Box2D/Common/b2Settings.h>
+
+/// Alignment (in bytes) of user memory associated with b2TrackedBlock.
+const int32 b2_mallocAlignment = 32;
+
+/// Allocated block of memory that can be tracked in a b2IntrusiveList.
+class b2TrackedBlock : public b2TypedIntrusiveListNode<b2TrackedBlock>
+{
+private:
+	// Initialize this block with a reference to "this".
+	b2TrackedBlock();
+	// Remove the block from the list.
+	~b2TrackedBlock() { }
+
+public:
+	/// Get the allocated memory associated with this block.
+	void* GetMemory() const;
+
+private:
+	// Padding required to align the pointer to user memory in the block
+	// to b2_mallocAlignment.
+	uint8 m_padding[b2_mallocAlignment + sizeof(b2TrackedBlock**)];
+
+public:
+	/// Allocate a b2TrackedBlock returning a pointer to memory of size
+	/// bytes that can be used by the caller.
+	static void* Allocate(uint32 size);
+
+	/// Get a b2TrackedBlock from a pointer to memory returned by
+	/// b2TrackedBlock::Allocate().
+	static b2TrackedBlock* GetFromMemory(void *memory);
+
+	/// Free a block of memory returned by b2TrackedBlock::Allocate()
+	static void Free(void *memory);
+
+	/// Free a b2TrackedBlock.
+	static void Free(b2TrackedBlock *block);
+};
+
+/// Allocator of blocks which are tracked in a list.
+class b2TrackedBlockAllocator
+{
+public:
+	/// Initialize.
+	b2TrackedBlockAllocator() {}
+	/// Free all allocated blocks.
+	~b2TrackedBlockAllocator()
+	{
+		FreeAll();
+	}
+
+	/// Allocate a block of size bytes using b2TrackedBlock::Allocate().
+	void* Allocate(uint32 size);
+
+	/// Free a block returned by Allocate().
+	void Free(void *memory);
+
+	/// Free all allocated blocks.
+	void FreeAll();
+
+	// Get the list of allocated blocks.
+	const b2TypedIntrusiveListNode<b2TrackedBlock>& GetList() const
+	{
+		return m_blocks;
+	}
+
+private:
+	b2TypedIntrusiveListNode<b2TrackedBlock> m_blocks;
+};
+
+#endif  // B2_TRACKED_BLOCK_H

+ 2350 - 0
engine/source/Box2D/Documentation/API-Ref/doxyfile

@@ -0,0 +1,2350 @@
+# Doxyfile 1.8.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+# 
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+# 
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "LiquidFun"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = "../../../Documentation/API-Ref"
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-
+# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,
+# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# Turkish, Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+# 
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+# 
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+# 
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+# 
+# Note For files without extension you can use no_extension as a placeholder.
+# 
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+# 
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+# 
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+# 
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = "../.."
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# 
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+# 
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.md
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+# 
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+# 
+# <filter> <input-file>
+# 
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+# 
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+# 
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+# 
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+# 
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+# 
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+# 
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = ../footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+# 
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+# 
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+# 
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+# 
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+# 
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+# 
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+# 
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+# 
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+# 
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+# 
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+# 
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+# 
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+# 
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = NO
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+# 
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+# 
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# 
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+# 
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES

+ 19 - 0
engine/source/Box2D/Documentation/Building/Building.md

@@ -0,0 +1,19 @@
+Building LiquidFun and Running Examples {#mainpage}
+=======================================
+
+LiquidFun is an extension of [Box2D](http://box2d.org), a 2D physics engine
+for games.
+
+API documentation is located in the Documentation/ folder and referenced
+by our [landing page](../../index.html).
+
+If your project already uses Box2D, please see these instructions for
+[Porting from Box2D](md__porting_from_box2_d.html).
+
+Instructions on how to build for:
+- [Android](md__building_android.html)
+- [iOS](md__buildingi_o_s.html)
+- [Linux](md__building_linux.html)
+- [Windows](md__building_windows.html)
+- [OS X](md__building_o_s_x.html)
+- [JavaScript version](md__building_java_script.html)

+ 117 - 0
engine/source/Box2D/Documentation/Building/BuildingAndroid.md

@@ -0,0 +1,117 @@
+# Building for Android
+
+### Version Requirements
+
+Following are the minimum required versions for the tools and libraries you
+need for building LiquidFun for Android:
+
+-   Android SDK:  Android 2.3.3 (API Level 10)
+-   ADT: 20130917
+-   NDK: android-ndk-r9
+-   NDK plugn for Eclipse: bundled with ADT
+-   cmake (when building from source): 2.8.12.1
+
+### Before Building
+
+-   Install the [Android SDK].
+-   Install the [Android NDK].
+
+### Building
+
+Each LiquidFun project for Android has an associated `AndroidManifest.xml`
+file and `jni` subdirectory.  For samples, `AndroidManifest.xml` contains
+details about how to build an Android package (apk).  For libraries, such as
+LiquidFun and freeglut, the `AndroidManifest.xml` file informs the `ndk-build`
+tool that the directory contains NDK makefiles under the `jni` subdirectory.
+
+The following [Android NDK][] projects live in the liquidfun directory tree.
+
+-   `liquidfun/Box2D` - liquidfun dynamic and static libraries.
+-   `liquidfun/Box2D/HelloWorld` - Non-interactive Hello World sample
+     application.
+-   `liquidfun/Box2D/Testbed` - Interactive Testbed sample application.
+
+To build an [Android NDK][] project:
+
+-   Open a command line window.
+-   Go to the working directory containing the project to build.
+-   Execute ndk-build.
+
+For example, to build the LiquidFun dynamic and static libraries:
+
+    cd liquidfun/Box2D
+    ndk-build
+
+### Executing a Sample
+
+Running a sample requires the Android Development Tools ([ADT][]) plugin and
+the [NDK Eclipse plugin][].
+
+#### Running an application using Eclipse:
+
+-   Build a project using `ndk-build` (see above).
+-   Open [ADT][] Eclipse.
+-   Select "File->Import..." from the menu.
+-   Select "Android > Existing Android Code Into Workspace", and click "Next".
+-   Click the "Browse..." button next to `Root Directory:` and select the
+    project folder (e.g. `liquidfun/Box2D/Testbed`).
+-   Click "Finish". Eclipse imports the project, and displays it in the
+    Package Explorer pane.
+-   Right-click the project, and select "Run->Run As->Android Application"
+    from the menu.
+-   If you do not have a physical device, you must define a virtual one.
+    For details about how to define a virtual device, see [managing avds][].
+    We don’t recommend a virtual device for development.
+
+-   If the target is a physical device, unlock the device and observe the application executing.
+
+#### Build and Run from the Command Line:
+
+It's also possible to use `build_apk.sh` to build, deploy, and execute an application.
+`build_apk.sh` requires the installation of the [Android NDK][] and [Android SDK][].
+On Windows the script requires that you install [Cygwin][], as it
+makes use of Bash and common UNIX utilities.  In addition, `build_apk.sh`
+requires the addition of the [Android SDK][] `sdk/tools`, [Android SDK][]
+`sdk/platform-tools` and [Android NDK][] root directories to the `PATH`
+environment variable.
+
+To build and run an application using `build_apk.sh`:
+
+-   Change into the directory containing the project to build.
+-   Run build\_apk.sh.
+
+For example, the following will build the Testbed application, deploy it to
+the connected device, and start it:
+
+    cd liquidfun/Box2D/Testbed
+    ../AndroidUtil/build_apk.sh
+
+### Code Generation
+
+By default, code is generated for devices that support the `armeabi-v7a` ABI.
+Alternatively, you can generate a fat `.apk` that includes code for all ABIs.
+To do so, override APP\_ABI on ndk-build's command line:
+
+    ndk-build APP_ABI=all
+
+### Running Unit Tests
+
+Developers modifying the LiquidFun library can verify that it is still working
+correctly by executing the provided unit tests.
+
+Use the run\_tests\_android.sh script to execute unit tests:
+
+    ./liquidfun/Box2D/Unittests/run_tests_android.sh
+
+`run_tests_android.sh` uses `build_apk.sh` to build, deploy, and
+execute each unit test on the connected device.
+The "Build and Run from the Command Line" section above describes
+the setup requirements for `build_apk.sh`.
+
+  [Android SDK]: http://developer.android.com/sdk/index.html
+  [Android NDK]: http://developer.android.com/tools/sdk/ndk/index.html
+  [NDK Eclipse plugin]: http://developer.android.com/sdk/index.html
+  [managing avds]: http://developer.android.com/tools/devices/managing-avds.html
+  [Cygwin installation]: http://www.cygwin.com/
+  [ADT]: http://developer.android.com/tools/sdk/eclipse-adt.html
+

+ 92 - 0
engine/source/Box2D/Documentation/Building/BuildingJavaScript.md

@@ -0,0 +1,92 @@
+# Building JavaScript version
+
+### Background
+
+LiquidFun can be translated from C++ into JavaScript by
+[Emscripten](http://github.com/kripken/emscripten/wiki).
+The entire JavaScript translation is in one file: liquidfun.js.
+
+The LiquidFun source includes a pre-made version of liquidfun.js.
+You can reference that liquidfun.js to start writing LiquidFun programs
+in JavaScript right away.
+
+However, if you make changes to the LiquidFun C++ code, or if you need
+to expose more of the LiquidFun API, you will need to remake liquidfun.js
+by following the steps on this page.
+
+### Before Building
+
+We use Emscripten on Linux, but you should be able to use the Emscripten SDK
+on Mac or Windows too, if you prefer. Note that Mac and Windows build
+environments have not been tested.
+
+-   Get Emscripten. See [Installing from Source](http://github.com/kripken/emscripten/wiki/Emscripten-SDK#installing-from-source). 
+    -   You also need [Fastcomp](http://github.com/kripken/emscripten/wiki/LLVM-Backend#getting-fastcomp)
+    -   And [Node.js](http://nodejs.org/download/)
+-   Setup Emscripten.
+    -   As suggested in the Emscripten docs, run "emcc -v"
+    -   Update your ~/.emscripten file. You'll probably want something like this:
+        -   LLVM_ROOT = os.path.expanduser('~/Code/emscripten-fastcomp/build/Release/bin')
+        -   NODE_JS = os.path.expanduser('~/Code/node-v0.10.29-linux-x64/bin/node')
+-   Get the [Closure Compiler](http://developers.google.com/closure/compiler/).
+-   Set environment variables. Depending on your setup, you may want to add
+    some lines like this to your ~/.bashrc file.
+    - export EMSCRIPTEN=~/Code/emscripten
+    - export CLOSURE_JAR=~/Code/closure/compiler.jar
+
+### Building
+
+The following commands run Emscripten to translate C++ to lf_core.js,
+then combine lf_core.js with the bindings in jsBindings into liquidfun.js.
+
+    cd Box2D/lfjs
+    make
+    ./uglify.sh
+
+### Executing the Testbed
+
+For an example program, try openning `Box2D/lfjs/index.html' in your browser.
+This will load a JavaScript version of the LiquidFun Testbed. It uses
+the liquidfun.js file that you built above.
+
+### Debugging
+
+The default output of `make` and `uglify.sh` is whitespace-optimized
+JavaScript that is difficult to debug. To create an un-optimized version
+of the testbed, please follow the steps below.
+
++ In `lfjs/Makefile` change -O2 to -O0, to disable Emscripten optimizations.
++ In `lfjs/index.html` replace `<script src="liquidfun.js"></script>` with
+  a similar line for every .js file in `lfjs/uglify.sh`. It should look
+  something like,
+
+        <script src="lf_core.js"></script>
+        <script src="jsBindings/offsets.js"></script>
+        <script src="jsBindings/Common/b2Math.js"></script>
+        <script src="jsBindings/Collision/b2Collision.js"></script>
+        <script src="jsBindings/Collision/Shapes/b2EdgeShape.js"></script>
+        <script src="jsBindings/Collision/Shapes/b2PolygonShape.js"></script>
+        <script src="jsBindings/Collision/Shapes/b2Shape.js"></script>
+        <script src="jsBindings/Collision/Shapes/b2ChainShape.js"></script>
+        <script src="jsBindings/Collision/Shapes/b2CircleShape.js"></script>
+        <script src="jsBindings/Dynamics/b2Body.js"></script>
+        <script src="jsBindings/Dynamics/b2World.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2WheelJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2WeldJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2GearJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2Joint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2FrictionJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2RevoluteJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2MotorJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2PulleyJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2DistanceJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2PrismaticJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2RopeJoint.js"></script>
+        <script src="jsBindings/Dynamics/Joints/b2MouseJoint.js"></script>
+        <script src="jsBindings/Dynamics/Contacts/b2Contact.js"></script>
+        <script src="jsBindings/Dynamics/b2Fixture.js"></script>
+        <script src="jsBindings/Dynamics/b2WorldCallbacks.js"></script>
+        <script src="jsBindings/Particle/b2ParticleSystem.js"></script>
+        <script src="jsBindings/Particle/b2ParticleGroup.js"></script>
+        <script src="jsBindings/Particle/b2Particle.js"></script>
+

+ 79 - 0
engine/source/Box2D/Documentation/Building/BuildingLinux.md

@@ -0,0 +1,79 @@
+# Building for Linux
+
+### Version Requirements
+
+Following are the minimum required versions for the tools and libraries you
+need for building LiquidFun for Linux:
+
+-   OpenGL: libglapi-mesa 8.0.4 (tested with libglapi-mesa 8.0.4-0ubuntu0)
+-   GLU: libglu1-mesa-dev 8.0.4 (tested with libglu1-mesa-dev 8.0.4.0ubuntu0)
+-   cmake (when building from source): 2.8.12.1
+
+### Before Building
+
+Prior to building, install the following components using the [Linux][]
+distribution's package manager:
+-    [cmake][]. You can also manually install from [cmake.org]
+     (http://cmake.org).
+-    OpenGL (`libglapi-mesa`).
+-    GLU (`libglu1-mesa-dev`).
+
+For example, on Ubuntu:
+
+    sudo apt-get install cmake
+    sudo apt-get install libglapi-mesa
+    sudo apt-get install libglu1-mesa-dev
+
+The sample applications require OpenGL and GLU.
+
+### Building
+
+-   Generate makefiles from the [cmake][] project in `liquidfun/Box2D`.
+-   Execute `make` to build the library and sample applications.
+
+For example:
+
+    cd liquidfun/Box2D
+    cmake -G'Unix Makefiles'
+    make
+
+To perform a debug build:
+
+    cd liquidfun/Box2D
+    cmake -G'Unix Makefiles' -DCMAKE_BUILD_TYPE=Debug
+    make
+
+Build targets can be configured using options exposed in
+`liquidfun/Box2D/CMakeLists.txt` by using cmake's `-D` option.
+Build configuration set using the `-D` option is sticky across subsequent
+builds.
+
+For example, if a build is performed using:
+
+    cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
+    make
+
+to switch to a release build CMAKE_BUILD_TYPE must be explicitly specified:
+
+    cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
+    make
+
+### Executing a Sample
+
+After building the project, you can execute the samples from the command line.
+For example:
+
+    ./liquidfun/Box2D/Testbed/Release/Testbed
+
+### Running Unit Tests
+
+Developers modifying the LiquidFun library can verify that it still working
+correctly by executing the provided unit tests.
+
+Use the run\_tests.sh script to execute unit tests:
+
+    ./liquidfun/Box2D/Unittests/run_tests.sh
+
+  [cmake]: http://www.cmake.org
+  [Linux]: http://en.wikipedia.org/wiki/Linux
+  [Ubuntu]: http://www.ubuntu.com

+ 62 - 0
engine/source/Box2D/Documentation/Building/BuildingOSX.md

@@ -0,0 +1,62 @@
+# Building for OS X
+
+You can use [cmake][] to generate an [Xcode][] project for LiquidFun's
+Testbed and Unittests on [OS X][].
+
+Alternatively, you can download a pre-generated Xcode
+project from the [release page][]. The [Xcode][] project is free of
+host-specific dependencies.
+
+### Version Requirements
+
+These are the minimum required versions for building LiquidFun on OS X:
+
+-   OS X: Mavericks 10.9.1.
+-   Xcode: 5.0.1
+-   Xquartz: 2.7.5 (xorg-server 1.14.4)
+-   cmake (when building from source) 2.8.12.1
+
+### Before Building
+
+-   Install [Xquartz][] to run LiquidFun sample applications.
+    The Testbed uses [freeglut][], which requires [Xquartz][].
+-   Reboot your machine.  Rebooting sets the `DISPLAY` environment variable for
+    [Xquartz][], which enables sample applications to run correctly.
+
+### Creating the Xcode project using [cmake][]
+
+When working directly with the source, you can generate the [Xcode][]
+project using [cmake][].  [cmake][] version 2.8.12.1 or above is required to
+build this project on [OS X][] 10.9 (Mavericks).  For example, the following
+generates the Xcode project in the liquidfun/Box2D directory.
+
+    cd liquidfun/Box2D
+    cmake -G "Xcode"
+
+### Building with [Xcode][]
+
+-   Double-click on `liquidfun/Box2D/Box2D.xcodeproj` to open the project in
+    [Xcode][].
+-   Select "Product-->Build" from the menu.
+
+### Executing a Sample
+
+-   Select a sample `Scheme`, for example "Testbed-->My Mac 64-bit", from the
+    combo box to the right of the "Run" button.
+-   Click the "Run" button.
+
+### Running Unit Tests
+
+Developers modifying the LiquidFun library can verify that it is still working
+correctly by executing the provided unit tests.
+
+Use the run\_tests.sh script to execute unit tests:
+
+    ./liquidfun/Box2D/Unittests/run_tests.sh
+
+  [Xquartz]: http://xquartz.macosforge.org/
+  [cmake]: http://www.cmake.org
+  [Xcode]: http://developer.apple.com/xcode/
+  [OS X]: http://www.apple.com/osx/
+  [freeglut]: http://freeglut.sourceforge.net/
+  [release page]: http://github.com/google/liquidfun/releases

+ 64 - 0
engine/source/Box2D/Documentation/Building/BuildingWindows.md

@@ -0,0 +1,64 @@
+# Building for Windows
+
+You can use [cmake][] to generate a [Visual Studio][] project for
+LiquidFun's Testbed and Unittests on [Windows][].
+
+Alternatively, you can download a pre-generated Visual Studio solution
+from the [release page][]. The Visual Studio solution is free of
+host-specific dependencies.
+
+### Version Requirements
+
+These are the minimum required versions for building LiquidFun for Windows:
+
+-   Windows: 7
+-   Visual Studio: 2010 or 2012
+-   cmake: 2.8.12.1
+
+### Creating the Visual Studio solution using [cmake][]
+
+When working directly with the source, use [cmake][] to generate the
+[Visual Studio][] solution and project files.  For example, the following
+generates the [Visual Studio][] 2012 solution in the `liquidfun/Box2D`
+directory:
+
+    cd liquidfun\Box2D
+    cmake -G "Visual Studio 11"
+
+To generate a [Visual Studio][] 2010 solution, use this commend:
+
+    cd liquidfun\Box2D
+    cmake -G "Visual Studio 10"
+
+Running [cmake][] under [cygwin][] requires empty TMP, TEMP, tmp and temp
+variables.  To generate a [Visual Studio][] solution from a [cygwin][]
+bash shell use:
+
+    $ cd liquidfun/Box2D
+    $ ( unset {temp,tmp,TEMP,TMP} ; cmake -G "Visual Studio 11" )
+
+### Building with [Visual Studio][]
+
+-   Double-click on `liquidfun/Box2D/Box2D.sln` to open the solution.
+-   Select "Build-->Build Solution" from the menu.
+
+### Executing a Sample
+
+-   Right-click on an example project (e.g Testbed) in the Solution Explorer
+    pane, and select "Set as StartUp Project".
+-   Select "Debug-->Start Debugging" from the menu.
+
+### Running Unit Tests
+
+Developers modifying the LiquidFun library can verify that it is still working
+correctly by executing the provided unit tests.
+
+Use the run\_tests.bat batch file to execute unit tests:
+
+    liquidfun\Box2D\Unittests\run_tests.bat
+
+  [cmake]: http://www.cmake.org
+  [Visual Studio]: http://www.visualstudio.com/
+  [Windows]: http://windows.microsoft.com/
+  [cygwin]: http://www.cygwin.com/
+  [release page]: http://github.com/google/liquidfun/releases

+ 32 - 0
engine/source/Box2D/Documentation/Building/BuildingiOS.md

@@ -0,0 +1,32 @@
+# Building for iOS
+
+The LiquidFun source contains [Xcode][] projects to build the Testbed
+application and EyeCandy demo. Unlike the OS X projects, the iOS Xcode
+projects are *not* generated using [cmake][]. They must be maintained
+manually.
+
+### Version Requirements
+
+Following are the minimum tested versions for building the tools and
+libraries you on iOS.
+
+-   OS X: Mavericks 10.9.3.
+-   Xcode: 5.1.1
+
+### Building with [Xcode][]
+
+-   Double-click `liquidfun/Box2D/Testbed/ios/Testbed.xcodeproj` or
+    `liquidfun/Box2D/EyeCandy/ios/EyeCandy.xcodeproj` to open the project
+    in [Xcode][].
+-   Select "Product-->Build" from the menu.
+
+### Executing a Testbed or EyeCandy
+
+-   Select a `Scheme`, for example "Testbed-->iPhone Retina (3.5-inch)",
+	from the combo box to the right of the "Run" button.
+-   Click the "Run" button.
+
+
+  [Xcode]: http://developer.apple.com/xcode/
+  [cmake]: http://www.cmake.org
+  [OS X]: http://www.apple.com/osx/

+ 40 - 0
engine/source/Box2D/Documentation/Building/PortingFromBox2D.md

@@ -0,0 +1,40 @@
+# Porting from Box2D
+
+LiquidFun extends Erin Catto's popular Box2D physics engine. If your project
+already uses Box2D, LiquidFun should be a simple drop-in replacement for you.
+
+### Drop-in LiquidFun Code
+
+To port from Box2D to LiquidFun, simply replace your Box2D directory with
+liquidfun/Box2D/Box2D. Your code should compile and run as it did under Box2D,
+and you will have access to LiquidFun's particle simulation API.
+
+LiquidFun is based off of a specific version of Box2D. If your version of
+Box2D is different from LiquidFun's you may have to adjust your code to
+match API differences.
+
+Please see the [Release Notes][] to find the version of Box2D that LiquidFun
+is based on.
+
+### Specify `particleIterations`
+
+LiquidFun adds a `particleIterations` parameter to b2World::Step. If you don't
+specify `particleIterations`, we calculate a default value based on the
+physical constants in your b2ParticleSystems.
+
+However, the number of `particleIterations` affects performance and stability
+significantly. You should experiment with the number of iterations to find
+a suitable balance for your situation.
+
+### Start using b2ParticleSystem
+
+`b2ParticleSystems` are created with `b2World::CreateParticleSystem`, the
+same way `b2Bodys` are created with `b2World::CreateBody`.
+
+For details, please see [Particle Module][] in the [Programmer's Guide][]
+
+
+  [Release Notes]: ../../ReleaseNotes.html
+  [Particle Module]: ../../Programmers-Guide/html/md__chapter11__particles.html
+  [Programmer's Guide]: ../../Programmers-Guide/html/index.html
+

+ 2357 - 0
engine/source/Box2D/Documentation/Building/doxyfile

@@ -0,0 +1,2357 @@
+# Doxyfile 1.8.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+# 
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+# 
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "LiquidFun Build and Run Instructions"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = "../../../Documentation/Building"
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-
+# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,
+# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# Turkish, Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = NO
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+# 
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+# 
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+# 
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 1
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+# 
+# Note For files without extension you can use no_extension as a placeholder.
+# 
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = NO
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+# 
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = NO
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= NO
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+# 
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+# 
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = NO
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = NO
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT = "Building.md" \
+        "PortingFromBox2D.md" \
+        "BuildingAndroid.md" \
+        "BuildingiOS.md" \
+        "BuildingLinux.md" \
+        "BuildingOSX.md" \
+        "BuildingWindows.md" \
+        "BuildingJavaScript.md"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# 
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+# 
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+# 
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+# 
+# <filter> <input-file>
+# 
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+# 
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = Building.md
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+# 
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+# 
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+# 
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+# 
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = NO
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = NO
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+# 
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = ../footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+# 
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+# 
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+# 
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+# 
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+# 
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+# 
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+# 
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+# 
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+# 
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+# 
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+# 
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+# 
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+# 
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = NO
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = NO
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+# 
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+# 
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# 
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+# 
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES

+ 274 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter01_Introduction.md

@@ -0,0 +1,274 @@
+# Introduction
+
+<img src="liquidfun-logo-square-small.png" alt="LiquidFun logo" style="float:right;"/>
+
+[About](#about)<br/>
+[Prerequisites](#pre)<br/>
+[About this manual](#atm)<br/>
+[Feedback and reporting bugs](#frb)<br/>
+[Core concepts](#cc)<br/>
+[Modules](#mo)<br/>
+[Units](#un)<br/>
+[Factories and definitions](#fd)<br/>
+
+
+<a name="About"></a><br/>
+
+## About
+
+LiquidFun is based on Erin Catto's [Box2D library](http://www.box2d.org), which
+provides 2D, rigid-body simulation in games. LiquidFun extends Box2D to provide
+[particle physics and fluid dynamics](md__chapter11__particles.html).
+
+Programmers can use LiquidFun in their games to make objects move in realistic
+ways and make the game world more interactive. From the game engine's point of
+view, a physics engine is just a system for procedural animation.
+
+LiquidFun is written in portable C++. Most of the types defined in the engine
+begin with the b2 prefix. Hopefully this is sufficient to avoid name clashing
+with your game engine.
+
+<a name="pre"></a><br/>
+## Prerequisites
+
+In this manual I'll assume you are familiar with basic physics concepts, such
+as mass, force, torque, and impulses. If not, please first consult Google
+search and Wikipedia.
+
+LiquidFun is based on the Box2D library, which was created as part of a
+physics tutorial at the Game Developer Conference. You can get these tutorials
+from the download section of Box2D.org.
+
+Since LiquidFun is written in C++, you are expected to be experienced in C++
+programming. LiquidFun should not be your first C++ programming project! You
+should be comfortable with compiling, linking, and debugging.
+
+	Caution
+	
+	LiquidFun should not be your first C++ project. Please learn C++
+programming, compiling, linking, and debugging before working with LiquidFun.
+There are many resources for this on the net.
+
+<a name="atm"></a><br/>
+
+## About this manual
+
+This manual covers the majority of the LiquidFun API. However, not every
+aspect is covered. You are encouraged to look at the testbed included with
+LiquidFun to learn more. Also, the LiquidFun code base has comments formatted
+for Doxygen, so it is easy to create a hyper-linked API document.
+
+This manual is only updated with new releases. The version in source control
+is likely to be out of date.
+
+<a name="frb"></a><br/>
+## Feedback and Reporting Bugs
+
+If you have a question or feedback about LiquidFun, please leave a comment in
+the forum. This is also a great place for community discussion.
+
+LiquidFun issues are tracked using a Google code project. This is a great way
+to track issues and ensures that your issue will not be lost in the depths of
+the forums.
+
+Please file bugs and feature requests here:
+[http://github.com/google/liquidfun/issues](http://github.com/google/liquidfun/issues)
+
+ You can help to ensure your issue gets fixed if you provide sufficient
+detail. A testbed example that reproduces the problem is ideal. You can read
+about the testbed later in this document.
+
+<a name="cc"></a><br/>
+## Core Concepts
+
+LiquidFun works with several fundamental concepts and objects. We briefly
+define these objects here and more details are given later in this
+document.<br/>
+<br/>
+### shape
+A shape is 2D geometrical object, such as a circle or polygon.<br/>
+
+### rigid body
+A chunk of matter that is so strong that the distance between any two bits of
+matter on the chunk is constant. They are hard like a diamond. In the
+following discussion we use body interchangeably with rigid body.<br/>
+
+### fixture
+A fixture binds a shape to a body and adds material properties such as
+density, friction, and restitution. A fixture puts a shape into the collision
+system (broad-phase) so that it can collide with other shapes.<br/>
+
+### constraint
+A constraint is a physical connection that removes degrees of freedom from
+bodies. A 2D body has 3 degrees of freedom (two translation coordinates and
+one rotation coordinate). If we take a body and pin it to the wall (like a
+pendulum) we have constrained the body to the wall. At this point the body can
+only rotate about the pin, so the constraint has removed 2 degrees of
+freedom.<br/>
+
+### contact constraint
+A special constraint designed to prevent penetration of rigid bodies and to
+simulate friction and restitution. You do not create contact constraints; they
+are created automatically by LiquidFun.<br/>
+
+### joint
+This is a constraint used to hold two or more bodies together. LiquidFun
+supports several joint types: revolute, prismatic, distance, and more. Some
+joints may have limits and motors.<br/>
+
+### joint limit
+A joint limit restricts the range of motion of a joint. For example, the human
+elbow only allows a certain range of angles.<br/>
+
+### joint motor
+A joint motor drives the motion of the connected bodies according to the
+joint's degrees of freedom. For example, you can use a motor to drive the
+rotation of an elbow.<br/>
+
+### world
+
+A physics world is a collection of bodies, fixtures, and constraints that
+interact together. LiquidFun supports the creation of multiple worlds, but
+this is usually not necessary or desirable.<br/>
+
+### solver
+The physics world has a solver that is used to advance time and to resolve
+contact and joint constraints. The LiquidFun solver is a high performance
+iterative solver that operates in order N time, where N is the number of
+constraints.<br/>
+
+### continuous collision
+The solver advances bodies in time using discrete time steps. Without
+intervention this can lead to tunneling.<br/>
+<br/>
+
+<img align="center" src="image_0.png" alt="Tunneling" height="293"
+width="275"><br/>
+
+LiquidFun contains specialized algorithms to deal with tunneling. First, the
+collision algorithms can interpolate the motion of two bodies to find the
+first time of impact (TOI). Second, there is a sub-stepping solver that moves
+bodies to their first time of impact and then resolves the collision.
+
+<a name="mo"></a><br/>
+## Modules
+
+LiquidFun is composed of three modules: Common, Collision, and Dynamics. The
+Common module has code for allocation, math, and settings. The Collision
+module defines shapes, a broad-phase, and collision functions/queries. Finally
+the Dynamics module provides the simulation world, bodies, fixtures, and
+joints.<br/>
+<br/>
+
+<img align="center" src="image_1.png" alt="Modules" height="229" width="217">
+<a name="un"></a><br/>
+## Units
+
+LiquidFun works with floating point numbers and tolerances have to be used to
+make LiquidFun perform well. These tolerances have been tuned to work well
+with meters-kilogram-second (MKS) units. In particular, LiquidFun has been
+tuned to work well with moving shapes between 0.1 and 10 meters. So this means
+objects between soup cans and buses in size should work well. Static shapes
+may be up to 50 meters long without trouble.
+
+Being a 2D physics engine, it is tempting to use pixels as your units.
+Unfortunately this will lead to a poor simulation and possibly weird behavior.
+An object of length 200 pixels would be seen by LiquidFun as the size of a 45
+story building.
+
+	Caution
+	
+	LiquidFun is tuned for MKS units. Keep the size of moving objects
+roughly between 0.1 and 10 meters. You'll need to use some scaling system when
+you render your environment and actors. The LiquidFun testbed does this by
+using an OpenGL viewport transform. DO NOT USE PIXELS.
+
+
+
+It is best to think of LiquidFun bodies as moving billboards upon which you
+attach your artwork. The billboard may move in a unit system of meters, but
+you can convert that to pixel coordinates with a simple scaling factor. You
+can then use those pixel coordinates to place your sprites, etc. You can also
+account for flipped coordinate axes.
+
+LiquidFun uses radians for angles. The body rotation is stored in radians and
+may grow unbounded. Consider normalizing the angle of your bodies if the
+magnitude of the angle becomes too large (use b2Body::SetAngle).
+
+	Caution
+	
+	LiquidFun uses radians, not degrees.
+
+<a name="fd"></a><br/>
+## Factories and Definitions
+
+Fast memory management plays a central role in the design of the LiquidFun
+API. So when you create a b2Body or a b2Joint, you need to call the factory
+functions on b2World. You should never try to allocate these types in another
+manner.
+
+There are creation functions:
+
+&nbsp;&nbsp;&nbsp;`b2Body* b2World::CreateBody(const b2BodyDef* def)`<br/>
+&nbsp;&nbsp;&nbsp;`b2Joint* b2World::CreateJoint(const b2JointDef* def)`<br/>
+&nbsp;&nbsp;&nbsp;`And there are corresponding destruction functions:`<br/>
+&nbsp;&nbsp;&nbsp;`void b2World::DestroyBody(b2Body* body)`<br/>
+&nbsp;&nbsp;&nbsp;`void b2World::DestroyJoint(b2Joint* joint)`<br/>
+
+When you create a body or joint, you need to provide a definition. These
+definitions contain all the information needed to build the body or joint. By
+using this approach we can prevent construction errors, keep the number of
+function parameters small, provide sensible defaults, and reduce the number of
+accessors.
+
+Since fixtures (shapes) must be parented to a body, they are created and
+destroyed using a factory method on b2Body:
+
+&nbsp;&nbsp;&nbsp;`b2Fixture* b2Body::CreateFixture(const b2FixtureDef*
+def)`<br/>
+&nbsp;&nbsp;&nbsp;`void b2Body::DestroyFixture(b2Fixture* fixture)`<br/>
+
+There is also shortcut to create a fixture directly from the shape and density.
+
+&nbsp;&nbsp;&nbsp;`b2Fixture* b2Body::CreateFixture(const b2Shape* shape,
+float32 density)`<br/>
+
+Factories do not retain references to the definitions. So you can create
+definitions on the stack and keep them in temporary resources.
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*
+
+
+[ ][Chapter02]
+[ ][Chapter03]
+[ ][Chapter04]
+[ ][Chapter05]
+[ ][Chapter06]
+[ ][Chapter07]
+[ ][Chapter08]
+[ ][Chapter09]
+[ ][Chapter10]
+[ ][Chapter11]
+[ ][Chapter12]
+[ ][Chapter13]
+[ ][Chapter14]
+[ ][Chapter15]
+
+  [Chapter02]: md__chapter02__hello__box2_d.html
+  [Chapter03]: md__chapter03__common.html
+  [Chapter04]: md__chapter04__collision__module.html
+  [Chapter05]: md__chapter05__dynamics__module.html
+  [Chapter06]: md__chapter06__bodies.html
+  [Chapter07]: md__chapter07__fixtures.html
+  [Chapter08]: md__chapter08__joints.html
+  [Chapter09]: md__chapter09__contacts.html
+  [Chapter10]: md__chapter10__world.html
+  [Chapter11]: md__chapter11__particles.html
+  [Chapter12]: md__chapter12__loose__ends.html
+  [Chapter13]: md__chapter13__debug__drawing.html
+  [Chapter14]: md__chapter14__limitations.html
+  [Chapter15]: md__chapter15__references.html
+

+ 290 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter02_Hello_Box2D.md

@@ -0,0 +1,290 @@
+# Hello LiquidFun
+
+[About](#about)<br/>
+[Creating a world](#cr)<br/>
+[Creating a ground box](#cgb)<br/>
+[Creating a dynamic body](#cdb)<br/>
+[Simulating the World (of LiquidFun)](#stw)<br>
+[Cleanup](#cl)<br>
+[The testbed](#tb)<br>
+<br/>
+
+<a name="about">
+## About
+In the distribution of LiquidFun is a Hello World project. The program creates
+a large ground box and a small dynamic box. This code does not contain any
+graphics. All you will see is text output in the console of the box's position
+over time.
+
+This is a good example of how to get up and running with LiquidFun.
+
+<a name="cr"></a><br/>
+
+## Creating a World
+
+Every LiquidFun program begins with the creation of a b2World object. b2World
+is the physics hub that manages memory, objects, and simulation. You can
+allocate the physics world on the stack, heap, or data section.
+
+It is easy to create a LiquidFun world. First, we define the gravity vector.
+
+b2Vec2 gravity(0.0f, -10.0f);
+
+Now we create the world object. Note that we are creating the world on the
+stack, so the world must remain in scope.
+
+b2World world(gravity);
+
+So now we have our physics world, let's start adding some stuff to it.
+
+<a name="cgb"></a><br/>
+## Creating a Ground Box
+
+Bodies are built using the following steps:
+
+1. Define a body with position, damping, etc.
+
+2. Use the world object to create the body.
+
+3. Define fixtures with a shape, friction, density, etc.
+
+4. Create fixtures on the body.
+
+For step 1 we create the ground body. For this we need a body definition. With
+the body definition we specify the initial position of the ground body.
+
+&nbsp;&nbsp;&nbsp;`b2BodyDef groundBodyDef;`<br/>
+&nbsp;&nbsp;&nbsp;`groundBodyDef.position.Set(0.0f, -10.0f);`<br/>
+
+For step 2 the body definition is passed to the world object to create the
+ground body. The world object does not keep a reference to the body
+definition. Bodies are static by default. Static bodies don't collide with
+other static bodies and are immovable.
+
+&nbsp;&nbsp;&nbsp;`b2Body* groundBody = world.CreateBody(&groundBodyDef);`<br/>
+
+For step 3 we create a ground polygon. We use the SetAsBox shortcut to form
+the ground polygon into a box shape, with the box centered on the origin of
+the parent body.
+
+&nbsp;&nbsp;&nbsp;`b2PolygonShape groundBox;`<br/>
+&nbsp;&nbsp;&nbsp;`groundBox.SetAsBox(50.0f, 10.0f);`<br/>
+
+The SetAsBox function takes the **half**-**width** and **half**-**height**
+(extents). So in this case the ground box is 100 units wide (x-axis) and 20
+units tall (y-axis). LiquidFun is tuned for meters, kilograms, and seconds. So
+you can consider the extents to be in meters. LiquidFun generally works best
+when objects are the size of typical real world objects. For example, a barrel
+is about 1 meter tall. Due to the limitations of floating point arithmetic,
+using LiquidFun to model the movement of glaciers or dust particles is not a
+good idea.
+
+We finish the ground body in step 4 by creating the shape fixture. For this
+step we have a shortcut. We do not have a need to alter the default fixture
+material properties, so we can pass the shape directly to the body without
+creating a fixture definition. Later we will see how to use a fixture
+definition for customized material properties. The second parameter is the
+shape density in kilograms per meter squared. A static body has zero mass by
+definition, so the density is not used in this case.
+
+&nbsp;&nbsp;&nbsp;`groundBody->CreateFixture(&groundBox, 0.0f);`
+
+LiquidFun does not keep a reference to the shape. It clones the data into a
+new b2Shape object.
+
+Note that every fixture must have a parent body, even fixtures that are
+static. However, you can attach all static fixtures to a single static body.
+
+When you attach a shape to a body using a fixture, the shape’s coordinates
+become local to the body. So when the body moves, so does the shape. A
+fixture’s world transform is inherited from the parent body. A fixture does
+not have a transform independent of the body. So we don’t move a shape
+around on the body. Moving or modifying a shape that is on a body is not
+supported. The reason is simple: a body with morphing shapes is not a rigid
+body, but LiquidFun is a rigid body engine. Many of the assumptions made in
+LiquidFun are based on the rigid body model. If this is violated many things
+will break
+
+<a name="cdb"></a><br/>
+## Creating a Dynamic Body
+
+So now we have a ground body. We can use the same technique to create a
+dynamic body. The main difference, besides dimensions, is that we must
+establish the dynamic body's mass properties.
+
+First we create the body using CreateBody. By default bodies are static, so we
+should set the b2BodyType at construction time to make the body dynamic.
+
+&nbsp;&nbsp;&nbsp;`b2BodyDef bodyDef;`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.type = b2_dynamicBody;`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.position.Set(0.0f, 4.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Body* body = world.CreateBody(&bodyDef);`<br/>
+
+    Caution
+
+    You must set the body type to b2_dynamicBody if you want the body to move in response to forces.
+
+
+
+Next we create and attach a polygon shape using a fixture definition. First we
+create a box shape:
+
+&nbsp;&nbsp;&nbsp;`b2PolygonShape dynamicBox;`<br/>
+&nbsp;&nbsp;&nbsp;`dynamicBox.SetAsBox(1.0f, 1.0f);`<br/>
+
+Next we create a fixture definition using the box. Notice that we set density
+to 1. The default density is zero. Also, the friction on the shape is set to
+0.3.
+
+&nbsp;&nbsp;&nbsp;`b2FixtureDef fixtureDef;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.shape = &dynamicBox;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.density = 1.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.friction = 0.3f;`<br/>
+
+
+    Caution
+
+    A dynamic body should have at least one fixture with a non-zero density.  Otherwise you will get strange behavior.
+
+Using the fixture definition we can now create the fixture. This automatically
+updates the mass of the body. You can add as many fixtures as you like to a
+body. Each one contributes to the total mass.
+
+&nbsp;&nbsp;&nbsp;`body->CreateFixture(&fixtureDef);`<br/>
+
+That's it for initialization. We are now ready to begin simulating.
+
+<a name="stw"></a><br/>
+## Simulating the World (of LiquidFun)
+
+So we have initialized the ground box and a dynamic box. Now we are ready to
+set Newton loose to do his thing. We just have a couple more issues to
+consider.
+
+LiquidFun uses a computational algorithm called an integrator. Integrators
+simulate the physics equations at discrete points of time. This goes along
+with the traditional game loop where we essentially have a flip book of
+movement on the screen. So we need to pick a time step for LiquidFun.
+Generally physics engines for games like a time step at least as fast as 60Hz
+or 1/60 seconds. You can get away with larger time steps, but you will have to
+be more careful about setting up the definitions for your world. We also don't
+like the time step to change much. A variable time step produces variable
+results, which makes it difficult to debug. So don't tie the time step to your
+frame rate (unless you really, really have to). Without further ado, here is
+the time step.
+
+&nbsp;&nbsp;&nbsp;`float32 timeStep = 1.0f / 60.0f;`<br/>
+
+In addition to the integrator, LiquidFun also uses a larger bit of code called
+a constraint solver. The constraint solver solves all the constraints in the
+simulation, one at a time. A single constraint can be solved perfectly.
+However, when we solve one constraint, we slightly disrupt other constraints.
+To get a good solution, we need to iterate over all constraints a number of
+times.
+
+There are two phases in the constraint solver: a velocity phase and a position
+phase. In the velocity phase the solver computes the impulses necessary for
+the bodies to move correctly. In the position phase the solver adjusts the
+positions of the bodies to reduce overlap and joint detachment. Each phase has
+its own iteration count. In addition, the position phase may exit iterations
+early if the errors are small.
+
+The suggested iteration count for LiquidFun is 8 for velocity and 3 for
+position. You can tune this number to your liking, just keep in mind that this
+has a trade-off between performance and accuracy. Using fewer iterations
+increases performance but accuracy suffers. Likewise, using more iterations
+decreases performance but improves the quality of your simulation. For this
+simple example, we don't need much iteration. Here are our chosen iteration
+counts.
+
+&nbsp;&nbsp;&nbsp;`int32 velocityIterations = 6;`<br/>
+&nbsp;&nbsp;&nbsp;`int32 positionIterations = 2;`<br/>
+
+Note that the time step and the iteration count are completely unrelated. An
+iteration is not a sub-step. One solver iteration is a single pass over all
+the constraints within a time step. You can have multiple passes over the
+constraints within a single time step.
+
+We are now ready to begin the simulation loop. In your game the simulation
+loop can be merged with your game loop. In each pass through your game loop
+you call b2World::Step. Just one call is usually enough, depending on your
+frame rate and your physics time step.
+
+The Hello World program was designed to be simple, so it has no graphical
+output. The code prints out the position and rotation of the dynamic body.
+Here is the simulation loop that simulates 60 time steps for a total of 1
+second of simulated time.
+
+&nbsp;&nbsp;&nbsp;`for (int32 i = 0; i < 60; ++i)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`    world.Step(timeStep,
+velocityIterations, positionIterations);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;` b2Vec2 position =
+body->GetPosition();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`    float32 angle =
+body->GetAngle();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`printf("%4.2f %4.2f %4.2f\n", position.x,
+position.y, angle);`<br/>
+&nbsp;&nbsp;&nbsp;`}`
+
+The output shows the box falling and landing on the ground box. Your output
+should look like this:
+
+0.00 4.00 0.00
+
+0.00 3.99 0.00
+
+0.00 3.98 0.00
+
+...
+
+0.00 1.25 0.00
+
+0.00 1.13 0.00
+
+0.00 1.01 0.00
+
+<a name="cl"></a><br/>
+## Cleanup
+
+When a world leaves scope or is deleted by calling delete on a pointer, all
+the memory reserved for bodies, fixtures, and joints is freed. This is done to
+improve performance and make your life easier. However, you will need to
+nullify any body, fixture, or joint pointers you have because they will become
+invalid.
+
+<a name="tb"></a><br/>
+## The Testbed
+
+Once you have conquered the HelloWorld example, you should start looking at
+LiquidFun's testbed. The testbed is a unit-testing framework and demo
+environment. Here are some of the features:
+
+* Camera with pan and zoom.
+
+* Mouse picking of shapes attached to dynamic bodies.
+
+* Extensible set of tests.
+
+* GUI for selecting tests, parameter tuning, and debug drawing options.
+
+* Pause and single step simulation.
+
+* Text rendering
+
+<img align="center" src="image_2.gif" alt="Modules" height="300"
+width="336"><br/>
+
+The testbed has many examples of LiquidFun usage in the test cases and the
+framework itself. I encourage you to explore and tinker with the testbed as
+you learn LiquidFun.
+
+Note: the testbed is written using freeglut and GLUI. The testbed is not part
+of the LiquidFun library. The LiquidFun library is agnostic about rendering.
+As shown by the HelloWorld example, you don't need a renderer to use LiquidFun.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 93 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter03_Common.md

@@ -0,0 +1,93 @@
+# Common
+[About](#about)<br/>
+[Settings](#settings)<br/>
+[Memory Management](#mm)<br/>
+[Math](#math)
+
+<a name="about">
+## About
+
+The Common module contains settings, memory management, and vector math.
+
+<a name="settings">
+## Settings
+
+The header b2Settings.h contains:
+
+* Types such as int32 and float32
+
+* Constants
+
+* Allocation wrappers
+
+* The version number
+
+### Types
+
+LiquidFun defines various types such as float32, int8, etc. to make it easy to
+determine the size of structures.
+
+### Constants
+
+LiquidFun defines several constants. These are all documented in b2Settings.h.
+Normally you do not need to adjust these constants.
+
+LiquidFun uses floating point math for collision and simulation. Due to
+round-off error some numerical tolerances are defined. Some tolerances are
+absolute and some are relative.  Absolute tolerances use MKS units.
+
+### Allocation wrappers
+
+The settings file defines b2Alloc and b2Free for large allocations. You may
+forward these calls to your own memory management system.
+
+### Version
+
+The b2Version structure holds the current version so you can query this at
+run-time.
+
+<a name="mm">
+## Memory Management
+
+A large number of the decisions about the design of LiquidFun were based on
+the need for quick and efficient use of memory. In this section I will discuss
+how and why LiquidFun allocates memory.
+
+LiquidFun tends to allocate a large number of small objects (around 50-300
+bytes). Using the system heap through malloc or new for small objects is
+inefficient and can cause fragmentation. Many of these small objects may have
+a short life span, such as contacts, but can persist for several time steps.
+So we need an allocator that can efficiently provide heap memory for these
+objects.
+
+LiquidFun's solution is to use a small object allocator (SOA) called
+b2BlockAllocator. The SOA keeps a number of growable pools of varying sizes.
+When a request is made for memory, the SOA returns a block of memory that best
+fits the requested size. When a block is freed, it is returned to the pool.
+Both of these operations are fast and cause little heap traffic.
+
+Since LiquidFun uses a SOA, you should never new or malloc a body, fixture, or
+joint. However, you do have to allocate a b2World on your own. The b2World
+class provides factories for you to create bodies, fixtures, and joints. This
+allows LiquidFun to use the SOA and hide the gory details from you. Never,
+call delete or free on a body, fixture, or joint.
+
+While executing a time step, LiquidFun needs some temporary workspace memory.
+For this, it uses a stack allocator called b2StackAllocator to avoid per-step
+heap allocations. You don't need to interact with the stack allocator, but
+it's good to know it's there.
+
+<a name="math">
+## Math
+
+LiquidFun includes a simple small vector and matrix module. This has been
+designed to suit the internal needs of LiquidFun and the API. All the members
+are exposed, so you may use them freely in your application.
+
+The math library is kept simple to make LiquidFun easy to port and maintain.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 438 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter04_Collision_Module.md

@@ -0,0 +1,438 @@
+# Collision Module
+[About](#about)<br/>
+[Shapes](#shapes)<br/>
+[Unary Geometric Queries](#un)<br/>
+[Binary Functions](#bf)<br/>
+[Dynamic Tree](#dt)<br/>
+[Broad-Phase](#bp)<br/>
+
+<a name="about">
+## About
+
+The Collision module contains shapes and functions that operate on them. The
+module also contains a dynamic tree and broad-phase to acceleration collision
+processing of large systems.
+
+The collision module is designed to be usable outside of the dynamic system.
+For example, you can use the dynamic tree for other aspects of your game
+besides physics.
+
+However, the main purpose of LiquidFun is to provide a rigid body physics
+engine, so the using the collision module by itself may feel limited for some
+applications. Likewise, I will not make a strong effort to document it or
+polish the APIs.
+
+<a name="shapes">
+## Shapes
+
+Shapes describe collision geometry and may be used independently of physics
+simulation. At a minimum, you should understand how to create shapes that can
+be later attached to rigid bodies.
+
+LiquidFun shapes implement the b2Shape base class. The base class defines
+functions to:
+
+* Test a point for overlap with the shape.
+
+* Perform a ray cast against the shape.
+
+* Compute the shape's AABB.
+
+* Compute the mass properties of the shape.
+
+In addition, each shape has a type member and a radius. The radius even
+applies to polygons, as discussed below.
+
+Keep in mind that a shape does not know about bodies and stand apart from the
+dynamics system. Shapes are stored in a compact form that is optimized for
+size and performance. As such, shapes are not easily moved around. You have to
+manually set the shape vertex positions to move a shape. However, when a shape
+is attached to a body using a fixture, the shapes move rigidly with the host
+body. In summary:
+
+* When a shape is **not** attached to a body, you can view it’s vertices as
+being expressed in world-space.
+
+* When a shape is attached to a body, you can view it’s vertices as being
+expressed in local coordinates.
+
+### Circle Shapes
+
+Circle shapes have a position and radius.  Circles are solid. You cannot make
+a hollow circle using the circle shape.
+
+&nbsp;&nbsp;&nbsp;`b2CircleShape circle;`<br/>
+&nbsp;&nbsp;&nbsp;`circle.m_p.Set(2.0f, 3.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`circle.m_radius = 0.5f;`<br/>
+
+### Polygon Shapes
+
+Polygon shapes are solid convex polygons. A polygon is convex when all line
+segments connecting two points in the interior do not cross any edge of the
+polygon. Polygons are solid and never hollow. A polygon must have 3 or more
+vertices.
+
+<img align="center" src="image_3.gif" alt="Polygon shapes" height="125"
+width="223"><br/>
+
+
+Polygon vertices are stored with a counter clockwise winding (CCW). We must be
+careful because the notion of CCW is with respect to a right-handed coordinate
+system with the z-axis pointing out of the plane. This might turn out to be
+clockwise on your screen, depending on your coordinate system conventions.
+
+<img align="center" src="image_4.png" alt="Polygon vertices" height="176"
+width="347"><br/>
+
+The polygon members are public, but you should use initialization functions to
+create a polygon. The initialization functions create normal vectors and
+perform validation.
+
+You can create a polygon shape by passing in a vertex array. The maximal size
+of the array is controlled by b2_maxPolygonVertices which has a default value
+of 8. This is sufficient to describe most convex polygons.
+
+The b2PolygonShape::Set function automatically computes the convex hull and
+establishes the proper winding order. This function is fast when the number of
+vertices is low. If you increase b2_maxPolygonVertices, then the convex hull
+computation might become slow. Also note that the convex hull function may
+eliminate and/or re-order the points you provide.
+
+&nbsp;&nbsp;&nbsp;`// This defines a triangle in CCW order.`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 vertices[3];`<br/>
+&nbsp;&nbsp;&nbsp;`vertices[0].Set(0.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`vertices[1].Set(1.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`vertices[2].Set(0.0f, 1.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`int32 count = 3;`<br/>
+&nbsp;&nbsp;&nbsp;`b2PolygonShape polygon;`<br/>
+&nbsp;&nbsp;&nbsp;`polygon.Set(vertices, count);`<br/>
+
+The polygon shape has some convenience functions to create boxes.
+
+&nbsp;&nbsp;&nbsp;`void SetAsBox(float32 hx, float32 hy);`<br/>
+&nbsp;&nbsp;&nbsp;`void SetAsBox(float32 hx, float32 hy, const b2Vec2& center,
+float32 angle);`<br/>
+
+Polygons inherit a radius from b2Shape. The radius creates a skin around the
+polygon. The skin is used in stacking scenarios to keep polygons slightly
+separated. This allows continuous collision to work against the core polygon.
+
+<img align="center" src="image_5.png" alt="Polygon skin" height="270"
+width="300"><br/>
+The polygon skin helps prevent tunneling by keeping the polygons separated.
+This results in small gaps between the shapes. Your visual representation can
+be larger than the polygon to hide any gaps.
+
+<img align="center" src="image_6.png" alt="Polygons collide" height="109"
+width="322"><br/>
+
+### Edge Shapes
+
+Edge shapes are line segments. These are provided to assist in making a
+free-form static environment for your game. A major limitation of edge shapes
+is that they can collide with circles and polygons but not with themselves.
+The collision algorithms used by LiquidFun require that at least one of two
+colliding shapes have volume. Edge shapes have no volume, so edge-edge
+collision is not possible.
+
+&nbsp;&nbsp;&nbsp;`// This an edge shape.`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 v1(0.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 v2(1.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2EdgeShape edge;`<br/>
+&nbsp;&nbsp;&nbsp;`edge.Set(v1, v2);`<br/>
+
+In many cases a game environment is constructed by connecting several edge
+shapes end-to-end. This can give rise to an unexpected artifact when a polygon
+slides along the chain of edges. In the figure below we see a box colliding
+with an internal vertex. These *ghost* collisions are caused when the polygon
+collides with an internal vertex generating an internal collision normal.
+
+<img align="center" src="image_7.png" alt="Ghost collision" height="154"
+width="315"><br/>
+If edge1 did not exist this collision would seem fine. With edge1 present, the
+internal collision seems like a bug. But normally when LiquidFun collides two
+shapes, it views them in isolation.
+
+Fortunately, the edge shape provides a mechanism for eliminating ghost
+collisions by storing the adjacent *ghost *vertices. LiquidFun uses these
+ghost vertices to prevent internal collisions.
+
+<img align="center" src="image_8.png" alt="Ghost vertices" height="153"
+width="332"><br/>
+&nbsp;&nbsp;&nbsp;`// This is an edge shape with ghost vertices.`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 v0(1.7f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 v1(1.0f, 0.25f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 v2(0.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 v3(-1.7f, 0.4f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2EdgeShape edge;`<br/>
+&nbsp;&nbsp;&nbsp;`edge.Set(v1, v2);`<br/>
+&nbsp;&nbsp;&nbsp;`edge.m_hasVertex0 = true;`<br/>
+&nbsp;&nbsp;&nbsp;`edge.m_hasVertex3 = true;`<br/>
+&nbsp;&nbsp;&nbsp;`edge.m_vertex0 = v0;`<br/>
+&nbsp;&nbsp;&nbsp;`edge.m_vertex3 = v3;`<br/>
+
+In general stitching edges together this way is a bit wasteful and tedious.
+This brings us to chain shapes.
+
+### Chain Shapes
+
+The chain shape provides an efficient way to connect many edges together to
+construct your static game worlds. Chain shapes automatically eliminate ghost
+collisions and provide two-sided collision.
+
+<img align="center" src="image_9.png" alt="Chain shape" height="165"
+width="305"><br/>
+&nbsp;&nbsp;&nbsp;`// This a chain shape with isolated vertices`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 vs[4];`<br/>
+&nbsp;&nbsp;&nbsp;`vs[0].Set(1.7f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`vs[1].Set(1.0f, 0.25f);`<br/>
+&nbsp;&nbsp;&nbsp;`vs[2].Set(0.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`vs[3].Set(-1.7f, 0.4f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2ChainShape chain;`<br/>
+&nbsp;&nbsp;&nbsp;`chain.CreateChain(vs, 4);`<br/>
+
+You may have a scrolling game world and would like to connect several chains
+together. You can connect chains together using ghost vertices, like we did
+with b2EdgeShape.
+
+&nbsp;&nbsp;&nbsp;`// Install ghost vertices`<br/>
+&nbsp;&nbsp;&nbsp;`chain.SetPrevVertex(b2Vec2(3.0f, 1.0f));`<br/>
+&nbsp;&nbsp;&nbsp;`chain.SetNextVertex(b2Vec2(-2.0f, 0.0f));`<br/>
+
+You may also create loops automatically.
+
+&nbsp;&nbsp;&nbsp;`// Create a loop. The first and last vertices are
+connected.`<br/>
+&nbsp;&nbsp;&nbsp;`b2ChainShape chain;`<br/>
+&nbsp;&nbsp;&nbsp;`chain.CreateLoop(vs, 4);`<br/>
+
+Self-intersection of chain shapes is not supported. It might work, it might
+not. The code that prevents ghost collisions assumes there are no
+self-intersections of the chain. Also, very close vertices can cause problems.
+Make sure all your edges are longer than b2_linearSlop (5mm).
+
+<img align="center" src="image_10.png" alt="No self-intersection" height="178"
+width="335"><br/>
+Each edge in the chain is treated as a child shape and can be accessed by
+index. When a chain shape is connected to a body, each edge gets its own
+bounding box in the broad-phase collision tree.
+
+&nbsp;&nbsp;&nbsp;`// Visit each child edge.`<br/>
+&nbsp;&nbsp;&nbsp;`for (int32 i = 0; i < chain.GetChildCount(); ++i)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2EdgeShape edge;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`chain.GetChildEdge(&edge, i);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`…`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+<a name="un">
+## Unary Geometric Queries
+
+You can perform a couple of geometric queries on a single shape.
+
+### Shape Point Test
+
+You can test a point for overlap with a shape. You provide a transform for the
+shape and a world point.
+
+&nbsp;&nbsp;&nbsp;`b2Transfrom transform;`<br/>
+&nbsp;&nbsp;&nbsp;`transform.SetIdentity();`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 point(5.0f, 2.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`bool hit = shape->TestPoint(transform, point);`<br/>
+
+Edge and chain shapes always return false, even if the chain is a loop.
+
+### Shape Ray Cast
+
+You can cast a ray at a shape to get the point of first intersection and
+normal vector. No hit will register if the ray starts inside the shape. A
+child index is included for chain shapes because the ray cast will only check
+a single edge at a time.
+
+&nbsp;&nbsp;&nbsp;`b2Transfrom transform;`<br/>
+&nbsp;&nbsp;&nbsp;`transform.SetIdentity();`<br/>
+&nbsp;&nbsp;&nbsp;`b2RayCastInput input;`<br/>
+&nbsp;&nbsp;&nbsp;`input.p1.Set(0.0f, 0.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`input.p2.Set(1.0f, 0.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`input.maxFraction = 1.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`int32 childIndex = 0;`<br/>
+&nbsp;&nbsp;&nbsp;`b2RayCastOutput output;`<br/>
+&nbsp;&nbsp;&nbsp;`bool hit = shape->RayCast(&output, input, transform,
+childIndex);`<br/>
+&nbsp;&nbsp;&nbsp;`if (hit)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 hitPoint = input.p1 +
+output.fraction * (input.p2 – input.p1);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`…`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+<a name="bf">
+## Binary Functions
+
+The Collision module contains bilateral functions that take a pair of shapes
+and compute some results. These include:
+
+* Overlap
+
+* Contact manifolds
+
+* Distance
+
+* Time of impact
+
+### Overlap
+
+You can test two shapes for overlap using this function:
+
+&nbsp;&nbsp;&nbsp;`b2Transform xfA = …, xfB = …;`<br/>
+&nbsp;&nbsp;&nbsp;`bool overlap = b2TestOverlap(shapeA, indexA, shapeB,
+indexB, xfA, xfB);`<br/>
+
+Again you must provide child indices to for the case of chain shapes.
+
+### Contact Manifolds
+
+LiquidFun has functions to compute contact points for overlapping shapes. If
+we consider circle-circle or circle-polygon, we can only get one contact point
+and normal. In the case of polygon-polygon we can get two points. These points
+share the same normal vector so LiquidFun groups them into a manifold
+structure. The contact solver takes advantage of this to improve stacking
+stability.
+
+<img align="center" src="image_11.png" alt="Manifold structure" height="300"
+width="419"><br/>
+Normally you don’t need to compute contact manifolds directly, however you
+will likely use the results produced in the simulation.
+
+The b2Manifold structure holds a normal vector and up to two contact points.
+The normal and points are held in local coordinates. As a convenience for the
+contact solver, each point stores the normal and tangential (friction)
+impulses.
+
+The data stored in b2Manifold is optimized for internal use. If you need this
+data, it is usually best to use the b2WorldManifold structure to generate the
+world coordinates of the contact normal and points. You need to provide a
+b2Manifold and the shape transforms and radii.
+
+&nbsp;&nbsp;&nbsp;`b2WorldManifold worldManifold;`<br/>
+&nbsp;&nbsp;&nbsp;`worldManifold.Initialize(&manifold, transformA,
+shapeA.m_radius, transformB, shapeB.m_radius);`<br/>
+&nbsp;&nbsp;&nbsp;`for (int32 i = 0; i < manifold.pointCount; ++i)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 point =
+worldManifold.points[i];`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`…`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+Notice that the world manifold uses the point count from the original manifold.
+
+During simulation shapes may move and the manifolds may change. Points may be
+added or removed. You can detect this using b2GetPointStates.
+
+&nbsp;&nbsp;&nbsp;`b2PointState state1[2], state2[2];`<br/>
+&nbsp;&nbsp;&nbsp;`b2GetPointStates(state1, state2, &manifold1,
+&manifold2);`<br/>
+&nbsp;&nbsp;&nbsp;`if (state1[0] == b2_removeState)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`// process event`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+### Distance
+
+The b2Distance function can be used to compute the distance between two
+shapes.  The distance function needs both shapes to be converted into a
+b2DistanceProxy. There is also some caching used to warm start the distance
+function for repeated calls. You can see the details in b2Distance.h.
+
+<img align="center" src="image_12.png" alt="Distance" height="134"
+width="271"><br/>
+### Time of Impact
+
+If two shapes are moving fast, they may *tunnel* through each other in a
+single time step.
+
+<img align="center" src="image_13.png" alt="Time-of-impact tunneling"
+height="133" width="234"><br/>
+The b2TimeOfImpact function is used to determine the time when two moving
+shapes collide. This is called the *time of impact *(TOI). The main purpose of
+b2TimeOfImpact is for tunnel prevention. In particular, it is designed to
+prevent moving objects from tunneling outside of static level geometry.
+
+This function accounts for rotation and translation of both shapes, however if
+the rotations are large enough, then the function may miss a collision.
+However the function will still report a non-overlapped time and will capture
+all translational collisions.
+
+The time of impact function identities an initial separating axis and ensures
+the shapes do not cross on that axis. This might miss collisions that are
+clear at the final positions. While this approach may miss some collisions, it
+is very fast and adequate for tunnel prevention.
+
+<img align="center" src="image_14.png" alt="Captured collision" height="169"
+width="297"><br/>
+<img align="center" src="image_15.png" alt="Missed collision" height="172"
+width="297"><br/>
+It is difficult to put a restriction on the rotation magnitude. There may be
+cases where collisions are missed for small rotations. Normally, these missed
+rotational collisions should not harm game play. They tend to be glancing
+collisions.
+
+The function requires two shapes (converted to b2DistanceProxy) and two
+b2Sweep structures. The sweep structure defines the initial and final
+transforms of the shapes.
+
+You can use fixed rotations to perform a *shape cast*. In this case, the time
+of impact function will not miss any collisions.
+
+<a name="dt">
+## Dynamic Tree
+
+The b2DynamicTree class is used by LiquidFun to organize large numbers of
+shapes efficiently. The class does not know about shapes. Instead it operates
+on axis-aligned bounding boxes (AABBs) with user data pointers.
+
+The dynamic tree is a hierarchical AABB tree. Each internal node in the tree
+has two children. A leaf node is a single user AABB. The tree uses rotations
+to keep the tree balanced, even in the case of degenerate input.
+
+The tree structure allows for efficient ray casts and region queries. For
+example, you may have hundreds of shapes in your scene. You could perform a
+ray cast against the scene in a brute force manner by ray casting each shape.
+This would be inefficient because it does not take advantage of shapes being
+spread out. Instead, you can maintain a dynamic tree and perform ray casts
+against the tree. This traverses the ray through the tree skipping large
+numbers of shapes.
+
+A region query uses the tree to find all leaf AABBs that overlap a query AABB.
+This is faster than a brute force approach because many shapes can be skipped.
+
+<img align="center" src="image_16.png" alt="Ray cast" height="249"
+width="248"><br/>
+<img align="center" src="image_17.png" alt="Region query" height="210"
+width="231"><br/>
+Normally you will not use the dynamic tree directly. Rather you will go
+through the b2World class for ray casts and region queries. If you plan to
+instantiate your own dynamic tree, you can learn how to use it by looking at
+how LiquidFun uses it.
+
+<a name="bp">
+## Broad-phase
+
+Collision processing in a physics step can be divided into narrow-phase and
+broad-phase. In the narrow-phase we compute contact points between pairs of
+shapes. Imagine we have N shapes. Using brute force, we would need to perform
+the narrow-phase for N*N/2 pairs.
+
+The b2BroadPhase class reduces this load by using a dynamic tree for pair
+management. This greatly reduces the number of narrow-phase calls.
+
+Normally you do not interact with the broad-phase directly. Instead, LiquidFun
+creates and manages a broad-phase internally. Also, b2BroadPhase is designed
+with LiquidFun’s simulation loop in mind, so it is likely not suited for
+other use cases.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 37 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter05_Dynamics_Module.md

@@ -0,0 +1,37 @@
+# Dynamics Module
+
+[Overview](#ov)<br/>
+
+<a name="ov">
+## Overview
+
+The Dynamics module is the most complex part of LiquidFun and is the part you
+likely interact with the most. The Dynamics module sits on top of the Common
+and Collision modules, so you should be somewhat familiar with those by now.
+
+The Dynamics module contains:
+
+* fixture class
+
+* rigid body class
+
+* contact class
+
+* joint classes
+
+* world class
+
+* listener classes
+
+There are many dependencies between these classes so it is difficult to
+describe one class without referring to another. In the following, you may see
+some references to classes that have not been described yet. Therefore, you
+may want to quickly skim this chapter before reading it closely.
+
+The dynamics module is covered in the following chapters.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 363 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter06_Bodies.md

@@ -0,0 +1,363 @@
+# Bodies
+
+[About](#about)<br/>
+[Body Definition](#bd)<br/>
+[Body Factory](#bf)<br/>
+[Using a Body](#ub)<br/>
+
+
+<a name="about">
+## About
+
+Bodies have position and velocity. You can apply forces, torques, and impulses
+to bodies. Bodies can be static, kinematic, or dynamic. Here are the body type
+definitions:
+
+### b2_staticBody
+
+A static body does not move under simulation and behaves as if it has infinite
+mass. Internally, LiquidFun stores zero for the mass and the inverse mass.
+Static bodies can be moved manually by the user. A static body has zero
+velocity. Static bodies do not collide with other static or kinematic bodies.
+
+### b2_kinematicBody
+
+A kinematic body moves under simulation according to its velocity. Kinematic
+bodies do not respond to forces. They can be moved manually by the user, but
+normally a kinematic body is moved by setting its velocity. A kinematic body
+behaves as if it has infinite mass, however, LiquidFun stores zero for the
+mass and the inverse mass. Kinematic bodies do not collide with other
+kinematic or static bodies.
+
+### b2_dynamicBody
+
+A dynamic body is fully simulated. They can be moved manually by the user, but
+normally they move according to forces. A dynamic body can collide with all
+body types. A dynamic body always has finite, non-zero mass. If you try to set
+the mass of a dynamic body to zero, it will automatically acquire a mass of
+one kilogram and it won’t rotate.
+
+Bodies are the backbone for fixtures (shapes). Bodies carry fixtures and move
+them around in the world. Bodies are always rigid bodies in LiquidFun. That
+means that two fixtures attached to the same rigid body never move relative to
+each other and fixtures attached to the same body don’t collide.
+
+Fixtures have collision geometry and density. Normally, bodies acquire their
+mass properties from the fixtures. However, you can override the mass
+properties after a body is constructed.
+
+You usually keep pointers to all the bodies you create. This way you can query
+the body positions to update the positions of your graphical entities. You
+should also keep body pointers so you can destroy them when you are done with
+them.
+
+<a name="bd">
+## Body Definition
+
+Before a body is created you must create a body definition (b2BodyDef). The
+body definition holds the data needed to create and initialize a body.
+
+LiquidFun copies the data out of the body definition; it does not keep a
+pointer to the body definition. This means you can recycle a body definition
+to create multiple bodies.
+
+Let’s go over some of the key members of the body definition.
+
+### Body Type
+
+As discussed at the beginning of this chapter, there are three different body
+types: static, kinematic, and dynamic. You should establish the body type at
+creation because changing the body type later is expensive.
+
+&nbsp;&nbsp;&nbsp;`bodyDef.type = b2_dynamicBody;`<br/>
+
+Setting the body type is mandatory.
+
+### Position and Angle
+
+The body definition gives you the chance to initialize the position of the
+body on creation. This has far better performance than creating the body at
+the world origin and then moving the body.
+
+	Caution
+	
+	Do not create a body at the origin and then move it. If you create
+several bodies at the origin, then performance will suffer.
+
+
+
+A body has two main points of interest. The first point is the body's origin.
+Fixtures and joints are attached relative to the body's origin. The second
+point of interest is the center of mass. The center of mass is determined from
+mass distribution of the attached shapes or is explicitly set with b2MassData.
+Much of LiquidFun's internal computations use the center of mass position. For
+example b2Body stores the linear velocity for the center of mass.
+
+When you are building the body definition, you may not know where the center
+of mass is located. Therefore you specify the position of the body's origin.
+You may also specify the body's angle in radians, which is not affected by the
+position of the center of mass. If you later change the mass properties of the
+body, then the center of mass may move on the body, but the origin position
+does not change and the attached shapes and joints do not move.
+
+&nbsp;&nbsp;&nbsp;`bodyDef.position.Set(0.0f, 2.0f);   // the body's origin
+position.`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.angle = 0.25f * b2_pi;      // the body's angle in
+radians.`<br/>
+
+A rigid body is also a frame of reference. You can define fixtures and joints
+in that frame. Those fixtures and joint anchors never move in the local frame
+of the body.
+
+### Damping
+
+Damping is used to reduce the world velocity of bodies. Damping is different
+than friction because friction only occurs with contact. Damping is not a
+replacement for friction and the two effects should be used together.
+
+Damping parameters should be between 0 and infinity, with 0 meaning no
+damping, and infinity meaning full damping. Normally you will use a damping
+value between 0 and 0.1. I generally do not use linear damping because it
+makes bodies look floaty.
+
+&nbsp;&nbsp;&nbsp;`bodyDef.linearDamping = 0.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.angularDamping = 0.01f;`<br/>
+
+Damping is approximated for stability and performance. At small damping values
+the damping effect is mostly independent of the time step. At larger damping
+values, the damping effect will vary with the time step. This is not an issue
+if you use a fixed time step (recommended).
+
+### Gravity Scale
+
+You can use the gravity scale to adjust the gravity on a single body. Be
+careful though, increased gravity can decrease stability.
+
+&nbsp;&nbsp;&nbsp;`// Set the gravity scale to zero so this body will
+float`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.gravityScale = 0.0f;`<br/>
+
+### Sleep Parameters
+
+What does sleep mean? Well it is expensive to simulate bodies, so the less we
+have to simulate the better. When a body comes to rest we would like to stop
+simulating it.
+
+When LiquidFun determines that a body (or group of bodies) has come to rest,
+the body enters a sleep state which has very little CPU overhead. If a body is
+awake and collides with a sleeping body, then the sleeping body wakes up.
+Bodies will also wake up if a joint or contact attached to them is destroyed.
+You can also wake a body manually.
+
+The body definition lets you specify whether a body can sleep and whether a
+body is created sleeping.
+
+&nbsp;&nbsp;&nbsp;`bodyDef.allowSleep = true;`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.awake = true;`<br/>
+
+### Fixed Rotation
+
+You may want a rigid body, such as a character, to have a fixed rotation. Such
+a body should not rotate, even under load. You can use the fixed rotation
+setting to achieve this:
+
+&nbsp;&nbsp;&nbsp;`bodyDef.fixedRotation = true;`<br/>
+
+The fixed rotation flag causes the rotational inertia and its inverse to be
+set to zero.
+
+### Bullets
+
+Game simulation usually generates a sequence of images that are played at some
+frame rate. This is called discrete simulation. In discrete simulation, rigid
+bodies can move by a large amount in one time step. If a physics engine
+doesn't account for the large motion, you may see some objects incorrectly
+pass through each other. This effect is called tunneling.
+
+By default, LiquidFun uses continuous collision detection (CCD) to prevent
+dynamic bodies from tunneling through static bodies. This is done by sweeping
+shapes from their old position to their new positions. The engine looks for
+new collisions during the sweep and computes the time of impact (TOI) for
+these collisions. Bodies are moved to their first TOI and then halted for the
+remainder of the time step.
+
+Normally CCD is not used between dynamic bodies. This is done to keep
+performance reasonable. In some game scenarios you need dynamic bodies to use
+CCD. For example, you may want to shoot a high speed bullet at a stack of
+dynamic bricks. Without CCD, the bullet might tunnel through the bricks.
+
+Fast moving objects in LiquidFun can be labeled as bullets. Bullets will
+perform CCD with both static and dynamic bodies. You should decide what bodies
+should be bullets based on your game design. If you decide a body should be
+treated as a bullet, use the following setting.
+
+&nbsp;&nbsp;&nbsp;`bodyDef.bullet = true;`<br/>
+
+The bullet flag only affects dynamic bodies.
+
+LiquidFun performs continuous collision sequentially, so bullets may miss fast
+moving bodies.
+
+### Activation
+
+You may wish a body to be created but not participate in collision or
+dynamics. This state is similar to sleeping except the body will not be woken
+by other bodies and the body's fixtures will not be placed in the broad-phase.
+This means the body will not participate in collisions, ray casts, etc.
+
+You can create a body in an inactive state and later re-activate it.
+
+&nbsp;&nbsp;&nbsp;`bodyDef.active = true;`<br/>
+
+Joints may be connected to inactive bodies. These joints will not be
+simulated. You should be careful when you activate a body that its joints are
+not distorted.
+
+### User Data
+
+User data is a void pointer. This gives you a hook to link your application
+objects to bodies. You should be consistent to use the same object type for
+all body user data.
+
+&nbsp;&nbsp;&nbsp;`b2BodyDef bodyDef;`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.userData = &myActor;`<br/>
+
+<a name="bf">
+## Body Factory
+
+Bodies are created and destroyed using a body factory provided by the world
+class. This lets the world create the body with an efficient allocator and add
+the body to the world data structure.
+
+Bodies can be dynamic or static depending on the mass properties. Both body
+types use the same creation and destruction methods.
+
+&nbsp;&nbsp;&nbsp;`b2Body* dynamicBody = myWorld->CreateBody(&bodyDef);`<br/>
+&nbsp;&nbsp;&nbsp;`... do stuff …`<br/>
+&nbsp;&nbsp;&nbsp;`myWorld->DestroyBody(dynamicBody);`<br/>
+&nbsp;&nbsp;&nbsp;`dynamicBody = NULL;`<br/>
+
+	Caution
+	
+	You should never use new or malloc to create a body. The world won't
+know about the body and the body won't be properly initialized.
+
+
+
+Static bodies do not move under the influence of other bodies. You may
+manually move static bodies, but you should be careful so that you don't
+squash dynamic bodies between two or more static bodies. Friction will not
+work correctly if you move a static body. Static bodies never collide with
+static or kinematic bodies. It is faster to attach several shapes to a static
+body than to create several static bodies with a single shape on each one.
+Internally, LiquidFun sets the mass and inverse mass of static bodies to zero.
+This makes the math work out so that most algorithms don't need to treat
+static bodies as a special case.
+
+LiquidFun does not keep a reference to the body definition or any of the data
+it holds (except user data pointers). So you can create temporary body
+definitions and reuse the same body definitions.
+
+LiquidFun allows you to avoid destroying bodies by deleting your b2World
+object, which does all the cleanup work for you. However, you should be
+mindful to nullify body pointers that you keep in your game engine.
+
+When you destroy a body, the attached fixtures and joints are automatically
+destroyed. This has important implications for how you manage shape and joint
+pointers.
+
+<a name="ub">
+## Using a Body
+
+After creating a body, there are many operations you can perform on the body.
+These include setting mass properties, accessing position and velocity,
+applying forces, and transforming points and vectors.
+
+### Mass Data
+
+Every body has a mass (scalar), center of mass (2-vector), and rotational
+inertia (scalar). For static bodies, the mass and rotational inertia are set
+to zero. When a body has fixed rotation, its rotational inertia is zero.
+
+Normally the mass properties of a body are established automatically when
+fixtures are added to the body. You can also adjust the mass of a body at
+run-time. This is usually done when you have special game scenarios that
+require altering the mass.
+
+&nbsp;&nbsp;&nbsp;`void SetMassData(const b2MassData* data);`<br/>
+
+After setting a body's mass directly, you may wish to revert to the natural
+mass dictated by the fixtures. You can do this with:
+
+&nbsp;&nbsp;&nbsp;`void ResetMassData();`<br/>
+
+The body's mass data is available through the following functions:
+
+&nbsp;&nbsp;&nbsp;`float32 GetMass() const;`
+
+&nbsp;&nbsp;&nbsp;`float32 GetInertia() const;`
+
+&nbsp;&nbsp;&nbsp;`const b2Vec2& GetLocalCenter() const;`
+
+&nbsp;&nbsp;&nbsp;`void GetMassData(b2MassData* data) const;`
+
+### State Information
+
+There are many aspects to the body's state. You can access this state data
+efficiently through the following functions:
+
+&nbsp;&nbsp;&nbsp;`void SetType(b2BodyType type);`
+
+&nbsp;&nbsp;&nbsp;`b2BodyType GetType();`
+
+&nbsp;&nbsp;&nbsp;`void SetBullet(bool flag);`
+
+&nbsp;&nbsp;&nbsp;`bool IsBullet() const;`
+
+&nbsp;&nbsp;&nbsp;`void SetSleepingAllowed(bool flag);`
+
+&nbsp;&nbsp;&nbsp;`bool IsSleepingAllowed() const;`
+
+&nbsp;&nbsp;&nbsp;`void SetAwake(bool flag);`
+
+&nbsp;&nbsp;&nbsp;`bool IsAwake() const;`
+
+&nbsp;&nbsp;&nbsp;`void SetActive(bool flag);`
+
+&nbsp;&nbsp;&nbsp;`bool IsActive() const;`
+
+&nbsp;&nbsp;&nbsp;`void SetFixedRotation(bool flag);`
+
+&nbsp;&nbsp;&nbsp;`bool IsFixedRotation() const;`
+
+### Position and Velocity
+
+You can access the position and rotation of a body. This is common when
+rendering your associated game actor. You can also set the position, although
+this is less common since you will normally use LiquidFun to simulate movement.
+
+&nbsp;&nbsp;&nbsp;`bool SetTransform(const b2Vec2& position, float32
+angle);`<br/>
+&nbsp;&nbsp;&nbsp;`const b2Transform& GetTransform() const;`<br/>
+&nbsp;&nbsp;&nbsp;`const b2Vec2& GetPosition() const;`<br/>
+&nbsp;&nbsp;&nbsp;`float32 GetAngle() const;`<br/>
+
+You can access the center of mass position in local and world coordinates.
+Much of the internal simulation in LiquidFun uses the center of mass. However,
+you should normally not need to access it. Instead you will usually work with
+the body transform. For example, you may have a body that is square. The body
+origin might be a corner of the square, while the center of mass is located at
+the center of the square.
+
+&nbsp;&nbsp;&nbsp;`const b2Vec2& GetWorldCenter() const;`<br/>
+&nbsp;&nbsp;&nbsp;`const b2Vec2& GetLocalCenter() const;`<br/>
+
+You can access the linear and angular velocity. The linear velocity is for the
+center of mass. Therefore, the linear velocity may change if the mass
+properties change.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 201 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter07_Fixtures.md

@@ -0,0 +1,201 @@
+# Fixtures
+
+[About](#about)<br/>
+[Fixture Creation](#fc)<br/>
+[Sensors](#se)<br/>
+
+<a name="about">
+## About
+
+Recall that shapes don’t know about bodies and may be used independently of
+the physics simulation. Therefore LiquidFun provides the b2Fixture class to
+attach shapes to bodies. A body may have zero or more fixtures. A body with
+multiple fixtures is sometimes called a *compound body.*
+
+Fixtures hold the following:
+
+* a single shape
+
+* broad-phase proxies
+
+* density, friction, and restitution
+
+* collision filtering flags
+
+* back pointer to the parent body
+
+* user data
+
+* sensor flag
+
+These are described in the following sections.
+
+<a name="fc">
+## Fixture Creation
+
+Fixtures are created by initializing a fixture definition and then passing the
+definition to the parent body.
+
+&nbsp;&nbsp;&nbsp;`b2FixtureDef fixtureDef;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.shape = &myShape;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.density = 1.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`b2Fixture* myFixture =
+myBody->CreateFixture(&fixtureDef);`<br/>
+
+This creates the fixture and attaches it to the body. You do not need to store
+the fixture pointer since the fixture will automatically be destroyed when the
+parent body is destroyed. You can create multiple fixtures on a single body.
+
+You can destroy a fixture on the parent body. You may do this to model a
+breakable object. Otherwise you can just leave the fixture alone and let the
+body destruction take care of destroying the attached fixtures.
+
+&nbsp;&nbsp;&nbsp;`myBody->DestroyFixture(myFixture);`<br/>
+
+### Density
+
+The fixture density is used to compute the mass properties of the parent body.
+The density can be zero or positive. You should generally use similar
+densities for all your fixtures. This will improve stacking stability.
+
+The mass of a body is not adjusted when you set the density. You must call
+ResetMassData for this to occur.
+
+&nbsp;&nbsp;&nbsp;`fixture->SetDensity(5.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`body->ResetMassData();`<br/>
+
+### Friction
+
+Friction is used to make objects slide along each other realistically.
+LiquidFun supports static and dynamic friction, but uses the same parameter
+for both. Friction is simulated accurately in LiquidFun and the friction
+strength is proportional to the normal force (this is called Coulomb
+friction). The friction parameter is usually set between 0 and 1, but can be
+any non-negative value. A friction value of 0 turns off friction and a value
+of 1 makes the friction strong. When the friction force is computed between
+two shapes, LiquidFun must combine the friction parameters of the two parent
+fixtures. This is done with the geometric mean:
+
+&nbsp;&nbsp;&nbsp;`float32 friction;`<br/>
+&nbsp;&nbsp;&nbsp;`friction = sqrtf(fixtureA->friction *
+fixtureB->friction);`<br/>
+
+So if one fixture has zero friction then the contact will have zero friction.
+
+You can override the default mixed friction using b2Contact::SetFriction. This
+is usually done in the b2ContactListener callback.
+
+### Restitution
+
+Restitution is used to make objects bounce. The restitution value is usually
+set to be between 0 and 1. Consider dropping a ball on a table. A value of
+zero means the ball won't bounce. This is called an inelastic collision. A
+value of one means the ball's velocity will be exactly reflected. This is
+called a perfectly elastic collision. Restitution is combined using the
+following formula.
+
+&nbsp;&nbsp;&nbsp;`float32 restitution;`<br/>
+&nbsp;&nbsp;&nbsp;`restitution = b2Max(fixtureA->restitution,
+fixtureB->restitution);`<br/>
+
+Restitution is combined this way so that you can have a bouncy super ball
+without having a bouncy floor.
+
+You can override the default mixed restitution using
+b2Contact::SetRestitution. This is usually done in the b2ContactListener
+callback.
+
+When a shape develops multiple contacts, restitution is simulated
+approximately. This is because LiquidFun uses an iterative solver. LiquidFun
+also uses inelastic collisions when the collision velocity is small. This is
+done to prevent jitter. See b2_velocityThreshold in b2Settings.h.
+
+### Filtering
+
+Collision filtering allows you to prevent collision between fixtures. For
+example, say you make a character that rides a bicycle. You want the bicycle
+to collide with the terrain and the character to collide with the terrain, but
+you don't want the character to collide with the bicycle (because they must
+overlap). LiquidFun supports such collision filtering using categories and
+groups.
+
+LiquidFun supports 16 collision categories. For each fixture you can specify
+which category it belongs to. You also specify what other categories this
+fixture can collide with. For example, you could specify in a multiplayer game
+that all players don't collide with each other and monsters don't collide with
+each other, but players and monsters should collide. This is done with masking
+bits. For example:
+
+&nbsp;&nbsp;&nbsp;`playerFixtureDef.filter.categoryBits = 0x0002;`<br/>
+&nbsp;&nbsp;&nbsp;`monsterFixtureDef.filter.categoryBits = 0x0004;`<br/>
+&nbsp;&nbsp;&nbsp;`playerFixtureDef.filter.maskBits = 0x0004;`<br/>
+&nbsp;&nbsp;&nbsp;`monsterFixtureDef.filter.maskBits = 0x0002;`<br/>
+
+Here is the rule for a collision to occur:
+
+&nbsp;&nbsp;&nbsp;`uint16 catA = fixtureA.filter.categoryBits;`<br/>
+&nbsp;&nbsp;&nbsp;`uint16 maskA = fixtureA.filter.maskBits;`<br/>
+&nbsp;&nbsp;&nbsp;`uint16 catB = fixtureB.filter.categoryBits;`<br/>
+&nbsp;&nbsp;&nbsp;`uint16 maskB = fixtureB.filter.maskBits;`<br/>
+&nbsp;&nbsp;&nbsp;`if ((catA & maskB) != 0 && (catB & maskA) != 0)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  `// fixtures can collide`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+Collision groups let you specify an integral group index. You can have all
+fixtures with the same group index always collide (positive index) or never
+collide (negative index). Group indices are usually used for things that are
+somehow related, like the parts of a bicycle. In the following example,
+fixture1 and fixture2 always collide, but fixture3 and fixture4 never collide.
+
+&nbsp;&nbsp;&nbsp;`fixture1Def.filter.groupIndex = 2;`<br/>
+&nbsp;&nbsp;&nbsp;`fixture2Def.filter.groupIndex = 2;`<br/>
+&nbsp;&nbsp;&nbsp;`fixture3Def.filter.groupIndex = -8;`<br/>
+&nbsp;&nbsp;&nbsp;`fixture4Def.filter.groupIndex = -8;`<br/>
+
+Collisions between fixtures of different group indices are filtered according
+the category and mask bits. In other words, group filtering has higher
+precedence than category filtering.
+
+Note that additional collision filtering occurs in LiquidFun. Here is a list:
+
+* A fixture on a static body can only collide with a dynamic body.
+
+* A fixture on a kinematic body can only collide with a dynamic body.
+
+* Fixtures on the same body never collide with each other.
+
+* You can optionally enable/disable collision between fixtures on bodies
+connected by a joint.
+
+Sometimes you might need to change collision filtering after a fixture has
+already been created. You can get and set the b2Filter structure on an
+existing fixture using b2Fixture::GetFilterData and b2Fixture::SetFilterData.
+Note that changing the filter data will not add or remove contacts until the
+next time step (see the World class).
+
+<a name="se">
+## Sensors
+
+Sometimes game logic needs to know when two fixtures overlap yet there should
+be no collision response. This is done by using sensors. A sensor is a fixture
+that detects collision but does not produce a response.
+
+You can flag any fixture as being a sensor. Sensors may be static, kinematic,
+or dynamic. Remember that you may have multiple fixtures per body and you can
+have any mix of sensors and solid fixtures. Also, sensors only form contacts
+when at least one body is dynamic, so you will not get a contact for kinematic
+versus kinematic, kinematic versus static, or static versus static.
+
+Sensors do not generate contact points. There are two ways to get the state of
+a sensor:
+
+1. `b2Contact::IsTouching`
+
+2. `b2ContactListener::BeginContact and EndContact`
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 434 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter08_Joints.md

@@ -0,0 +1,434 @@
+# Joints
+
+[About](#about)<br/>
+[Joint Definition](#jd)<br/>
+[Joint Factory](#jf)<br/>
+[Using Joints](#uj)<br/>
+
+<a name="about">
+
+## About
+
+Joints are used to constrain bodies to the world or to each other. Typical
+examples in games include ragdolls, teeters, and pulleys. Joints can be
+combined in many different ways to create interesting motions.
+
+Some joints provide limits so you can control the range of motion. Some joint
+provide motors which can be used to drive the joint at a prescribed speed
+until a prescribed force/torque is exceeded.
+
+Joint motors can be used in many ways. You can use motors to control position
+by specifying a joint velocity that is proportional to the difference between
+the actual and desired position. You can also use motors to simulate joint
+friction: set the joint velocity to zero and provide a small, but significant
+maximum motor force/torque. Then the motor will attempt to keep the joint from
+moving until the load becomes too strong.
+
+<a name="jd">
+## Joint Definition
+
+Each joint type has a definition that derives from b2JointDef. All joints are
+connected between two different bodies. One body may static. Joints between
+static and/or kinematic bodies are allowed, but have no effect and use some
+processing time.
+
+You can specify user data for any joint type and you can provide a flag to
+prevent the attached bodies from colliding with each other. This is actually
+the default behavior and you must set the collideConnected Boolean to allow
+collision between to connected bodies.
+
+Many joint definitions require that you provide some geometric data. Often a
+joint will be defined by anchor points. These are points fixed in the attached
+bodies. LiquidFun requires these points to be specified in local coordinates.
+This way the joint can be specified even when the current body transforms
+violate the joint constraint --- a common occurrence when a game is saved and
+reloaded. Additionally, some joint definitions need to know the default
+relative angle between the bodies. This is necessary to constrain rotation
+correctly.
+
+Initializing the geometric data can be tedious, so many joints have
+initialization functions that use the current body transforms to remove much
+of the work. However, these initialization functions should usually only be
+used for prototyping. Production code should define the geometry directly.
+This will make joint behavior more robust.
+
+The rest of the joint definition data depends on the joint type. We cover
+these now.
+
+<a name="jf">
+## Joint Factory
+
+Joints are created and destroyed using the world factory methods. This brings
+up an old issue:
+
+    Caution
+
+    Don't try to create a joint on the stack or on the heap using new or malloc.  You must create and destroy bodies and joints using the create and destroy methods of the b2World class.
+
+Here's an example of the lifetime of a revolute joint:
+
+&nbsp;&nbsp;&nbsp;`b2RevoluteJointDef jointDef;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.bodyA = myBodyA;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.bodyB = myBodyB;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.anchorPoint = myBodyA->GetCenterPosition();`<br/>
+&nbsp;&nbsp;&nbsp;`b2RevoluteJoint* joint =
+(b2RevoluteJoint*)myWorld->CreateJoint(&jointDef);`<br/>
+&nbsp;&nbsp;&nbsp;`… do stuff …`<br/>
+&nbsp;&nbsp;&nbsp;`myWorld->DestroyJoint(joint);`<br/>
+&nbsp;&nbsp;&nbsp;`joint = NULL;`<br/>
+
+It is always good to nullify your pointer after they are destroyed. This will
+make the program crash in a controlled manner if you try to reuse the pointer.
+
+The lifetime of a joint is not simple. Heed this warning well:
+
+    Caution
+
+    Joints are destroyed when an attached body is destroyed.
+
+This precaution is not always necessary. You may organize your game engine so
+that joints are always destroyed before the attached bodies. In this case you
+don't need to implement the listener class. See the section on Implicit
+Destruction for details.
+
+<a name="uj">
+## Using Joints
+
+Many simulations create the joints and don't access them again until they are
+destroyed. However, there is a lot of useful data contained in joints that you
+can use to create a rich simulation.
+
+First of all, you can get the bodies, anchor points, and user data from a
+joint.
+
+&nbsp;&nbsp;&nbsp;`b2Body* GetBodyA();`
+
+&nbsp;&nbsp;&nbsp;`b2Body* GetBodyB();`
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetAnchorA();`
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetAnchorB();`
+
+&nbsp;&nbsp;&nbsp;`void* GetUserData();`
+
+All joints have a reaction force and torque. This the reaction force applied
+to body 2 at the anchor point. You can use reaction forces to break joints or
+trigger other game events. These functions may do some computations, so don't
+call them if you don't need the result.
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetReactionForce();`<br/>
+
+&nbsp;&nbsp;&nbsp;`float32 GetReactionTorque();`<br/>
+
+### Distance Joint
+
+One of the simplest joint is a distance joint which says that the distance
+between two points on two bodies must be constant. When you specify a distance
+joint the two bodies should already be in place. Then you specify the two
+anchor points in world coordinates. The first anchor point is connected to
+body 1, and the second anchor point is connected to body 2. These points imply
+the length of the distance constraint.
+
+<img align="center" src="image_18.gif" alt="Distance joint" height="118"
+width="155"><br/>
+
+Here is an example of a distance joint definition. In this case we decide to
+allow the bodies to collide.
+
+&nbsp;&nbsp;&nbsp;`b2DistanceJointDef jointDef;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.Initialize(myBodyA, myBodyB, worldAnchorOnBodyA,
+worldAnchorOnBodyB);`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.collideConnected = true;`<br/>
+
+The distance joint can also be made soft, like a spring-damper connection. See
+the Web example in the testbed to see how this behaves.
+
+Softness is achieved by tuning two constants in the definition: frequency and
+damping ratio. Think of the frequency as the frequency of a harmonic
+oscillator (like a guitar string). The frequency is specified in Hertz.
+Typically the frequency should be less than a half the frequency of the time
+step. So if you are using a 60Hz time step, the frequency of the distance
+joint should be less than 30Hz. The reason is related to the Nyquist frequency.
+
+The damping ratio is non-dimensional and is typically between 0 and 1, but can
+be larger. At 1, the damping is critical (all oscillations should vanish).
+
+&nbsp;&nbsp;&nbsp;`jointDef.frequencyHz = 4.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.dampingRatio = 0.5f;`<br/>
+
+### Revolute Joint
+
+A revolute joint forces two bodies to share a common anchor point, often
+called a hinge point. The revolute joint has a single degree of freedom: the
+relative rotation of the two bodies. This is called the joint angle.
+
+<img align="center" src="image_19.gif" alt="Revolute joint" height="97"
+width="139"><br/>
+
+To specify a revolute you need to provide two bodies and a single anchor point
+in world space. The initialization function assumes that the bodies are
+already in the correct position.
+
+In this example, two bodies are connected by a revolute joint at the first
+body's center of mass.
+
+&nbsp;&nbsp;&nbsp;`b2RevoluteJointDef jointDef;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.Initialize(myBodyA, myBodyB,
+myBodyA->GetWorldCenter());`<br/>
+
+The revolute joint angle is positive when bodyB rotates CCW about the angle
+point. Like all angles in LiquidFun, the revolute angle is measured in
+radians. By convention the revolute joint angle is zero when the joint is
+created using Initialize(), regardless of the current rotation of the two
+bodies.
+
+In some cases you might wish to control the joint angle. For this, the
+revolute joint can optionally simulate a joint limit and/or a motor.
+
+A joint limit forces the joint angle to remain between a lower and upper
+bound. The limit will apply as much torque as needed to make this happen. The
+limit range should include zero, otherwise the joint will lurch when the
+simulation begins.
+
+A joint motor allows you to specify the joint speed (the time derivative of
+the angle). The speed can be negative or positive. A motor can have infinite
+force, but this is usually not desirable. Recall the eternal question:
+
+*"What happens when an irresistible force meets an immovable object?"*
+
+I can tell you it's not pretty. So you can provide a maximum torque for the
+joint motor. The joint motor will maintain the specified speed unless the
+required torque exceeds the specified maximum. When the maximum torque is
+exceeded, the joint will slow down and can even reverse.
+
+You can use a joint motor to simulate joint friction. Just set the joint speed
+to zero, and set the maximum torque to some small, but significant value. The
+motor will try to prevent the joint from rotating, but will yield to a
+significant load.
+
+Here's a revision of the revolute joint definition above; this time the joint
+has a limit and a motor enabled. The motor is setup to simulate joint friction.
+
+b2RevoluteJointDef jointDef;
+jointDef.Initialize(bodyA, bodyB, myBodyA->GetWorldCenter());
+jointDef.lowerAngle = -0.5f * b2_pi; // -90 degrees
+jointDef.upperAngle = 0.25f * b2_pi; // 45 degrees
+jointDef.enableLimit = true;
+jointDef.maxMotorTorque = 10.0f;
+jointDef.motorSpeed = 0.0f;
+jointDef.enableMotor = true;
+
+You can access a revolute joint's angle, speed, and motor torque.
+
+&nbsp;&nbsp;&nbsp;`float32 GetJointAngle() const;`<br/>
+&nbsp;&nbsp;&nbsp;`float32 GetJointSpeed() const;`<br/>
+&nbsp;&nbsp;&nbsp;`float32 GetMotorTorque() const;`<br/>
+
+You also update the motor parameters each step.
+
+&nbsp;&nbsp;&nbsp;`void SetMotorSpeed(float32 speed);`<br/>
+&nbsp;&nbsp;&nbsp;`void SetMaxMotorTorque(float32 torque);`<br/>
+
+Joint motors have some interesting abilities. You can update the joint speed
+every time step so you can make the joint move back-and-forth like a sine-wave
+or according to whatever function you want.
+
+&nbsp;&nbsp;&nbsp;`... Game Loop Begin ...`<br/>
+&nbsp;&nbsp;&nbsp;`myJoint->SetMotorSpeed(cosf(0.5f * time));`<br/>
+&nbsp;&nbsp;&nbsp;`... Game Loop End ...`<br/>
+
+You can also use joint motors to track a desired joint angle. For example:
+
+&nbsp;&nbsp;&nbsp;`... Game Loop Begin ...`<br/>
+&nbsp;&nbsp;&nbsp;`float32 angleError = myJoint->GetJointAngle() -
+angleTarget;`<br/>
+&nbsp;&nbsp;&nbsp;`float32 gain = 0.1f;`<br/>
+&nbsp;&nbsp;&nbsp;`myJoint->SetMotorSpeed(-gain * angleError);`<br/>
+&nbsp;&nbsp;&nbsp;`... Game Loop End ...`<br/>
+
+Generally your gain parameter should not be too large. Otherwise your joint
+may become unstable.
+
+### Prismatic Joint
+
+A prismatic joint allows for relative translation of two bodies along a
+specified axis. A prismatic joint prevents relative rotation. Therefore, a
+prismatic joint has a single degree of freedom.
+
+<img align="center" src="image_20.gif" alt="Prismatic joint" height="134"
+width="165"><br/>
+
+The prismatic joint definition is similar to the revolute joint description;
+just substitute translation for angle and force for torque. Using this analogy
+provides an example prismatic joint definition with a joint limit and a
+friction motor:
+
+&nbsp;&nbsp;&nbsp;`b2PrismaticJointDef jointDef;`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 worldAxis(1.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.Initialize(myBodyA, myBodyB,
+myBodyA->GetWorldCenter(), worldAxis);`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.lowerTranslation = -5.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.upperTranslation = 2.5f;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.enableLimit = true;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.maxMotorForce = 1.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.motorSpeed = 0.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.enableMotor = true;`<br/>
+
+The revolute joint has an implicit axis coming out of the screen. The
+prismatic joint needs an explicit axis parallel to the screen. This axis is
+fixed in the two bodies and follows their motion.
+
+Like the revolute joint, the prismatic joint translation is zero when the
+joint is created using Initialize(). So be sure zero is between your lower and
+upper translation limits.
+
+Using a prismatic joint is similar to using a revolute joint. Here are the
+relevant member functions:
+
+&nbsp;&nbsp;&nbsp;`float32 GetJointTranslation() const;`
+
+&nbsp;&nbsp;&nbsp;`float32 GetJointSpeed() const;`
+
+&nbsp;&nbsp;&nbsp;`float32 GetMotorForce() const;`
+
+&nbsp;&nbsp;&nbsp;`void SetMotorSpeed(float32 speed);`
+
+&nbsp;&nbsp;&nbsp;`void SetMotorForce(float32 force);`
+
+### Pulley Joint
+
+A pulley is used to create an idealized pulley. The pulley connects two bodies
+to ground and to each other. As one body goes up, the other goes down. The
+total length of the pulley rope is conserved according to the initial
+configuration.
+
+length1 + length2 == constant
+
+You can supply a ratio that simulates a block and tackle. This causes one side
+of the pulley to extend faster than the other. At the same time the constraint
+force is smaller on one side than the other. You can use this to create
+mechanical leverage.
+
+length1 + ratio * length2 == constant
+
+For example, if the ratio is 2, then length1 will vary at twice the rate of
+length2. Also the force in the rope attached to body1 will have half the
+constraint force as the rope attached to body2.
+
+<img align="center" src="image_21.gif" alt="Pulley joint" height="213"
+width="237"><br/>
+
+Pulleys can be troublesome when one side is fully extended. The rope on the
+other side will have zero length. At this point the constraint equations
+become singular (bad). You should configure collision shapes to prevent this.
+
+Here is an example pulley definition:
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 anchor1 = myBody1->GetWorldCenter();`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 anchor2 = myBody2->GetWorldCenter();`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 groundAnchor1(p1.x, p1.y + 10.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 groundAnchor2(p2.x, p2.y + 12.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`float32 ratio = 1.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`b2PulleyJointDef jointDef;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.Initialize(myBody1, myBody2, groundAnchor1,
+groundAnchor2, anchor1, anchor2, ratio);`<br/>
+
+Pulley joints provide the current lengths.
+
+&nbsp;&nbsp;&nbsp;`float32 GetLengthA() const;`<br/>
+&nbsp;&nbsp;&nbsp;`float32 GetLengthB() const;`<br/>
+
+### Gear Joint
+
+If you want to create a sophisticated mechanical contraption you might want to
+use gears. In principle you can create gears in LiquidFun by using compound
+shapes to model gear teeth. This is not very efficient and might be tedious to
+author. You also have to be careful to line up the gears so the teeth mesh
+smoothly. LiquidFun has a simpler method of creating gears:  the gear joint.
+
+<img align="center" src="image_22.gif" alt="Gear joint" height="188"
+width="179"><br/>
+
+The gear joint can only connect revolute and/or prismatic joints.
+
+Like the pulley ratio, you can specify a gear ratio. However, in this case the
+gear ratio can be negative. Also keep in mind that when one joint is a
+revolute joint (angular) and the other joint is prismatic (translation), and
+then the gear ratio will have units of length or one over length.
+
+coordinate1 + ratio * coordinate2 == constant
+
+Here is an example gear joint. The bodies myBodyA and myBodyB are any bodies
+from the two joints, as long as they are not the same bodies.
+
+&nbsp;&nbsp;&nbsp;`b2GearJointDef jointDef;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.bodyA = myBodyA;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.bodyB = myBodyB;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.joint1 = myRevoluteJoint;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.joint2 = myPrismaticJoint;`<br/>
+&nbsp;&nbsp;&nbsp;`jointDef.ratio = 2.0f * b2_pi / myLength;`<br/>
+
+Note that the gear joint depends on two other joints. This creates a fragile
+situation. What happens if those joints are deleted?
+
+    Caution
+
+    Always delete gear joints before the revolute/prismatic joints on the gears. Otherwise your code will crash in a bad way due to the orphaned joint pointers in the gear joint. You should also delete the gear joint before you delete any of the bodies involved.
+
+
+### Mouse Joint
+
+The mouse joint is used in the testbed to manipulate bodies with the mouse. It
+attempts to drive a point on a body towards the current position of the
+cursor. There is no restriction on rotation.
+
+The mouse joint definition has a target point, maximum force, frequency, and
+damping ratio. The target point initially coincides with the body’s anchor
+point. The maximum force is used to prevent violent reactions when multiple
+dynamic bodies interact. You can make this as large as you like. The frequency
+and damping ratio are used to create a spring/damper effect similar to the
+distance joint.
+
+ Many users have tried to adapt the mouse joint for game play. Users often
+want to achieve precise positioning and instantaneous response. The mouse
+joint doesn’t work very well in that context. You may wish to consider using
+kinematic bodies instead.
+
+### Wheel Joint
+
+The wheel joint restricts a point on bodyB to a line on bodyA. The wheel joint
+also provides a suspension spring. See b2WheelJoint.h and Car.h for details.
+
+<img align="center" src="image_23.png" alt="Wheel joint" height="286"
+width="157"><br/>
+
+### Weld Joint
+
+The weld joint attempts to constrain all relative motion between two bodies.
+See the Cantilever.h in the testbed to see how the weld joint behaves.
+
+It is tempting to use the weld joint to define breakable structures. However,
+the LiquidFun solver is iterative so the joints are a bit soft. So chains of
+bodies connected by weld joints will flex.
+
+Instead it is better to create breakable bodies starting with a single body
+with multiple fixtures. When the body breaks, you can destroy a fixture and
+recreate it on a new body. See the Breakable example in the testbed.
+
+### Rope Joint
+
+The rope joint restricts the maximum distance between two points. This can be
+useful to prevent chains of bodies from stretching, even under high load. See
+b2RopeJoint.h and RopeJoint.h for details.
+
+### Friction Joint
+
+The friction joint is used for top-down friction. The joint provides 2D
+translational friction and angular friction. See b2FrictionJoint.h and
+ApplyForce.h for details.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 364 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter09_Contacts.md

@@ -0,0 +1,364 @@
+# Contacts
+
+[About](#about)<br/>
+[Contact Class](#cc)<br/>
+[Accessing Contacts](#ac)<br/>
+[Contact Listener](#cl)<br/>
+[Contact Filtering](#cf)<br/>
+
+
+<a name="about"></a>
+## About
+
+Contacts are objects created by LiquidFun to manage collision between two
+fixtures. If the fixture has children, such as a chain shape, then a contact
+exists for each relevant child. There are different kinds of contacts, derived
+from b2Contact, for managing contact between different kinds of fixtures. For
+example there is a contact class for managing polygon-polygon collision and
+another contact class for managing circle-circle collision.
+
+Here is some terminology associated with contacts.
+
+### contact point
+
+A contact point is a point where two shapes touch. LiquidFun approximates
+contact with a small number of points.
+
+### contact normal
+
+A contact normal is a unit vector that points from one shape to another. By
+convention, the normal points from fixtureA to fixtureB.
+
+### contact separation
+
+Separation is the opposite of penetration. Separation is negative when shapes
+overlap. It is possible that future versions of LiquidFun will create contact
+points with positive separation, so you may want to check the sign when
+contact points are reported.
+
+### contact manifold
+
+Contact between two convex polygons may generate up to 2 contact points. Both
+of these points use the same normal, so they are grouped into a contact
+manifold, which is an approximation of a continuous region of contact.
+
+### normal impulse
+
+The normal force is the force applied at a contact point to prevent the shapes
+from penetrating. For convenience, LiquidFun works with impulses. The normal
+impulse is just the normal force multiplied by the time step.
+
+### tangent impulse
+
+The tangent force is generated at a contact point to simulate friction. For
+convenience, this is stored as an impulse.
+
+### contact ids
+
+LiquidFun tries to re-use the contact force results from a time step as the
+initial guess for the next time step. LiquidFun uses contact ids to match
+contact points across time steps. The ids contain geometric features indices
+that help to distinguish one contact point from another.
+
+Contacts are created when two fixture’s AABBs overlap. Sometimes collision
+filtering will prevent the creation of contacts. Contacts are destroyed with
+the AABBs cease to overlap.
+
+So you might gather that there may be contacts created for fixtures that are
+not touching (just their AABBs). Well, this is correct. It's a "chicken or egg"
+problem. We don't know if we need a contact object until one is created
+to analyze the collision. We could delete the contact right away if the shapes
+are not touching, or we can just wait until the AABBs stop overlapping.
+LiquidFun takes the latter approach because it lets the system cache
+information to improve performance.
+
+<a name="cc">
+## Contact Class
+
+As mentioned before, the contact class is created and destroyed by LiquidFun.
+Contact objects are not created by the user. However, you are able to access
+the contact class and interact with it.
+
+You can access the raw contact manifold:
+
+&nbsp;&nbsp;&nbsp;`b2Manifold* GetManifold();`<br/>
+&nbsp;&nbsp;&nbsp;`const b2Manifold* GetManifold() const;`<br/>
+
+You can potentially modify the manifold, but this is generally not supported
+and is for advanced usage.
+
+There is a helper function to get the b2WorldManifold:
+
+&nbsp;&nbsp;&nbsp;`void GetWorldManifold(b2WorldManifold* worldManifold)
+const;`<br/>
+
+This uses the current positions of the bodies to compute world positions of
+the contact points.
+
+Sensors do not create manifolds, so for them use:
+
+&nbsp;&nbsp;&nbsp;`bool touching = sensorContact->IsTouching();`<br/>
+
+This function also works for non-sensors.
+
+You can get the fixtures from a contact. From those you can get the bodies.
+
+&nbsp;&nbsp;&nbsp;`b2Fixture* fixtureA = myContact->GetFixtureA();`<br/>
+&nbsp;&nbsp;&nbsp;`b2Body* bodyA = fixtureA->GetBody();`<br/>
+&nbsp;&nbsp;&nbsp;`MyActor* actorA = (MyActor*)bodyA->GetUserData();`<br/>
+
+You can disable a contact. This only works inside the
+b2ContactListener::PreSolve event, discussed below.
+
+<a name="ac">
+## Accessing Contacts
+
+You can get access to contacts in several ways. You can access the contacts
+directly on the world and body structures. You can also implement a contact
+listener.
+
+You can iterate over all contacts in the world:
+
+&nbsp;&nbsp;&nbsp;`for (b2Contact* c = myWorld->GetContactList(); c; c =
+c->GetNext())`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`// process c`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+You can also iterate over all the contacts on a body. These are stored in a
+graph using a contact edge structure.
+
+&nbsp;&nbsp;&nbsp;`for (b2ContactEdge* ce = myBody->GetContactList(); ce; ce =
+ce->next)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`  b2Contact* c = ce->contact;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`  // process c`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+You can also access contacts using the contact listener that is described
+below.
+
+	Caution
+	
+	Accessing contacts off b2World and b2Body may miss some transient
+contacts that occur in the middle of the time step. Use b2ContactListener to
+get the most accurate results.
+
+<a name="cl">
+## Contact Listener
+
+You can receive contact data by implementing b2ContactListener. The contact
+listener supports several events: begin, end, pre-solve, and post-solve.
+
+&nbsp;&nbsp;&nbsp;`class MyContactListener : public b2ContactListener`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`public:`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`void BeginContact(b2Contact*
+contact)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{ /* handle begin event */ }`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`void EndContact(b2Contact* contact)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{ /* handle end event */ }`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`void PreSolve(b2Contact* contact, const
+b2Manifold* oldManifold)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{ /* handle pre-solve event */ }`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`void PostSolve(b2Contact* contact, const
+b2ContactImpulse* impulse)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{ /* handle post-solve event */ }`<br/>
+&nbsp;&nbsp;&nbsp;`};`<br/>
+
+	Caution
+	
+	Do not keep a reference to the pointers sent to b2ContactListener.
+Instead make a deep copy of the contact point data into your own buffer. The
+example below shows one way of doing this.
+	
+	At run-time you can create an instance of the listener and register it
+with b2World::SetContactListener. Be sure your listener remains in scope while
+the world object exists.
+
+### Begin Contact Event
+
+This is called when two fixtures begin to overlap. This is called for sensors
+and non-sensors. This event can only occur inside the time step.
+
+### End Contact Event
+
+This is called when two fixtures cease to overlap. This is called for sensors
+and non-sensors. This may be called when a body is destroyed, so this event
+can occur outside the time step.
+
+### Pre-Solve Event
+
+This is called after collision detection, but before collision resolution.
+This gives you a chance to disable the contact based on the current
+configuration. For example, you can implement a one-sided platform using this
+callback and calling b2Contact::SetEnabled(false). The contact will be
+re-enabled each time through collision processing, so you will need to disable
+the contact every time-step. The pre-solve event may be fired multiple times
+per time step per contact due to continuous collision detection.
+
+&nbsp;&nbsp;&nbsp;`void PreSolve(b2Contact* contact, const b2Manifold*
+oldManifold)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;`b2WorldManifold worldManifold;`<br/>
+&nbsp;&nbsp;&nbsp;`contact->GetWorldManifold(&worldManifold);`<br/>
+&nbsp;&nbsp;&nbsp;`if (worldManifold.normal.y < -0.5f)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`contact->SetEnabled(false);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+The pre-solve event is also a good place to determine the point state and the
+approach velocity of collisions.
+
+&nbsp;&nbsp;&nbsp;`void PreSolve(b2Contact* contact, const b2Manifold*
+oldManifold)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2WorldManifold worldManifold;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`contact->GetWorldManifold(&worldManifold);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2PointState state1[2], state2[2];`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2GetPointStates(state1, state2,
+oldManifold, contact->GetManifold());`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (state2[0] == b2_addState)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`const b2Body* bodyA =
+contact->GetFixtureA()->GetBody();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`const b2Body* bodyB =
+contact->GetFixtureB()->GetBody();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 point =
+worldManifold.points[0];`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 vA =
+bodyA->GetLinearVelocityFromWorldPoint(point);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 vB =
+bodyB->GetLinearVelocityFromWorldPoint(point);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`float32
+approachVelocity = b2Dot(vB – vA, worldManifold.normal);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (approachVelocity >
+1.0f)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`MyPlayCollisionSound();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+### Post-Solve Event
+
+The post solve event is where you can gather collision impulse results. If you
+don’t care about the impulses, you should probably just implement the
+pre-solve event.
+
+It is tempting to implement game logic that alters the physics world inside a
+contact callback. For example, you may have a collision that applies damage
+and try to destroy the associated actor and its rigid body. However, LiquidFun
+does not allow you to alter the physics world inside a callback because you
+might destroy objects that LiquidFun is currently processing, leading to
+orphaned pointers.
+
+The recommended practice for processing contact points is to buffer all
+contact data that you care about and process it after the time step. You
+should always process the contact points immediately after the time step;
+otherwise some other client code might alter the physics world, invalidating
+the contact buffer. When you process the contact buffer you can alter the
+physics world, but you still need to be careful that you don't orphan pointers
+stored in the contact point buffer. The testbed has example contact point
+processing that is safe from orphaned pointers.
+
+This code from the CollisionProcessing test shows how to handle orphaned
+bodies when processing the contact buffer. Here is an excerpt. Be sure to read
+the comments in the listing. This code assumes that all contact points have
+been buffered in the b2ContactPoint array m_points.
+
+&nbsp;&nbsp;&nbsp;`// We are going to destroy some bodies according to
+contact`<br/>
+&nbsp;&nbsp;&nbsp;`// points. We must buffer the bodies that should be
+destroyed`<br/>
+&nbsp;&nbsp;&nbsp;`// because they may belong to multiple contact points.`<br/>
+&nbsp;&nbsp;&nbsp;`const int32 k_maxNuke = 6;`<br/>
+&nbsp;&nbsp;&nbsp;`b2Body* nuke[k_maxNuke];`<br/>
+&nbsp;&nbsp;&nbsp;`int32 nukeCount = 0;`<br/>
+&nbsp;&nbsp;&nbsp;`// Traverse the contact buffer. Destroy bodies that`<br/>
+&nbsp;&nbsp;&nbsp;`// are touching heavier bodies.`<br/>
+&nbsp;&nbsp;&nbsp;`for (int32 i = 0; i < m_pointCount; ++i)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`ContactPoint* point = m_points + i;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Body* bodyA =
+point->fixtureA->GetBody();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Body* bodyB =
+point->FixtureB->GetBody();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`float32 massA = bodyA->GetMass();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`float32 massB = bodyB->GetMass();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (massA > 0.0f && massB > 0.0f)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (massB > massA)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`nuke[nukeCount++] = bodyA;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`else`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`nuke[nukeCount++] = bodyB;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (nukeCount == k_maxNuke)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`break;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`// Sort the nuke array to group duplicates.`<br/>
+&nbsp;&nbsp;&nbsp;`std::sort(nuke, nuke + nukeCount);`<br/>
+&nbsp;&nbsp;&nbsp;`// Destroy the bodies, skipping duplicates.`<br/>
+&nbsp;&nbsp;&nbsp;`int32 i = 0;`<br/>
+&nbsp;&nbsp;&nbsp;`while (i < nukeCount)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Body* b = nuke[i++];`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`while (i < nukeCount && nuke[i] ==
+b)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`++i;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`m_world->DestroyBody(b);`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+## Contact Filtering
+
+Often in a game you don't want all objects to collide. For example, you may
+want to create a door that only certain characters can pass through. This is
+called contact filtering, because some interactions are filtered out.
+
+LiquidFun allows you to achieve custom contact filtering by implementing a
+b2ContactFilter class. This class requires you to implement a ShouldCollide
+function that receives two b2Shape pointers. Your function returns true if the
+shapes should collide.
+
+The default implementation of ShouldCollide uses the b2FilterData defined in
+Chapter 6, Fixtures.
+
+&nbsp;&nbsp;&nbsp;`bool b2ContactFilter::ShouldCollide(b2Fixture* fixtureA,
+b2Fixture* fixtureB)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`const b2Filter& filterA =
+fixtureA->GetFilterData();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`const b2Filter& filterB =
+fixtureB->GetFilterData();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (filterA.groupIndex ==
+filterB.groupIndex && filterA.groupIndex != 0)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`return
+filterA.groupIndex > 0;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && (filterA.categoryBits & filterB.maskBits) != 0;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`return collide;`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+At run-time you can create an instance of your contact filter and register it
+with b2World::SetContactFilter. Make sure your filter stays in scope while the
+world exists.
+
+&nbsp;&nbsp;&nbsp;`MyContactFilter filter;`<br/>
+&nbsp;&nbsp;&nbsp;`world->SetContactFilter(&filter);`<br/>
+&nbsp;&nbsp;&nbsp;`// filter remains in scope …`<br/>
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 322 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter10_World.md

@@ -0,0 +1,322 @@
+# World Class
+
+[About](#about)<br/>
+[Creating and Destroying a World](#cdw)<br/>
+[Using a World](#uw)<br/>
+[Simulation](#sim)<br/>
+[Exploring the World](#ew)<br/>
+[AABB Queries](#ab)<br/>
+[Ray Casts](#rc)<br/>
+[Forces and Impulses](#fi)<br/>
+[Coordinate Transformations](#ct)<br/>
+[Lists](#lists)<br/>
+<a name="about"></a><br/>
+## About
+
+The b2World class contains the bodies and joints. It manages all aspects of
+the simulation and allows for asynchronous queries (like AABB queries and
+ray-casts). Much of your interactions with LiquidFun will be with a b2World
+object.
+
+<a name="cdw"></a><br/>
+## Creating and Destroying a World
+
+Creating a world is fairly simple. You just need to provide a gravity vector
+and a Boolean indicating if bodies can sleep. Usually you will create and
+destroy a world using new and delete.
+
+&nbsp;&nbsp;&nbsp;`b2World* myWorld = new b2World(gravity, doSleep);`<br/>
+&nbsp;&nbsp;&nbsp;`... do stuff ...`<br/>
+&nbsp;&nbsp;&nbsp;`delete myWorld;`<br/>
+
+<a name="uw"></a><br/>
+## Using a World
+
+The world class contains factories for creating and destroying bodies and
+joints. These factories are discussed later in the sections on bodies and
+joints. There are some other interactions with b2World that I will cover now.
+
+<a name="sim"></a><br/>
+## Simulation
+
+The world class is used to drive the simulation. You specify a time step and a
+velocity and position iteration count. For example:
+
+&nbsp;&nbsp;&nbsp;`float32 timeStep = 1.0f / 60.f;`<br/>
+&nbsp;&nbsp;&nbsp;`int32 velocityIterations = 10;`<br/>
+&nbsp;&nbsp;&nbsp;`int32 positionIterations = 8;`<br/>
+&nbsp;&nbsp;&nbsp;`myWorld->Step(timeStep, velocityIterations,
+positionIterations);`<br/>
+
+After the time step you can examine your bodies and joints for information.
+Most likely you will grab the position off the bodies so that you can update
+your actors and render them. You can perform the time step anywhere in your
+game loop, but you should be aware of the order of things. For example, you
+must create bodies before the time step if you want to get collision results
+for the new bodies in that frame.
+
+As I discussed above in the HelloWorld tutorial, you should use a fixed time
+step. By using a larger time step you can improve performance in low frame
+rate scenarios. But generally you should use a time step no larger than 1/30
+seconds. A time step of 1/60 seconds will usually deliver a high quality
+simulation.
+
+The iteration count controls how many times the constraint solver sweeps over
+all the contacts and joints in the world. More iteration always yields a
+better simulation. But don't trade a small time step for a large iteration
+count. 60Hz and 10 iterations is far better than 30Hz and 20 iterations.
+
+After stepping, you should clear any forces you have applied to your bodies.
+This is done with the command b2World::ClearForces. This lets you take
+multiple sub-steps with the same force field.
+
+&nbsp;&nbsp;&nbsp;`myWorld->ClearForces();`<br/>
+
+
+<a name="ew"></a><br/>
+## Exploring the World
+
+The world is a container for bodies, contacts, and joints. You can grab the
+body, contact, and joint lists off the world and iterate over them. For
+example, this code wakes up all the bodies in the world:
+
+&nbsp;&nbsp;&nbsp;`for (b2Body* b = myWorld->GetBodyList(); b; b =
+b->GetNext())`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`    b->SetAwake(true);`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+Unfortunately real programs can be more complicated. For example, the
+following code is broken:
+
+&nbsp;&nbsp;&nbsp;`for (b2Body* b = myWorld->GetBodyList(); b; b =
+b->GetNext())`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`GameActor* myActor =
+(GameActor*)b->GetUserData();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (myActor->IsDead())`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`myWorld->DestroyBody(b);
+// ERROR: now GetNext returns garbage.`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+Everything goes ok until a body is destroyed. Once a body is destroyed, its
+next pointer becomes invalid. So the call to b2Body::GetNext() will return
+garbage. The solution to this is to copy the next pointer before destroying
+the body.
+
+&nbsp;&nbsp;&nbsp;`b2Body* node = myWorld->GetBodyList();`<br/>
+&nbsp;&nbsp;&nbsp;`while (node)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Body* b = node;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`node = node->GetNext();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`GameActor* myActor =
+(GameActor*)b->GetUserData();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (myActor->IsDead())`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`myWorld->DestroyBody(b);`
+<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+This safely destroys the current body. However, you may want to call a game
+function that may destroy multiple bodies. In this case you need to be very
+careful. The solution is application specific, but for convenience I'll show
+one method of solving the problem.
+
+&nbsp;&nbsp;&nbsp;`b2Body* node = myWorld->GetBodyList();`<br/>
+&nbsp;&nbsp;&nbsp;`while (node)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Body* b = node;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`node = node->GetNext();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`GameActor* myActor =
+(GameActor*)b->GetUserData();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if (myActor->IsDead())`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`bool
+otherBodiesDestroyed = GameCrazyBodyDestroyer(b);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`if
+(otherBodiesDestroyed)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`node
+= myWorld->GetBodyList();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+Obviously to make this work, GameCrazyBodyDestroyer must be honest about what
+it has destroyed.
+
+<a name="ab"></a><br/>
+## AABB Queries
+
+Sometimes you want to determine all the shapes in a region. The b2World class
+has a fast log(N) method for this using the broad-phase data structure. You
+provide an AABB in world coordinates and an implementation of b2QueryCallback.
+The world calls your class with each fixture whose AABB overlaps the query
+AABB. Return true to continue the query, otherwise return false. For example,
+the following code finds all the fixtures that potentially intersect a
+specified AABB and wakes up all of the associated bodies.
+
+&nbsp;&nbsp;&nbsp;`class MyQueryCallback : public b2QueryCallback`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`public:`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`bool ReportFixture(b2Fixture*
+fixture)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Body* body =
+fixture->GetBody();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`body->SetAwake(true);`<br
+/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`// Return true to
+continue the query.`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`return true;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`};`<br/>
+&nbsp;&nbsp;&nbsp;`...`<br/>
+&nbsp;&nbsp;&nbsp;`MyQueryCallback callback;`<br/>
+&nbsp;&nbsp;&nbsp;`b2AABB aabb;`<br/>
+&nbsp;&nbsp;&nbsp;`aabb.lowerBound.Set(-1.0f, -1.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`aabb.upperBound.Set(1.0f, 1.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`myWorld->Query(&callback, aabb);`<br/>
+
+You cannot make any assumptions about the order of the callbacks.
+
+<a name="rc"></a><br/>
+## Ray Casts
+
+You can use ray casts to do line-of-sight checks, fire guns, etc. You perform
+a ray cast by implementing a callback class and providing the start and end
+points. The world class calls your class with each fixture hit by the ray.
+Your callback is provided with the fixture, the point of intersection, the
+unit normal vector, and the fractional distance along the ray. You cannot make
+any assumptions about the order of the callbacks.
+
+You control the continuation of the ray cast by returning a fraction.
+Returning a fraction of zero indicates the ray cast should be terminated. A
+fraction of one indicates the ray cast should continue as if no hit occurred.
+If you return the fraction from the argument list, the ray will be clipped to
+the current intersection point. So you can ray cast any shape, ray cast all
+shapes, or ray cast the closest shape by returning the appropriate fraction.
+
+You may also return of fraction of -1 to filter the fixture. Then the ray cast
+will proceed as if the fixture does not exist.
+
+Here is an example:
+
+&nbsp;&nbsp;&nbsp;`// This class captures the closest hit shape.`<br/>
+&nbsp;&nbsp;&nbsp;`class MyRayCastCallback : public b2RayCastCallback`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`public:`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`MyRayCastCallback()`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`m_fixture = NULL;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`float32 ReportFixture(b2Fixture* fixture,
+const b2Vec2& point, const b2Vec2& normal, float32 fraction)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`m_fixture =
+fixture;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`m_point = point;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`m_normal = normal;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`m_fraction =
+fraction;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`return fraction;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Fixture* m_fixture;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 m_point;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b2Vec2 m_normal;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`float32 m_fraction;`<br/>
+&nbsp;&nbsp;&nbsp;`};`<br/>
+&nbsp;&nbsp;&nbsp;`MyRayCastCallback callback;`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 point1(-1.0f, 0.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 point2(3.0f, 1.0f);`<br/>
+&nbsp;&nbsp;&nbsp;`myWorld->RayCast(&callback, point1, point2);`<br/>
+
+	Caution
+	
+	Due to round-off errors, ray casts can sneak through small cracks
+between polygons in your static environment. If this is not acceptable in your
+application, please enlarge your polygons slightly.
+
+&nbsp;&nbsp;&nbsp;`void SetLinearVelocity(const b2Vec2& v);`<br/>
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetLinearVelocity() const;`<br/>
+&nbsp;&nbsp;&nbsp;`void SetAngularVelocity(float32 omega);`<br/>
+&nbsp;&nbsp;&nbsp;`float32 GetAngularVelocity() const;`<br/>
+
+<a name="fi"></a><br/>
+## Forces and Impulses
+
+You can apply forces, torques, and impulses to a body. When you apply a force
+or an impulse, you provide a world point where the load is applied. This often
+results in a torque about the center of mass.
+
+void ApplyForce(const b2Vec2& force, const b2Vec2& point);
+void ApplyTorque(float32 torque);
+void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point);
+void ApplyAngularImpulse(float32 impulse);
+
+Applying a force, torque, or impulse wakes the body. Sometimes this is
+undesirable. For example, you may be applying a steady force and want to allow
+the body to sleep to improve performance. In this case you can use the
+following code.
+
+&nbsp;&nbsp;&nbsp;`if (myBody->IsAwake() == true)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`myBody->ApplyForce(myForce,
+myPoint);`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+You can apply forces and impulses to particles and particle groups, as well.
+Unlike with bodies, however, the load is not applied to an arbitrary world
+point. Instead, it acts upon the center of each particle.
+
+You can apply forces and impulses to individual particles or to particle groups.
+The following example spreads an impulse of (0.7, 0.3) kg m/s across the
+particles in myParticleGroup:
+
+&nbsp;&nbsp;&nbsp;`const b2Vec2 impulse(0.7f, 0.3f);`
+&nbsp;&nbsp;&nbsp;`myParticleGroup->ApplyLinearImpulse(impulse);`
+
+<a name="ct"></a><br/>
+## Coordinate Transformations
+
+The body class has some utility functions to help you transform points and
+vectors between local and world space. If you don't understand these concepts,
+please read "Essential Mathematics for Games and Interactive Applications" by
+Jim Van Verth and Lars Bishop. These functions are efficient (when inlined).
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetWorldPoint(const b2Vec2& localPoint);`<br/>
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetWorldVector(const b2Vec2& localVector);`<br/>
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetLocalPoint(const b2Vec2& worldPoint);`<br/>
+
+&nbsp;&nbsp;&nbsp;`b2Vec2 GetLocalVector(const b2Vec2& worldVector);`<br/>
+
+<a name="lists"></a><br/>
+## Lists
+
+You can iterate over a body's fixtures. This is mainly useful if you need to
+access the fixture's user data.
+
+&nbsp;&nbsp;&nbsp;`for (b2Fixture* f = body->GetFixtureList(); f; f =
+f->GetNext())`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`MyFixtureData* data =
+(MyFixtureData*)f->GetUserData();`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`… do something with data …`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+You can similarly iterate over the body's joint list.
+
+The body also provides a list of associated contacts. You can use this to get
+information about the current contacts. Be careful, because the contact list
+may not contain all the contacts that existed during the previous time step.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 729 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter11_Particles.md

@@ -0,0 +1,729 @@
+# Particle Module
+
+[About](#About)<br/>
+[Particles](#Particles)<br/>
+[Particle Systems](#ps)<br/>
+[Particle Groups](#pg)<br/>
+[Discrete Particles vs. Particle Groups](#dp)<br/>
+[Stepping the World](#stw)<br/>
+[Maximum Velocity](#mv)<br/>
+[Creating and Destroying Particles](#cdp)<br/>
+[Creating and Destroying Particle Groups](#cdpg)<br/>
+[Particle Behaviors](#pb)<br/>
+[Particle Properties](#pp)<br/>
+[Rendering with OpenGL](#gl)<br/>
+[Sample Applications](#sa)<br/>
+
+<a name="About">
+## About
+The Particle module offers the ability to create and manipulate liquid or soft
+(deformable) bodies. It allows you to create (and destroy) particles with
+various behaviors and properties, and provides various methods for
+manipulating
+them. The module permits you to define particles discretely or as groups. It
+is
+designed to allow you to manipulate large numbers of particles efficiently.
+
+<a name="Particles">
+## Particles
+A particle is round, and the minimal unit of matter in a particle system. By
+default, a particle behaves as a liquid. You can set behavioral flags,
+however, to assign different behaviors (explained in
+[Particle Behaviors](#pb)) to individual particles or groups of particles.
+You can also set other particle properties including position, velocity, and
+color.<br/>
+The `b2Particle.h` file contains the enumerated behavior values, as well as
+the
+variables specifying other particle properties. The corresponding enum is
+named `b2ParticleFlag.`
+
+<a name="ps">
+## Particle Systems
+
+The "world" that particles inhabit is called a particle system. A particle
+system describes a wide variety of physical coefficients that help dictate
+how particles interact with the world around them. A few examples of these
+conditions are default particle radius, elasticity, and viscosity. For more
+detail, see the API Reference description of the b2ParticleSystemDef struct.
+
+The following example creates a particle system:
+
+&nbsp;&nbsp;&nbsp;`const b2ParticleSystemDef particleSystemDef;`<br/>
+&nbsp;&nbsp;&nbsp;`m_particleSystems[0] =
+`m_world->CreateParticleSystem(&particleSystemDef);`<br/>
+
+You can also create more than one particle system: Thus, one "world's"
+particles may have a certain default radius, elasticity, etc., while the other
+"world" has different default values for these properties. The following sample
+shows the creation of multiple particle systems:
+
+&nbsp;&nbsp;&nbsp;`const b2ParticleSystemDef particleSystemDef;`<br/>
+&nbsp;&nbsp;&nbsp;`for (int i = 0; i < NUM_PARTICLE_SYSTEMS; ++i) {`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+`m_particleSystems[i] = m_world->CreateParticleSystem(&particleSystemDef);`
+<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+In many, if not most,
+cases, it will not be necessary to adjust the default values or create multiple
+particle systems. You may find it useful in some cases, however.
+
+For example, dividing particles into multiple systems can yield a performance
+gain by allowing you to simulate only the visible systems while putting all
+other systems in a "paused" state using `b2ParticleSystem::SetPaused()`.
+
+The "Multiple Systems" example in the Testbed provides an example of
+two particle systems influencing a rigid body while not interacting with each
+other.
+
+<a name="pg">
+## Particle Groups
+
+Instead of creating particles individually, you can create a group of
+particles to manipulate en masse. Some of the particle-group properties that
+you can set are the same as those for discrete particles: behavior, position,
+linear velocity, and color. There are also properties specific to groups:
+rotational angle, rotational velocity, and strength.<br/>
+The `b2ParticleGroup.h` file contains the declarations for all of these
+variables, as well as the enum for particle-group behavior:
+`b2ParticleGroupFlag`.
+
+<a name="dp">
+## Discrete Particles vs. Particle Groups
+
+With one main exception, there is no functional difference between working
+with individual particles and groups of particles. The exception is rigid
+particles: Because of the internal algorithm used to make particles rigid, you
+must define them as a group.
+
+Particle groups do offer several conveniences. First, they allow you to create
+and destroy large numbers of particles automatically. If you do not create a
+group, you must create all of the particles individually. Also, a group allows
+you to assign the same property, such as angle of rotation, to all of its
+particles at once.
+
+<a name="stw">
+## Stepping the World (Particle Iterations)
+
+The particle solver can iterate multiple times per step. Larger numbers of
+steps improve the stability and fidelity of the particle simulation. However,
+more steps also require more processor cycles.
+
+The cycles cost is almost linear: double the number of particle iterations
+will almost double the cycles cost of b2ParticleSystem::Solve.
+
+Use the `particleIterations` parameter in `b2World::Step` to set the number
+of iterations. The default value of `particleIterations` is 1.
+
+You should experiment with `particleIterations` in your game to find the best
+balance of stability versus cycles. Try calling `b2CalculateParticleIterations`
+or `b2World::CalculateReasonableParticleIterations` to estimate a reasonable
+value. Note that these functions are, necessarily, a simplification, and
+should be used only as a starting point.
+
+If your simulation seems overly bouncy or energetic, or if the particles in
+your simulation are passing through contacts, try increasing the number of
+particle iterations.
+
+Note that, as particle iterations increases, the affect of pressure on
+highly-compressed particles also increases. That is, particles get more
+incompressible as you increase particle iterations.
+
+<a name="mv">
+## Maximum Velocity
+
+The particle simulation enforces a maximum velocity on the particles, for
+stability and to prevent excessive interpenetration. The maximum velocity is,
+
+&nbsp;&nbsp;&nbsp;`particle diameter / (particle iterations *
+b2World::Step's dt)`<br/>
+
+<a name="cdp">
+## Creating and Destroying Particles
+
+To create individual particles, create a `b2ParticleDef`-struct object. Next,
+specify the behavior and properties of the particle. Finally, call the method
+to create the particle.<br/>
+The following example creates an individual particle.
+
+&nbsp;&nbsp;&nbsp;`b2ParticleDef pd;`<br>
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_elasticParticle;`<br/>
+&nbsp;&nbsp;&nbsp;`pd.color.Set(0, 0, 255, 255);`<br/>
+&nbsp;&nbsp;&nbsp;`pd.position.Set(i, 0);`<br/>
+&nbsp;&nbsp;&nbsp;`int tempIndex = m_particleSystem->CreateParticle(pd);`<br/>
+
+Particle lists are self-compacting. Therefore, the index returned by
+CreateParticle is only valid until a lower-indexed particle, or a group
+referencing a lower-indexed particle, is deleted.<br/>
+To destroy an individual particle, invoke the function
+
+&nbsp;&nbsp;&nbsp;`void DestroyParticle(int32 index);`
+
+The following example destroys the particle created above.
+
+&nbsp;&nbsp;&nbsp;`m_particleSystem->DestroyParticle(tempIndex);`<br/>
+
+### Particle lifetimes
+
+In addition to manual destruction of particles as described above, particles
+can also expire and be destroyed due to age.
+
+The following example tells the system to track particle ages for the purpose
+of destroying them.
+
+&nbsp;&nbsp;&nbsp;`m_particleSystem->SetParticleDestructionByAge(true);`
+
+A particle can die one of two "age-related" deaths. First, you can set a
+lifetime for a particle--a period of time after which it expires.  The following
+example does this:
+
+&nbsp;&nbsp;&nbsp;`m_particleSystem->SetParticleLifetime(`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`index, Random() *`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+`(k_particleLifetimeMax - k_particleLifetimeMin) +`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`k_particleLifetimeMin);`<br/>
+
+where `index` specifies the number of the particle whose lifetime is being
+assigned, and the `Random()` function generates a random value for that
+lifetime.
+
+You do not need to set a specific lifetime for a particle for it to have an
+age-related death. If you set a maximum number of particles that can exist in a
+particle system, and you have have told the system to track particle ages, the
+system clamps particle count by culling "excess" particles. Particle culling
+takes place in age order, with the oldest ones destroyed first.
+
+The following example sets a maximum particle count for a particle system.
+
+&nbsp;&nbsp;&nbsp;`m_particleSystem->SetMaxParticleCount(k_maxParticleCount);`
+
+The Faucet example in the Testbed provides an example of both types of
+lifetime-driven particle destruction.
+
+### Stuck Particles
+
+Particles may get stuck and become obstructions that need to be destroyed or
+relocated. A particle is identified as possibly stuck if it remains in contact
+with two or more surfaces for a user-specified number (threshold) of particle
+iterations. Once "candidates" are identified, you can implement your own logic
+to decide whether they are actually stuck, and how to deal with them.
+
+The ability to implement your own logic gives you flexibility in deciding
+when you want to consider a particle stuck. For instance, a ball may
+be traveling down a chute, making contact with walls on multiple sides. This
+state satisfies the "possibly stuck" condition described in the previous
+paragraph. But you could implement logic judging the ball not stuck as long
+as it keeps traveling down the chute.
+
+On the other hand, you could also decide that not only an immobile particle,
+but even a mobile one trapped in a certain spatial range, is stuck. The system
+relies on you to judge the candidates.
+
+The following example shows one possible implementation for such a case.
+
+<pre>
+  // This code example of app logic deciding whether or not to eliminate stuck
+  // particles shows a user who set up a global array of sensor fixtures
+  // covering areas they know to be "problematic" for stuck particles in
+  // their geometry, and then at each step testing any stuck particles against
+  // those sensors, eliminating any stuck particles that lie inside a known
+  // problem region.
+  void DestroyStuckParticlesInSensors(
+      const b2Fixture * const *sensors, int32 num)
+  {
+  	const int32 stuck = gParticleSystem->GetStuckCandidateCount();
+  	if (stuck > 0)
+  	{
+  		const int32 *candidates = gParticleSystem->GetStuckCandidates();
+  		const b2Vec2 *positions = gParticleSystem->GetPositionBuffer();
+  		for (int32 i = 0; i < stuck; ++i)
+  		{
+  			const int32 particle = candidates[i];
+  			const b2Vec2 &position = positions[particle];
+  			for (int32 j = 0; j < num; ++j)
+  			{
+  				if(sensors[j]->TestPoint(position))
+  				{
+  					gParticleSystem->DestroyParticle(particle);
+  				}
+  			}
+  		}
+  	}
+  }
+  // particles in multiple contacts for 5 or more iterations are
+  // candidates
+  gParticleSystem->SetStuckThreshold(5);
+
+  // step the world (assuming the timestep, velocity iterations,
+  // and position iterations have been set globally).
+  gWorld->Step(gTimeStep, gVelocityIterations, gPositionIterations);
+
+  // Perform the above check for stuck particles against sensors
+  // in this global array.
+  DestroyStuckParticlesInSensors(gProblemAreaSensors, gNumSensors);
+</pre>
+
+<a name="cdpg">
+## Creating and Destroying Particle Groups
+
+A particle group begins life in a shaped container. You must therefore start a
+particle group definition by specifying a shape. Next, create a
+b2ParticleGroupDef-struct object. Then, specify the behavior and properties of
+the particles themselves. Finally, call the method to create a particle
+group.<br/>
+The following example creates five differently colored, box-shaped groups of
+particles.
+
+&nbsp;&nbsp;&nbsp;`b2ParticleGroupDef pd;`<br/>
+&nbsp;&nbsp;&nbsp;`b2PolygonShape shape;`<br/>
+&nbsp;&nbsp;&nbsp;`shape.SetAsBox(10, 5);`<br/>
+&nbsp;&nbsp;&nbsp;`pd.shape = &shape;`<br/>
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_elasticParticle;`<br/>
+&nbsp;&nbsp;&nbsp;`pd.angle = -0.5f;`<br/>
+&nbsp;&nbsp;&nbsp;`pd.angularVelocity = 2.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`for (int32 i = 0; i < 5; i++)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`pd.position.Set(10 + 20 * i, 40);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`pd.color.Set(i * 255 / 5, 255 - i * 255 /
+5, 128, 255);`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+`m_particleSystem->CreateParticleGroup(pd);`<br/>
+&nbsp;&nbsp;&nbsp;`}`<br/>
+
+To destroy a particles in a group, invoke the function
+
+&nbsp;&nbsp;&nbsp;`DestroyParticles(bool callDestructionListener);`<br/>
+
+Groups are automatically destroyed when they contain no particles if the
+`b2_particleGroupCanBeEmpty` is not set in the group's flags.
+
+The following example destroys all particle groups in the particle system.
+
+<pre>
+  b2ParticleGroup* group = m_particleSystem->GetParticleGroupList();
+  while (group)
+  {
+      m_particleSystem->SetGroupFlags(
+          m_particleSystem->GetGroupFlags() & ~b2_particleGroupCanBeEmpty);
+      group->DestroyParticles(false);
+      // The destruction of particle groups are deferred to the next call of
+      // Step() so it's safe to reference the group here.
+      group = group->GetNext();
+  }
+</pre>
+
+The next several sections provide more information on how to define particle
+behaviors and properties.
+
+<a name="pb">
+## Particle Behaviors
+
+Particle behaviors are defined either for entire groups of, or individual,
+particles.
+
+For a group of particles, use the `b2ParticleGroupFlag` enum, which provides
+two types of particle groups:
+
+###Solid
+
+A solid particle group prevents other bodies from lodging inside of it. Should
+anything penetrate it, the solid particle group pushes the offending body back
+out to its surface.
+
+A solid particle group also possesses an especially strong repulsive force. It
+is useful, for example, in a case where:
+
+* Something should be expected to bounce with unusual vigor
+** As when a racquetball strikes the wall of a court
+
+Use the `b2_SolidParticleGroup` flag of the `b2ParticleGroupFlag` enum to
+specify a solid particle group. For example:
+
+&nbsp;&nbsp;&nbsp;`pd.groupFlags = b2_solidParticleGroup;`
+
+###Rigid
+
+Rigid particle groups are ones whose shape does not change, even when they
+collide
+with other bodies. Working with rigid particle groups confers a few advantages
+over simply
+working with rigid bodies: With a rigid particle group, you can:<br/>
+
+* Delete part of the group (i.e., some of its particles).
+    * For example, firing a bullet that leaves a hole in a box-shaped group of
+particles.
+* Merge it with other groups.
+    * For example, creating a snowman from three round particle groups, and
+then merging them into a single particle group.
+
+Use the `b2_rigidParticleGroup` flag of the `b2ParticleGroupFlag` enum to
+specify a rigid particle group.  For example:
+
+&nbsp;&nbsp;&nbsp;`pd.groupFlags = b2_rigidParticleGroup;`
+
+For individual particles, use the b2ParticleFlag enum. The b2ParticleFlag enum
+provides the flags described in the following sections.  Note that different
+particle behaviors may exact different performance costs.
+
+### Elastic
+
+Elastic particles deform and may also bounce when they collide with rigid
+bodies.<br/>
+Set particle behavior as elastic using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_elasticParticle;`
+
+The green circle and the blue box in the "Elastic Particles" demo of the
+Testbed application comprise elastic particles.
+
+### Color-mixing
+
+Color-mixing particles take on some of the color of other particles with which
+they collide. If only one of the two colliding particles is a color-mixing
+one,
+the other particle retains its pre-collision color.<br/>
+<br/>
+The following example shows how color mixture is calculated. It shows the
+collision of two color-mixing particles: one red ("R") and one green ("G").
+
+1. First, the system calculates deltaColor, which is the value by which each
+   color will change.
+
+	deltaColor = colorMixingStrength * (B's color - A's color).<br/>
+	= 0.5 * ((0,255,0,255) - (255,0,0,255))<br/>
+	= 0.5 * (-255,255,0,0)<br/>
+	= (-127.5,127.5,0,0)
+
+2. Then, it applies the delta to each particle
+
+	R's color += deltaColor<br/>
+	G's color -= deltaColor
+
+3. As a result, both particles are now yellow:
+
+	A's color = (127.5,127.5,0,255)<br/>
+	B's color = (127.5,127.5,0,255)<br/>
+<br/>
+Note that when one of the operations in step 2 results in a negative number,
+the
+system uses the absolute value of that number. When it results in a value over
+255, it rolls over from zero.<br/>
+Set particle behavior as color-mixing using the statement<br/>
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_colorMixingParticle;`
+
+The "Surface Tension" demo of the Testbed application uses color-mixing
+particles.
+
+### Powder
+
+Powder particles produce a scattering effect such as you might see with sand
+or
+dust.<br/>
+Set particle behavior as powder using the statement<br/>
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_powderParticle;`
+
+The "Sparky" demo of the Testbed application uses powder particles.
+
+### Spring
+
+Spring particles produce the effect of being attached to one another, as by a
+spring. Particles are "connected" in pairs. Each particle is connected to the
+one that was closest to it at time of creation. Once paired, particles do not
+change "partners." The farther an external force pulls them from one another,
+the greater the power with which they collide when that external force is
+removed. No matter how far particles get from one another, the connection
+between them does not "snap."<br/>
+Set spring behavior using the statement<br/>
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_springParticle;`
+
+The red circle in the "Elastic Particles" demo of the Testbed application
+comprises spring particles.
+
+### Tensile
+
+Tensile particles are used to produce the effect of surface tension, or the
+taut
+curvature on the surface of a body of liquid. They might be used, for example,
+to create the surface tension you would see on a drop of water.<br/>
+Once the tension is broken, the particles bounce as if they were elastic, but
+also continue to attract each other. As a result, particles tend to form
+clusters as they bounce.<br/>
+Set tensile behavior using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_tensileParticle;`
+
+The "Surface Tension" demo of the Testbed application uses tensile particles.
+
+### Viscous
+
+Viscous particles exhibit clinginess or stickiness, like oil.<br/>
+Set viscous behavior using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_viscousParticle;`
+
+The "Liquid Timer" demo of the Testbed application uses viscous particles.
+
+### Static Pressure
+
+Particles are subject to compression when pressure acts upon them. For example,
+when particles pour into a container, the ones at the bottom of the container
+are "crushed" under the weight of those above them and packed more tightly
+together than the ones at the top of the pile.
+
+The static-pressure particle eliminates this differential; the same amount of
+pressure acts upon each particle in the group.
+
+The following example sets static-pressure behavior.
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_staticPressureParticle;`
+
+### Wall
+
+Wall particles are static. They are permanently stationary, even if something
+collides with them. <br/>
+Set wall behavior using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_wallParticle;`
+
+### Barrier
+
+Solid or rigid particle groups are not inherently tunneling-proof. Particles
+traveling at high enough velocities may penetrate them. Barrier particles,
+used in conjunction with other particle types, provide particle groups
+with protection against tunneling. This functionality is useful when, for
+example, you want to ensure that liquid particles will not leak out of a
+container formed of wall particles.
+
+Barrier particles only prevent penetration of the particle groups they inhabit.
+They cannot prevent particles from getting between groups of particles, even if
+the groups' positions make them look as if they are contiguous.
+
+You can use barrier particles with elastic, spring, or wall particles.
+
+The following example creates an impermeable group of wall particles:
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_wallParticle | b_barrierParticle;`
+&nbsp;&nbsp;&nbsp;`pd.groupFlags = b2_solidParticleGroup;`
+
+### Zombie
+
+Zombie particles are useful when you want efficiently to destroy multiple
+particles in a single step. All of the particles that you designate as zombies
+are destroyed at the same time, in a single iteration of the solver.
+Destroying
+particles in a batch, after designating them as zombies, yields better
+performance than destroying them one by one: Whereas destroying particles
+one-by-one takes (number of parti`cles) * (time per particle) to complete,
+destroying them all in a batch takes the same time as it would to destroy a
+single particle.<br/>
+In the following example, every other particle in a group is designated as a
+zombie, and will be destroyed in the next step of the solver. (For more
+information on the LiquidFun solver, see Chapter 1. Introduction.)
+
+&nbsp;&nbsp;&nbsp;`b2ParticleGroup*group=
+m_particleSystem->CreateParticleGroup(pd);`<br/>
+&nbsp;&nbsp;&nbsp;`for (int32 i=0;i<group->GetParticleCount();i+=2)`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`group->GetFlagsBuffer()[i] |=`
+`b2_zombieParticle;`<br/>
+&nbsp;&nbsp;&nbsp;`}`
+
+Note that you can assign multiple behaviors to a group or particle. Use
+the | ("bitwise OR") operator to chain behavior flags. For example, for a group:
+
+&nbsp;&nbsp;&nbsp;`pd.groupFlags = b2_solidParticleGroup |
+b2_rigidParticleGroup;`
+
+And for particles:
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_elasticParticle | b2_viscousParticle;`
+
+To define a group combining a specific group behavior with a specific particle
+behavior, use two statements. For example:
+
+&nbsp;&nbsp;&nbsp;`pd.flags = b2_elasticParticle;`<br/>
+&nbsp;&nbsp;&nbsp;`pd.groupFlags = b2_solidParticleGroup;`<br/>
+
+<a name="pp">
+## Particle Properties
+
+### Color
+
+Set particle or particle-group color using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.color.Set(r, g, b, a);`
+
+whose parameters set red, green, blue, and opacity, respectively. Each
+parameter takes a value of 0-255.
+
+### Size
+
+There are two points to keep in mind when using small particles. First, in the
+case of particle groups, particle size can affect performance. This is
+because particle size is inversely proportional to the number of particles
+generated to constitute a group. Having a large number of particles, in turn,
+can diminish performance.
+
+Set particle size using the statement
+
+&nbsp;&nbsp;&nbsp;`m_particleSystem->SetRadius(r);`
+
+where `r` is a float32 value greater than 0.0f. Default particle radius is
+1.0f.
+
+Small particles may also behave unpredictably (i.e., break conservation of
+momentum) in scenarios such as explosions. Slowing these particles down by
+reducing gravity scale can stabilize their behavior.
+
+Set gravity scale using the statement
+
+&nbsp;&nbsp;&nbsp;`m_particleSystem->SetGravityScale(g);`
+
+where `g` is a `float32` value greater than 0.0f. Default gravity scale is
+1.0f.
+
+It is worth noting that adjusting the number of particle iterations per solver
+step can also affect the effect of gravity on particles. Larger iteration sizes
+confer greater resistance to gravity. A common reason for increasing the number
+of particle-iterations is to prevent volume loss (i.e. compression) due to
+gravity.
+
+### Position
+
+Set particle or particle-group position using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.position.Set(x, y);`
+
+ where `x` and `y` are the world-coordinates of the translation of the
+particle
+group.
+
+### Velocity
+
+For discrete particles, set velocity using the statement
+
+&nbsp;&nbsp;&nbsp;`pd.velocity.Set(x,y);`
+
+where `x` is velocity along the x-axis, and `y` is velocity along the
+y-axis.<br/>
+For particle groups, set velocity using the statements
+
+&nbsp;&nbsp;&nbsp;`pd.linearVelocity.Set(x,y);`<br/>
+&nbsp;&nbsp;&nbsp;`pd.angularVelocity = aV;`<br/>
+
+where `x` is the group's velocity along the x-axis, `y` is velocity along the
+y-axis, and `aV` is the group's angular (i.e., rotational) velocity (expressed
+as radians per second).
+
+### Angle (Groups Only)
+
+This property applies only to rigid particle groups. It indicates the angle at
+which a group is tilted. Set angle with the statement
+
+&nbsp;&nbsp;&nbsp;`pd.angle =checkout a;`
+
+where `a` is the angle of tilt, expressed in radians. Left unspecified, the
+value defaults to 0.
+
+### Strength (Groups Only)
+
+Strength describes the cohesion of a group of particles. Set strength with the
+statement
+
+&nbsp;&nbsp;&nbsp;`pd.strength = s;`<br/>
+
+where `s` is a float32 value between 0.0 (least cohesive) and 1.0 (most
+cohesive). The default value is 1.0.
+
+<a name="gl">
+## Rendering with OpenGL
+
+The Particle module provides particularly efficient rendering via OpenGL.
+
+Each type of particle property lives in a contiguous memory buffer. For
+example,
+all particles' position data live next door to one another, all color data
+live
+next door to one another, and so forth. Table 1 provides a visual
+representation
+of this storage.
+
+**_Table 1. Memory Map of Particle Buffers_**
+
+<table>
+<tr>
+<td></td>
+<td>Particle 1</td>
+<td>Particle 2</td>
+<td>Particle 3</td>
+</tr>
+<tr>
+<td>Position</td>
+<td>x1,y1</td>
+<td>x2,y2</td>
+<td>x3,y3</td>
+</tr>
+<tr>
+<td>Address</td>
+<td>0x00001000</td>
+<td>0x00001008</td>
+<td>0x00001010</td>
+</tr>
+<tr>
+<td></td>
+<td></td>
+<td></td>
+<td></td>
+</tr>
+<tr>
+<td>Color</td>
+<td>r1,g1,b1,a1</td>
+<td>r2,g2,b2,a2</td>
+<td>r3,g3,b3,a3</td>
+</tr>
+<tr>
+<td>Address</td>
+<td>0x00002000</td>
+<td>0x00002004</td>
+<td>0x00002008</td>
+</tr>
+</table>
+
+OpenGL can use these buffers directly in rendering.<br/>
+In this example, OpenGL 1.1 would use glVertexPointer and glColorPointer to
+get
+the values from memory. OpenGL 2.0 would use glVertexAttribPointer.<br/>
+OpenGL can be used to render either individual particles or particle groups.
+
+<a name="sa">
+## Sample Applications
+
+Among the samples included in the LiquidFun distribution are two applications 
+that offer a quick look into the capabilities of the library.
+
+Testbed includes a large number of demos that provide examples of different 
+types of particle behavior. While some of the demos are "look only," others are 
+interactive, allowing you to use your mouse or touchscreen to affect the 
+behavior on screen. 
+
+Experimenting with each of the demos, and comparing their behavior against the 
+source code, can provide useful insights into how different particles behave 
+under various conditions. Testbed builds and runs on Android, MacOSX, Linux, 
+and Windows.
+
+EyeCandy is an Android-only application and is twofold in purpose: It provides
+a simple Android example of how to use LiquidFun; and, it seeks to inspire
+developers with its demonstration of the powerful liquid shaders it brings to
+mobile hardware.
+ 
+When running the program, you can slosh the fluid around by changing the
+orientation of the Android device. You can also toggle bewteen shaders by
+tapping the screen.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 178 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter12_Loose_Ends.md

@@ -0,0 +1,178 @@
+# Loose Ends
+
+[User Data](#ud)<br/>
+[Implicit Destruction](#id)<br/>
+[Pixels and Coordinate Systems](#pcs)<br/>
+
+<a name="ud"></a>
+## User Data
+
+The b2Fixture, b2Body, and b2Joint classes allow you to attach user data as a
+void pointer. This is handy when you are examining LiquidFun data structures
+and you want to determine how they relate to the objects in your game engine.
+
+For example, it is typical to attach an actor pointer to the rigid body on
+that actor. This sets up a circular reference. If you have the actor, you can
+get the body. If you have the body, you can get the actor.
+
+&nbsp;&nbsp;&nbsp;`GameActor* actor = GameCreateActor();`<br/>
+&nbsp;&nbsp;&nbsp;`b2BodyDef bodyDef;`<br/>
+&nbsp;&nbsp;&nbsp;`bodyDef.userData = actor;`<br/>
+&nbsp;&nbsp;&nbsp;`actor->body = box2Dworld->CreateBody(&bodyDef);`<br/>
+
+Here are some examples of cases where you would need the user data:
+
+* Applying damage to an actor using a collision result.
+
+* Playing a scripted event if the player is inside an axis-aligned box.
+
+* Accessing a game structure when LiquidFun notifies you that a joint is going
+to be destroyed.
+
+Keep in mind that user data is optional and you can put anything in it.
+However, you should be consistent. For example, if you want to store an actor
+pointer on one body, you should keep an actor pointer on all bodies. Don't
+store an actor pointer on one body, and a foo pointer on another body. Casting
+an actor pointer to a foo pointer may lead to a crash.
+
+User data pointers are NULL by default.
+
+For fixtures you might consider defining a user data structure that lets you
+store game specific information, such as material type, effects hooks, sound
+hooks, etc.
+
+&nbsp;&nbsp;&nbsp;`struct FixtureUserData`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`  int materialIndex;`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`  . . .`<br/>
+&nbsp;&nbsp;&nbsp;`};`<br/>
+&nbsp;&nbsp;&nbsp;`FixtureUserData myData = new FixtureUserData;`<br/>
+&nbsp;&nbsp;&nbsp;`myData->materialIndex = 2;`<br/>
+&nbsp;&nbsp;&nbsp;`b2FixtureDef fixtureDef;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.shape = &someShape;`<br/>
+&nbsp;&nbsp;&nbsp;`fixtureDef.userData = myData;`<br/>
+&nbsp;&nbsp;&nbsp;`b2Fixture* fixture = body->CreateFixture(&fixtureDef);`<br/>
+&nbsp;&nbsp;&nbsp;`. . .`<br/>
+&nbsp;&nbsp;&nbsp;`delete fixture->GetUserData();`<br/>
+&nbsp;&nbsp;&nbsp;`fixture->SetUserData(NULL);`<br/>
+&nbsp;&nbsp;&nbsp;`body->DestroyFixture(fixture);`<br/>
+
+<a name="id"></a>
+## Implicit Destruction
+
+LiquidFun doesn't use reference counting. So if you destroy a body it is
+really gone. Accessing a pointer to a destroyed body has undefined behavior.
+In other words, your program will likely crash and burn. To help fix these
+problems, the debug build memory manager fills destroyed entities with
+FDFDFDFD. This can help find problems more easily in some cases.
+
+If you destroy a LiquidFun entity, it is up to you to make sure you remove all
+references to the destroyed object. This is easy if you only have a single
+reference to the entity. If you have multiple references, you might consider
+implementing a handle class to wrap the raw pointer.
+
+Often when using LiquidFun you will create and destroy many bodies, shapes,
+and joints. Managing these entities is somewhat automated by LiquidFun. If you
+destroy a body then all associated shapes and joints are automatically
+destroyed. This is called implicit destruction.
+
+When you destroy a body, all its attached shapes, joints, and contacts are
+destroyed. This is called implicit destruction. Any body connected to one of
+those joints and/or contacts is woken. This process is usually convenient.
+However, you must be aware of one crucial issue:
+
+	Caution
+	
+	When a body is destroyed, all fixtures and joints attached to the body
+are automatically destroyed. You must nullify any pointers you have to those
+shapes and joints. Otherwise, your program will die horribly if you try to
+access or destroy those shapes or joints later.
+
+
+
+To help you nullify your joint pointers, LiquidFun provides a listener class
+named b2DestructionListener that you can implement and provide to your world
+object. Then the world object will notify you when a joint is going to be
+implicitly destroyed
+
+ Note that there no notification when a joint or fixture is explicitly
+destroyed. In this case ownership is clear and you can perform the necessary
+cleanup on the spot. If you like, you can call your own implementation of
+b2DestructionListener to keep cleanup code centralized.
+
+Implicit destruction is a great convenience in many cases. It can also make
+your program fall apart. You may store pointers to shapes and joints somewhere
+in your code. These pointers become orphaned when an associated body is
+destroyed. The situation becomes worse when you consider that joints are often
+created by a part of the code unrelated to management of the associated body.
+For example, the testbed creates a b2MouseJoint for interactive manipulation
+of bodies on the screen.
+
+LiquidFun provides a callback mechanism to inform your application when
+implicit destruction occurs. This gives your application a chance to nullify
+the orphaned pointers. This callback mechanism is described later in this
+manual.
+
+You can implement a b2DestructionListener that allows b2World to inform you
+when a shape or joint is implicitly destroyed because an associated body was
+destroyed. This will help prevent your code from accessing orphaned pointers.
+
+&nbsp;&nbsp;&nbsp;`class MyDestructionListener : public
+b2DestructionListener`<br/>
+&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`void SayGoodbye(b2Joint* joint)`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`{`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`// remove all
+references to joint.`<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`}`<br/>
+&nbsp;&nbsp;&nbsp;`};`<br/>
+
+You can then register an instance of your destruction listener with your world
+object. You should do this during world initialization.
+
+&nbsp;&nbsp;&nbsp;`myWorld->SetListener(myDestructionListener);`
+
+<a name="pcs"></a>
+## Pixels and Coordinate Systems
+
+Recall that LiquidFun uses MKS (meters, kilograms, and seconds) units and
+radians for angles. You may have trouble working with meters because your game
+is expressed in terms of pixels. To deal with this in the testbed I have the
+whole *game* work in meters and just use an OpenGL viewport transformation to
+scale the world into screen space.
+
+&nbsp;&nbsp;&nbsp;`float lowerX = -25.0f, upperX = 25.0f, lowerY = -5.0f,
+upperY = 25.0f;`<br/>
+&nbsp;&nbsp;&nbsp;`gluOrtho2D(lowerX, upperX, lowerY, upperY);`<br/>
+
+If your game must work in pixel units then you should convert your length
+units from pixels to meters when passing values from LiquidFun. Likewise you
+should convert the values received from LiquidFun from meters to pixels. This
+will improve the stability of the physics simulation.
+
+You have to come up with a reasonable conversion factor. I suggest making this
+choice based on the size of your characters. Suppose you have determined to
+use 50 pixels per meter (because your character is 75 pixels tall). Then you
+can convert from pixels to meters using these formulas:
+
+&nbsp;&nbsp;&nbsp;`xMeters = 0.02f * xPixels;`<br/>
+&nbsp;&nbsp;&nbsp;`yMeters = 0.02f * yPixels;`<br/>
+
+In reverse:
+
+&nbsp;&nbsp;&nbsp;`xPixels = 50.0f * xMeters;`<br/>
+&nbsp;&nbsp;&nbsp;`yPixels = 50.0f * yMeters;`<br/>
+
+You should consider using MKS units in your game code and just convert to
+pixels when you render. This will simplify your game logic and reduce the
+chance for errors since the rendering conversion can be isolated to a small
+amount of code.
+
+If you use a conversion factor, you should try tweaking it globally to make
+sure nothing breaks. You can also try adjusting it to improve stability.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 28 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter13_Debug_Drawing.md

@@ -0,0 +1,28 @@
+# Debug Drawing
+
+You can implement the b2DebugDraw class to get detailed drawing of the physics
+world. Here are the available entities:
+
+* shape outlines
+
+* joint connectivity
+
+* broad-phase axis-aligned bounding boxes (AABBs)
+
+* center of mass
+
+<img align="center" src="image_24.png" alt="Debug drawing" height="306"
+width="431"><br/>
+This is the preferred method of drawing these physics entities, rather than
+accessing the data directly. The reason is that much of the necessary data is
+internal and subject to change.
+
+The testbed draws physics entities using the debug draw facility and the
+contact listener, so it serves as the primary example of how to implement
+debug drawing as well as how to draw contact points.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 33 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter14_Limitations.md

@@ -0,0 +1,33 @@
+## Limitations
+
+LiquidFun uses several approximations to simulate rigid body physics
+efficiently. This brings some limitations.
+
+Here are the current limitations:
+
+1. Stacking heavy bodies on top of much lighter bodies is not stable.
+Stability degrades as the mass ratio passes 10:1.
+
+2. Chains of bodies connected by joints may stretch if a lighter body is
+supporting a heavier body. For example, a wrecking ball connect to a chain of
+light weight bodies may not be stable. Stability degrades as the mass ratio
+passes 10:1.
+
+3. There is typically around 0.5cm of slop in shape versus shape collision.
+
+4. Continuous collision does not handle joints. So you may see joint
+stretching on fast moving objects.
+
+5. LiquidFun uses the symplectic Euler integration scheme. It does not
+reproduce parabolic motion of projectiles and has only first-order accuracy.
+However it is fast and has good stability.
+
+6. LiquidFun uses an iterative solver to provide real-time performance. You
+will not get precisely rigid collisions or pixel perfect accuracy. Increasing
+the iterations will improve accuracy.
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 13 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Chapter15_References.md

@@ -0,0 +1,13 @@
+# References
+
+Erin Catto's GDC Tutorials:<br/>
+[http://code.google.com/p/box2d/downloads/list](http://code.google.com/p/box2d/downloads/list)<br/>
+_Collision Detection in Interactive 3D Environments,_ Gino van den Bergen,
+2004<br/>
+_Real-Time Collision Detection,_ Christer Ericson, 2005
+
+
+*This content is licensed under
+[Creative Commons Attribution 4.0](http://creativecommons.org/licenses/by/4.0/legalcode).
+For details and restrictions, please see the
+[Content License](md__content_license.html).*

+ 11 - 0
engine/source/Box2D/Documentation/Programmers-Guide/ContentLicense.md

@@ -0,0 +1,11 @@
+# Content License
+
+Portions of this documentation are modifications based on work
+created and shared by Erin Catto and used according to terms
+described in the
+[Creative Commons 4.0 Attribution License](http://creativecommons.org/licenses/by/4.0/legalcode)
+
+Copyright © 2007-2011 Erin Catto
+
+Copyright © 2013-2014 Fun Propulsion Labs at Google
+

+ 17 - 0
engine/source/Box2D/Documentation/Programmers-Guide/Logo.md

@@ -0,0 +1,17 @@
+# Logo
+
+Please feel free to make fair use the LiquidFun logo in connection with any
+implementations (in your splash screens or documentation, for example).
+There is no requirement to include the logo, but we appreciate your
+acknowledgement. We only ask that you avoid changing the proportions of the
+logo or otherwise modifying it, and that you avoid using the logo in a way
+that suggests your implementation is developed by, sponsored by, or affiliated
+with Fun Propulsion Labs or Google. (For example, you shouldn't use the
+LiquidFun logo as your app icon, and you shouldn't use it more prominently
+than your own logos or icons.)
+
+![LiquidFun Logo bitmap](liquidfun-logo-small.png)
+
+* [Logo in bitmap format](liquidfun-logo.png)
+* [Logo in vector format](liquidfun-logo.ai)
+

+ 2396 - 0
engine/source/Box2D/Documentation/Programmers-Guide/doxyfile

@@ -0,0 +1,2396 @@
+# Doxyfile 1.8.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+# 
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+# 
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "LiquidFun Programmer's Guide"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = "../../../Documentation/Programmers-Guide"
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-
+# Traditional, Croatian, Czech, Danish, Dutch, English, Esperanto, Farsi,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en,
+# Korean, Korean-en, Latvian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish,
+# Turkish, Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = NO
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+# 
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+# 
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+# 
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = NO
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 1
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C.
+# 
+# Note For files without extension you can use no_extension as a placeholder.
+# 
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = NO
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+# 
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = NO
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = NO
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= NO
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = NO
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+# 
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+# 
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = NO
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = NO
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = NO
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = "Chapter01_Introduction.md" \
+                         "Chapter02_Hello_Box2D.md" \
+                         "Chapter03_Common.md" \
+                         "Chapter04_Collision_Module.md" \
+                         "Chapter05_Dynamics_Module.md" \
+                         "Chapter06_Bodies.md" \
+                         "Chapter07_Fixtures.md" \
+                         "Chapter08_Joints.md" \
+                         "Chapter09_Contacts.md" \
+                         "Chapter10_World.md" \
+                         "Chapter11_Particles.md" \
+                         "Chapter12_Loose_Ends.md" \
+                         "Chapter13_Debug_Drawing.md" \
+                         "Chapter14_Limitations.md" \
+                         "Chapter15_References.md" \
+                         "ContentLicense.md" \
+                         "Logo.md"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.idl \
+                         *.ddl \
+                         *.odl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.cs \
+                         *.d \
+                         *.php \
+                         *.php4 \
+                         *.php5 \
+                         *.phtml \
+                         *.inc \
+                         *.m \
+                         *.markdown \
+                         *.md \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.for \
+                         *.tcl \
+                         *.vhd \
+                         *.vhdl \
+                         *.ucf \
+                         *.qsf \
+                         *.as \
+                         *.js
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# 
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+# 
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+# 
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+# 
+# <filter> <input-file>
+# 
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+# 
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = Chapter01_Introduction.md
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+# 
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+# 
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+# 
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+# 
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = NO
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = NO
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+# 
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = ../footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = "image_0.png" \
+                         "image_1.png" \
+                         "image_10.png" \
+                         "image_11.png" \
+                         "image_12.png" \
+                         "image_13.png" \
+                         "image_14.png" \
+                         "image_15.png" \
+                         "image_16.png" \
+                         "image_17.png" \
+                         "image_18.gif" \
+                         "image_19.gif" \
+                         "image_2.gif" \
+                         "image_20.gif" \
+                         "image_21.gif" \
+                         "image_22.gif" \
+                         "image_23.png" \
+                         "image_24.png" \
+                         "image_3.gif" \
+                         "image_4.png" \
+                         "image_5.png" \
+                         "image_6.png" \
+                         "image_7.png" \
+                         "image_8.png" \
+                         "image_9.png" \
+                         "liquidfun-logo.png" \
+                         "liquidfun-logo.ai" \
+                         "liquidfun-logo-small.png" \
+                         "liquidfun-logo-horizontal-small.png" \
+                         "liquidfun-logo-square-small.png"
+
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+# 
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = YES
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+# 
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+# 
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = NO
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavours of web server based searching depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools. See
+# the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+# 
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+# 
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+# 
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+# 
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+# 
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+# 
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+# 
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+# 
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+# 
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
+# validating XML parser to check the syntax of the XML files.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+# 
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = NO
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all refrences to function-like macros that are alone on a line, have an
+# all uppercase name, and do not end with a semicolon. Such function macros are
+# typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have an unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = NO
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = NO
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+# 
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+# 
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# 
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+# 
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES

Some files were not shown because too many files changed in this diff