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
 ## 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.
 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
 ### 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
 ### Building the Source
 
 
@@ -28,7 +28,7 @@ After downloading a copy of the source code, the following project files for eac
 * **Android:** Android Studio
 * **Android:** Android Studio
 * **Web:** Emscripten/Cmake
 * **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
 ### Batteries Included
 
 
@@ -40,7 +40,7 @@ The Sandbox is also an excellent framework for rapidly prototyping your own game
 
 
 ### Documentation
 ### 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
 ### 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)
 * [Torque 2D Professional Forum](http://www.garagegames.com/community/forums/85)
 * [GarageGames Community Blogs](http://www.garagegames.com/community/blogs)
 * [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
 # License
 Copyright (c) 2012 GarageGames, LLC
 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\gui\SceneWindow.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\CompositeSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\CompositeSprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\ParticlePlayer.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\SceneObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectSet.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectSet.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Scroller.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\ShapeVector.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\SkeletonObject.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
     <ClCompile Include="..\..\source\2d\sceneobject\Sprite.cc" />
@@ -316,10 +318,13 @@
     <ClCompile Include="..\..\source\Box2D\Collision\Shapes\b2PolygonShape.cpp" />
     <ClCompile Include="..\..\source\Box2D\Collision\Shapes\b2PolygonShape.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2BlockAllocator.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2BlockAllocator.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Draw.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\b2Math.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Settings.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2Settings.cpp" />
     <ClCompile Include="..\..\source\Box2D\Common\b2StackAllocator.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\b2Timer.cpp" />
+    <ClCompile Include="..\..\source\Box2D\Common\b2TrackedBlock.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Body.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Body.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2ContactManager.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2ContactManager.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\b2Fixture.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\b2RopeJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.cpp" />
     <ClCompile Include="..\..\source\Box2D\Dynamics\Joints\b2WheelJoint.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\Box2D\Rope\b2Rope.cpp" />
     <ClCompile Include="..\..\source\collection\bitTables.cc" />
     <ClCompile Include="..\..\source\collection\bitTables.cc" />
     <ClCompile Include="..\..\source\collection\hashTable.cc" />
     <ClCompile Include="..\..\source\collection\hashTable.cc" />
@@ -694,6 +704,8 @@
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\CompositeSprite_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ParticlePlayer_ScriptBinding.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\SceneObject.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectList.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectList.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectMoveToEvent.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\SceneObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\Scroller_ScriptBinding.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.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ShapeVector_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\ShapeVector_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject.h" />
     <ClInclude Include="..\..\source\2d\sceneobject\SkeletonObject.h" />
@@ -768,11 +782,17 @@
     <ClInclude Include="..\..\source\Box2D\Collision\Shapes\b2Shape.h" />
     <ClInclude Include="..\..\source\Box2D\Collision\Shapes\b2Shape.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2BlockAllocator.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2BlockAllocator.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Draw.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\b2GrowableStack.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2IntrusiveList.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Math.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Math.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Settings.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\b2StackAllocator.h" />
+    <ClInclude Include="..\..\source\Box2D\Common\b2Stat.h" />
     <ClInclude Include="..\..\source\Box2D\Common\b2Timer.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\b2Body.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2ContactManager.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2ContactManager.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\b2Fixture.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\b2RopeJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WeldJoint.h" />
     <ClInclude Include="..\..\source\Box2D\Dynamics\Joints\b2WheelJoint.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\Box2D\Rope\b2Rope.h" />
     <ClInclude Include="..\..\source\collection\bitMatrix.h" />
     <ClInclude Include="..\..\source\collection\bitMatrix.h" />
     <ClInclude Include="..\..\source\collection\bitSet.h" />
     <ClInclude Include="..\..\source\collection\bitSet.h" />
@@ -1286,7 +1312,10 @@
   <ItemGroup>
   <ItemGroup>
     <Image Include="Torque 2D.ico" />
     <Image Include="Torque 2D.ico" />
   </ItemGroup>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\source\Box2D\Particle\b2ParticleAssembly.neon.s" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
   </ImportGroup>
-</Project>
+</Project>

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

@@ -199,6 +199,9 @@
     <Filter Include="bitmapFont">
     <Filter Include="bitmapFont">
       <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
       <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="Box2D\Particle">
+      <UniqueIdentifier>{b2903a96-6c49-4961-82a8-f1832989d4a4}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1383,6 +1386,35 @@
     </ClCompile>
     </ClCompile>
     <ClCompile Include="..\..\source\gui\guiTextCtrl.cc">
     <ClCompile Include="..\..\source\gui\guiTextCtrl.cc">
       <Filter>gui</Filter>
       <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>
     </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
@@ -3102,6 +3134,53 @@
     </ClInclude>
     </ClInclude>
     <ClInclude Include="..\..\source\gui\guiTextCtrl.h">
     <ClInclude Include="..\..\source\gui\guiTextCtrl.h">
       <Filter>gui</Filter>
       <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>
     </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
@@ -3124,4 +3203,9 @@
   <ItemGroup>
   <ItemGroup>
     <Image Include="Torque 2D.ico" />
     <Image Include="Torque 2D.ico" />
   </ItemGroup>
   </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
 // TEXTINCLUDE
 //
 //
 
 
-1 TEXTINCLUDE DISCARDABLE 
+1 TEXTINCLUDE DISCARDABLE
 BEGIN
 BEGIN
     "resource.h\0"
     "resource.h\0"
 END
 END
 
 
-2 TEXTINCLUDE DISCARDABLE 
+2 TEXTINCLUDE DISCARDABLE
 BEGIN
 BEGIN
     "#include ""afxres.h""\r\n"
     "#include ""afxres.h""\r\n"
     "\0"
     "\0"
 END
 END
 
 
-3 TEXTINCLUDE DISCARDABLE 
+3 TEXTINCLUDE DISCARDABLE
 BEGIN
 BEGIN
     "\r\n"
     "\r\n"
     "\0"
     "\0"
@@ -107,4 +107,3 @@ END
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 #endif    // not APSTUDIO_INVOKED
 #endif    // not APSTUDIO_INVOKED
-

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

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

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

@@ -199,6 +199,9 @@
     <Filter Include="bitmapFont">
     <Filter Include="bitmapFont">
       <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
       <UniqueIdentifier>{447ecd65-a7a2-4e18-9c55-b53356c6f7a9}</UniqueIdentifier>
     </Filter>
     </Filter>
+    <Filter Include="Box2D\Particle">
+      <UniqueIdentifier>{b2903a96-6c49-4961-82a8-f1832989d4a4}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1414,6 +1417,36 @@
     <ClCompile Include="..\..\source\platform\platformNet.cpp" />
     <ClCompile Include="..\..\source\platform\platformNet.cpp" />
     <ClCompile Include="..\..\source\platform\platformNetAsync.cpp" />
     <ClCompile Include="..\..\source\platform\platformNetAsync.cpp" />
     <ClCompile Include="..\..\source\platform\platformNet_ScriptBinding.cc" />
     <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>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\source\audio\audio.h">
     <ClInclude Include="..\..\source\audio\audio.h">
@@ -3156,6 +3189,54 @@
     <ClInclude Include="..\..\source\gui\containers\guiScrollCtrl_ScriptBinding.h">
     <ClInclude Include="..\..\source\gui\containers\guiScrollCtrl_ScriptBinding.h">
       <Filter>gui\containers</Filter>
       <Filter>gui\containers</Filter>
     </ClInclude>
     </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>
   <ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">
@@ -3174,4 +3255,9 @@
   <ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="Torque 2D.rc" />
     <ResourceCompile Include="Torque 2D.rc" />
   </ItemGroup>
   </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>
     <ProjectGuid>{15CBFEFF-7965-41F5-B4E2-21E8795C9159}</ProjectGuid>
     <RootNamespace>libogg</RootNamespace>
     <RootNamespace>libogg</RootNamespace>
     <Keyword>Win32Proj</Keyword>
     <Keyword>Win32Proj</Keyword>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -179,4 +179,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
   </ImportGroup>
-</Project>
+</Project>

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

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

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

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

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

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

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

@@ -46,7 +46,7 @@
   </ItemGroup>
   </ItemGroup>
   <PropertyGroup Label="Globals">
   <PropertyGroup Label="Globals">
     <ProjectGuid>{86CB2525-0CF3-40D3-BF42-A0A95035EE8C}</ProjectGuid>
     <ProjectGuid>{86CB2525-0CF3-40D3-BF42-A0A95035EE8C}</ProjectGuid>
-    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
   </PropertyGroup>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -182,4 +182,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
   </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;
     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[] =
 static EnumTable::Enums particleOrientationTypeLookup[] =
@@ -132,7 +182,11 @@ ParticleAssetEmitter::ParticleAssetEmitter() :
                             mEmitterName( StringTable->EmptyString ),
                             mEmitterName( StringTable->EmptyString ),
                             mOwner( NULL ),
                             mOwner( NULL ),
                             mEmitterType( POINT_EMITTER ),
                             mEmitterType( POINT_EMITTER ),
+                            mPhysicsParticleType(b2_waterParticle),
+                            mPhysicsParticles(false),
                             mEmitterOffset( 0.0f, 0.0f),
                             mEmitterOffset( 0.0f, 0.0f),
+                            mTargetParticle(false),
+                            mTargetPosition(0.0f, 0.0f),
                             mEmitterAngle( 0.0f ),
                             mEmitterAngle( 0.0f ),
                             mEmitterSize( 10.0f, 10.0f ),
                             mEmitterSize( 10.0f, 10.0f ),
                             mFixedAspect( true ),
                             mFixedAspect( true ),
@@ -224,6 +278,14 @@ void ParticleAssetEmitter::initPersistFields()
     addProtectedField("EmitterName", TypeString, Offset(mEmitterName, ParticleAssetEmitter), &setEmitterName, &defaultProtectedGetFn, &defaultProtectedWriteFn, "");
     addProtectedField("EmitterName", TypeString, Offset(mEmitterName, ParticleAssetEmitter), &setEmitterName, &defaultProtectedGetFn, &defaultProtectedWriteFn, "");
     addProtectedField("EmitterType", TypeEnum, Offset(mEmitterType, ParticleAssetEmitter), &setEmitterType, &defaultProtectedGetFn, &writeEmitterType, 1, &EmitterTypeTable);
     addProtectedField("EmitterType", TypeEnum, Offset(mEmitterType, ParticleAssetEmitter), &setEmitterType, &defaultProtectedGetFn, &writeEmitterType, 1, &EmitterTypeTable);
     addProtectedField("EmitterOffset", TypeVector2, Offset(mEmitterOffset, ParticleAssetEmitter), &setEmitterOffset, &defaultProtectedGetFn, &writeEmitterOffset, "");
     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("EmitterAngle", TypeF32, Offset(mEmitterAngle, ParticleAssetEmitter), &setEmitterAngle, &defaultProtectedGetFn, &writeEmitterAngle, "");
     addProtectedField("EmitterSize", TypeVector2, Offset(mEmitterSize, ParticleAssetEmitter), &setEmitterSize, &defaultProtectedGetFn, &writeEmitterSize, "");
     addProtectedField("EmitterSize", TypeVector2, Offset(mEmitterSize, ParticleAssetEmitter), &setEmitterSize, &defaultProtectedGetFn, &writeEmitterSize, "");
     addProtectedField("FixedAspect", TypeBool, Offset(mFixedAspect, ParticleAssetEmitter), &setFixedAspect, &defaultProtectedGetFn, &writeFixedAspect, "");
     addProtectedField("FixedAspect", TypeBool, Offset(mFixedAspect, ParticleAssetEmitter), &setFixedAspect, &defaultProtectedGetFn, &writeFixedAspect, "");

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

@@ -71,6 +71,26 @@ public:
         TORUS_EMITTER,
         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:
 private:
     typedef SimObject Parent;
     typedef SimObject Parent;
 
 
@@ -91,7 +111,14 @@ private:
     F32                                     mRandomArc;
     F32                                     mRandomArc;
     F32                                     mFixedAngleOffset;
     F32                                     mFixedAngleOffset;
     Vector2                                 mPivotPoint;
     Vector2                                 mPivotPoint;
-
+    //Physics Particles
+    PhysicsParticleType                     mPhysicsParticleType;
+    bool                                    mPhysicsParticles;
+    //Physics Particles end---
+    //Particle Target
+    bool                                    mTargetParticle;
+    Vector2                                 mTargetPosition;
+    //Particle Target end---
     bool                                    mLinkEmissionRotation;
     bool                                    mLinkEmissionRotation;
     bool                                    mIntenseParticles;
     bool                                    mIntenseParticles;
     bool                                    mSingleParticle;
     bool                                    mSingleParticle;
@@ -157,6 +184,18 @@ public:
     inline const Vector2& getFixedForceDirection( void ) const { return mFixedForceDirection; }
     inline const Vector2& getFixedForceDirection( void ) const { return mFixedForceDirection; }
     inline void setOrientationType( const ParticleOrientationType particleOrientationType ) { mOrientationType = particleOrientationType; refreshAsset(); }
     inline void setOrientationType( const ParticleOrientationType particleOrientationType ) { mOrientationType = particleOrientationType; refreshAsset(); }
     inline ParticleOrientationType getOrientationType( void ) const { return mOrientationType; }
     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 void setKeepAligned( const bool keepAligned ) { mKeepAligned = keepAligned; refreshAsset(); }
     inline bool getKeepAligned( void ) const { return mKeepAligned; }
     inline bool getKeepAligned( void ) const { return mKeepAligned; }
     inline void setAlignedAngleOffset( const F32 angleOffset ) { mAlignedAngleOffset = angleOffset; refreshAsset(); }
     inline void setAlignedAngleOffset( const F32 angleOffset ) { mAlignedAngleOffset = angleOffset; refreshAsset(); }
@@ -250,6 +289,10 @@ public:
 
 
     static EmitterType getEmitterTypeEnum(const char* label);
     static EmitterType getEmitterTypeEnum(const char* label);
     static const char* getEmitterTypeDescription( const EmitterType emitterType );
     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 ParticleOrientationType getOrientationTypeEnum(const char* label);
     static const char* getOrientationTypeDescription( const ParticleOrientationType orientationType );
     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     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     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     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     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     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; }
     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     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     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() ); }
     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     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     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; }
     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();
     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.
 /*! Sets the emitter size.

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

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

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

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

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

@@ -678,7 +678,7 @@ public:
     static const char* getPickModeDescription( PickMode pickMode );
     static const char* getPickModeDescription( PickMode pickMode );
     static DebugOption getDebugOptionEnum(const char* label);
     static DebugOption getDebugOptionEnum(const char* label);
     static const char* getDebugOptionDescription( DebugOption debugOption );
     static const char* getDebugOptionDescription( DebugOption debugOption );
-
+    b2ParticleSystem*			mParticleSystem;
     /// Declare Console Object.
     /// Declare Console Object.
     DECLARE_CONOBJECT(Scene);
     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(),
                                                                 pParticleAssetEmitter->getEmissionForceVariationField(),
                                                                 particlePlayerAge) * getForceScale();
                                                                 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.
         // Calculate Emission Arc.
         // NOTE:-   We're actually interested in half the emission arc!
         // NOTE:-   We're actually interested in half the emission arc!
         emissionArc = ParticleAssetField::calculateFieldBV( pParticleAssetEmitter->getEmissionArcBaseField(),
         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.
    // Finish if nothing is dirty.
     if ( !mSpatialDirty )
     if ( !mSpatialDirty )
         return;
         return;
-
+    
     // Reset spatial changed.
     // Reset spatial changed.
     mSpatialDirty = false;
     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