From 80632b5906c874abb5041213623a8f6657b86e61 Mon Sep 17 00:00:00 2001 From: dsc Date: Wed, 4 May 2011 22:36:52 -0700 Subject: [PATCH] Checkpoint on box2d as a lib --- libs/box2d/.gitignore | 2 + libs/box2d/box2d-ios.xcodeproj/project.pbxproj | 541 ++++++++++ libs/box2d/box2d-iphone.xcodeproj/project.pbxproj | 560 ++++++++++ libs/box2d/box2d-osx.xcodeproj/project.pbxproj | 541 ++++++++++ libs/box2d/iPhone/Box2D_Prefix.pch | 8 + libs/box2d/iPhone/Classes/Box2DAppDelegate.h | 24 + libs/box2d/iPhone/Classes/Box2DAppDelegate.mm | 62 ++ libs/box2d/iPhone/Classes/Box2DView.h | 63 ++ libs/box2d/iPhone/Classes/Box2DView.mm | 299 ++++++ libs/box2d/iPhone/Classes/Delegates.h | 14 + libs/box2d/iPhone/Classes/GLES-Render.h | 58 ++ libs/box2d/iPhone/Classes/GLES-Render.mm | 149 +++ .../iPhone/Classes/TestEntriesViewController.h | 19 + .../iPhone/Classes/TestEntriesViewController.mm | 75 ++ libs/box2d/iPhone/Classes/iPhoneTest.h | 189 ++++ libs/box2d/iPhone/Classes/iPhoneTest.mm | 415 ++++++++ libs/box2d/iPhone/Classes/iPhoneTestEntries.mm | 111 ++ libs/box2d/iPhone/Icon.png | Bin 0 -> 1951 bytes libs/box2d/iPhone/Info.plist | 30 + libs/box2d/iPhone/MainWindow.xib | 232 +++++ libs/box2d/iPhone/main.m | 17 + libs/box2d/src/Box2D/Box2D.h | 62 ++ .../src/Box2D/Collision/Shapes/b2CircleShape.cpp | 89 ++ .../src/Box2D/Collision/Shapes/b2CircleShape.h | 87 ++ .../src/Box2D/Collision/Shapes/b2PolygonShape.cpp | 434 ++++++++ .../src/Box2D/Collision/Shapes/b2PolygonShape.h | 131 +++ libs/box2d/src/Box2D/Collision/Shapes/b2Shape.h | 95 ++ libs/box2d/src/Box2D/Collision/b2BroadPhase.cpp | 116 +++ libs/box2d/src/Box2D/Collision/b2BroadPhase.h | 229 +++++ libs/box2d/src/Box2D/Collision/b2CollideCircle.cpp | 154 +++ .../box2d/src/Box2D/Collision/b2CollidePolygon.cpp | 306 ++++++ libs/box2d/src/Box2D/Collision/b2Collision.cpp | 250 +++++ libs/box2d/src/Box2D/Collision/b2Collision.h | 240 +++++ libs/box2d/src/Box2D/Collision/b2Distance.cpp | 571 +++++++++++ libs/box2d/src/Box2D/Collision/b2Distance.h | 141 +++ libs/box2d/src/Box2D/Collision/b2DynamicTree.cpp | 365 +++++++ libs/box2d/src/Box2D/Collision/b2DynamicTree.h | 286 ++++++ libs/box2d/src/Box2D/Collision/b2TimeOfImpact.cpp | 483 +++++++++ libs/box2d/src/Box2D/Collision/b2TimeOfImpact.h | 59 ++ libs/box2d/src/Box2D/Common/b2BlockAllocator.cpp | 205 ++++ libs/box2d/src/Box2D/Common/b2BlockAllocator.h | 59 ++ libs/box2d/src/Box2D/Common/b2Math.cpp | 55 + libs/box2d/src/Box2D/Common/b2Math.h | 624 ++++++++++++ libs/box2d/src/Box2D/Common/b2Settings.cpp | 33 + libs/box2d/src/Box2D/Common/b2Settings.h | 151 +++ libs/box2d/src/Box2D/Common/b2StackAllocator.cpp | 83 ++ libs/box2d/src/Box2D/Common/b2StackAllocator.h | 60 ++ .../Box2D/Dynamics/Contacts/b2CircleContact.cpp | 52 + .../src/Box2D/Dynamics/Contacts/b2CircleContact.h | 38 + .../src/Box2D/Dynamics/Contacts/b2Contact.cpp | 226 ++++ libs/box2d/src/Box2D/Dynamics/Contacts/b2Contact.h | 242 +++++ .../Box2D/Dynamics/Contacts/b2ContactSolver.cpp | 623 +++++++++++ .../src/Box2D/Dynamics/Contacts/b2ContactSolver.h | 78 ++ .../Contacts/b2PolygonAndCircleContact.cpp | 52 + .../Dynamics/Contacts/b2PolygonAndCircleContact.h | 38 + .../Box2D/Dynamics/Contacts/b2PolygonContact.cpp | 52 + .../src/Box2D/Dynamics/Contacts/b2PolygonContact.h | 38 + .../src/Box2D/Dynamics/Contacts/b2TOISolver.cpp | 231 +++++ .../src/Box2D/Dynamics/Contacts/b2TOISolver.h | 51 + .../src/Box2D/Dynamics/Joints/b2DistanceJoint.cpp | 211 ++++ .../src/Box2D/Dynamics/Joints/b2DistanceJoint.h | 140 +++ .../src/Box2D/Dynamics/Joints/b2FrictionJoint.cpp | 229 +++++ .../src/Box2D/Dynamics/Joints/b2FrictionJoint.h | 99 ++ .../src/Box2D/Dynamics/Joints/b2GearJoint.cpp | 259 +++++ libs/box2d/src/Box2D/Dynamics/Joints/b2GearJoint.h | 111 ++ libs/box2d/src/Box2D/Dynamics/Joints/b2Joint.cpp | 186 ++++ libs/box2d/src/Box2D/Dynamics/Joints/b2Joint.h | 226 ++++ .../src/Box2D/Dynamics/Joints/b2LineJoint.cpp | 591 +++++++++++ libs/box2d/src/Box2D/Dynamics/Joints/b2LineJoint.h | 170 +++ .../src/Box2D/Dynamics/Joints/b2MouseJoint.cpp | 197 ++++ .../box2d/src/Box2D/Dynamics/Joints/b2MouseJoint.h | 114 ++ .../src/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp | 586 +++++++++++ .../src/Box2D/Dynamics/Joints/b2PrismaticJoint.h | 175 ++++ .../src/Box2D/Dynamics/Joints/b2PulleyJoint.cpp | 427 ++++++++ .../src/Box2D/Dynamics/Joints/b2PulleyJoint.h | 148 +++ .../src/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp | 478 +++++++++ .../src/Box2D/Dynamics/Joints/b2RevoluteJoint.h | 174 ++++ .../src/Box2D/Dynamics/Joints/b2WeldJoint.cpp | 219 ++++ libs/box2d/src/Box2D/Dynamics/Joints/b2WeldJoint.h | 82 ++ libs/box2d/src/Box2D/Dynamics/b2Body.cpp | 470 +++++++++ libs/box2d/src/Box2D/Dynamics/b2Body.h | 802 +++++++++++++++ libs/box2d/src/Box2D/Dynamics/b2ContactManager.cpp | 266 +++++ libs/box2d/src/Box2D/Dynamics/b2ContactManager.h | 52 + libs/box2d/src/Box2D/Dynamics/b2Fixture.cpp | 163 +++ libs/box2d/src/Box2D/Dynamics/b2Fixture.h | 326 ++++++ libs/box2d/src/Box2D/Dynamics/b2Island.cpp | 374 +++++++ libs/box2d/src/Box2D/Dynamics/b2Island.h | 105 ++ libs/box2d/src/Box2D/Dynamics/b2TimeStep.h | 35 + libs/box2d/src/Box2D/Dynamics/b2World.cpp | 1076 ++++++++++++++++++++ libs/box2d/src/Box2D/Dynamics/b2World.h | 285 ++++++ libs/box2d/src/Box2D/Dynamics/b2WorldCallbacks.cpp | 61 ++ libs/box2d/src/Box2D/Dynamics/b2WorldCallbacks.h | 217 ++++ libs/box2d/src/Tests/ApplyForce.h | 180 ++++ libs/box2d/src/Tests/BodyTypes.h | 159 +++ libs/box2d/src/Tests/Breakable.h | 155 +++ libs/box2d/src/Tests/Bridge.h | 125 +++ libs/box2d/src/Tests/BulletTest.h | 136 +++ libs/box2d/src/Tests/Cantilever.h | 203 ++++ libs/box2d/src/Tests/Car.h | 286 ++++++ libs/box2d/src/Tests/Chain.h | 74 ++ libs/box2d/src/Tests/CharacterCollision.h | 212 ++++ libs/box2d/src/Tests/CollisionFiltering.h | 176 ++++ libs/box2d/src/Tests/CollisionProcessing.h | 188 ++++ libs/box2d/src/Tests/CompoundShapes.h | 143 +++ libs/box2d/src/Tests/Confined.h | 167 +++ libs/box2d/src/Tests/ContinuousTest.h | 137 +++ libs/box2d/src/Tests/DistanceTest.h | 135 +++ libs/box2d/src/Tests/Dominos.h | 215 ++++ libs/box2d/src/Tests/DynamicTreeTest.h | 357 +++++++ libs/box2d/src/Tests/EdgeShapes.h | 249 +++++ libs/box2d/src/Tests/EdgeTest.h | 109 ++ libs/box2d/src/Tests/Gears.h | 141 +++ libs/box2d/src/Tests/LineJoint.h | 68 ++ libs/box2d/src/Tests/OneSidedPlatform.h | 120 +++ libs/box2d/src/Tests/Pinball.h | 169 +++ libs/box2d/src/Tests/PolyCollision.h | 122 +++ libs/box2d/src/Tests/PolyShapes.h | 292 ++++++ libs/box2d/src/Tests/Prismatic.h | 106 ++ libs/box2d/src/Tests/Pulleys.h | 106 ++ libs/box2d/src/Tests/Pyramid.h | 89 ++ libs/box2d/src/Tests/RayCast.h | 441 ++++++++ libs/box2d/src/Tests/Revolute.h | 166 +++ libs/box2d/src/Tests/Rope.h | 101 ++ libs/box2d/src/Tests/RopeJoint.h | 145 +++ libs/box2d/src/Tests/SensorTest.h | 181 ++++ libs/box2d/src/Tests/ShapeEditing.h | 93 ++ libs/box2d/src/Tests/SliderCrank.h | 156 +++ libs/box2d/src/Tests/SphereStack.h | 86 ++ libs/box2d/src/Tests/TheoJansen.h | 256 +++++ libs/box2d/src/Tests/Tiles.h | 146 +++ libs/box2d/src/Tests/TimeOfImpact.h | 131 +++ libs/box2d/src/Tests/VaryingFriction.h | 124 +++ libs/box2d/src/Tests/VaryingRestitution.h | 69 ++ libs/box2d/src/Tests/VerticalStack.h | 165 +++ libs/box2d/src/Tests/Web.h | 209 ++++ 135 files changed, 26640 insertions(+), 0 deletions(-) create mode 100644 libs/box2d/.gitignore create mode 100644 libs/box2d/box2d-ios.xcodeproj/project.pbxproj create mode 100644 libs/box2d/box2d-iphone.xcodeproj/project.pbxproj create mode 100644 libs/box2d/box2d-osx.xcodeproj/project.pbxproj create mode 100644 libs/box2d/iPhone/Box2D_Prefix.pch create mode 100644 libs/box2d/iPhone/Classes/Box2DAppDelegate.h create mode 100644 libs/box2d/iPhone/Classes/Box2DAppDelegate.mm create mode 100644 libs/box2d/iPhone/Classes/Box2DView.h create mode 100644 libs/box2d/iPhone/Classes/Box2DView.mm create mode 100644 libs/box2d/iPhone/Classes/Delegates.h create mode 100644 libs/box2d/iPhone/Classes/GLES-Render.h create mode 100644 libs/box2d/iPhone/Classes/GLES-Render.mm create mode 100644 libs/box2d/iPhone/Classes/TestEntriesViewController.h create mode 100644 libs/box2d/iPhone/Classes/TestEntriesViewController.mm create mode 100644 libs/box2d/iPhone/Classes/iPhoneTest.h create mode 100644 libs/box2d/iPhone/Classes/iPhoneTest.mm create mode 100644 libs/box2d/iPhone/Classes/iPhoneTestEntries.mm create mode 100644 libs/box2d/iPhone/Icon.png create mode 100644 libs/box2d/iPhone/Info.plist create mode 100644 libs/box2d/iPhone/MainWindow.xib create mode 100644 libs/box2d/iPhone/main.m create mode 100644 libs/box2d/src/Box2D/Box2D.h create mode 100644 libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.cpp create mode 100644 libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.h create mode 100644 libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.cpp create mode 100644 libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.h create mode 100644 libs/box2d/src/Box2D/Collision/Shapes/b2Shape.h create mode 100644 libs/box2d/src/Box2D/Collision/b2BroadPhase.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2BroadPhase.h create mode 100644 libs/box2d/src/Box2D/Collision/b2CollideCircle.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2CollidePolygon.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2Collision.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2Collision.h create mode 100644 libs/box2d/src/Box2D/Collision/b2Distance.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2Distance.h create mode 100644 libs/box2d/src/Box2D/Collision/b2DynamicTree.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2DynamicTree.h create mode 100644 libs/box2d/src/Box2D/Collision/b2TimeOfImpact.cpp create mode 100644 libs/box2d/src/Box2D/Collision/b2TimeOfImpact.h create mode 100644 libs/box2d/src/Box2D/Common/b2BlockAllocator.cpp create mode 100644 libs/box2d/src/Box2D/Common/b2BlockAllocator.h create mode 100644 libs/box2d/src/Box2D/Common/b2Math.cpp create mode 100644 libs/box2d/src/Box2D/Common/b2Math.h create mode 100644 libs/box2d/src/Box2D/Common/b2Settings.cpp create mode 100644 libs/box2d/src/Box2D/Common/b2Settings.h create mode 100644 libs/box2d/src/Box2D/Common/b2StackAllocator.cpp create mode 100644 libs/box2d/src/Box2D/Common/b2StackAllocator.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2CircleContact.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2CircleContact.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2Contact.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2Contact.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2ContactSolver.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2ContactSolver.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2PolygonContact.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2PolygonContact.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2TOISolver.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Contacts/b2TOISolver.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2DistanceJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2DistanceJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2FrictionJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2FrictionJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2GearJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2GearJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2Joint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2Joint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2LineJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2LineJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2MouseJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2MouseJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2PrismaticJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2PrismaticJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2PulleyJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2PulleyJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2RevoluteJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2RevoluteJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2WeldJoint.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/Joints/b2WeldJoint.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2Body.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/b2Body.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2ContactManager.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/b2ContactManager.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2Fixture.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/b2Fixture.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2Island.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/b2Island.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2TimeStep.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2World.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/b2World.h create mode 100644 libs/box2d/src/Box2D/Dynamics/b2WorldCallbacks.cpp create mode 100644 libs/box2d/src/Box2D/Dynamics/b2WorldCallbacks.h create mode 100644 libs/box2d/src/Tests/ApplyForce.h create mode 100644 libs/box2d/src/Tests/BodyTypes.h create mode 100644 libs/box2d/src/Tests/Breakable.h create mode 100644 libs/box2d/src/Tests/Bridge.h create mode 100644 libs/box2d/src/Tests/BulletTest.h create mode 100644 libs/box2d/src/Tests/Cantilever.h create mode 100644 libs/box2d/src/Tests/Car.h create mode 100644 libs/box2d/src/Tests/Chain.h create mode 100644 libs/box2d/src/Tests/CharacterCollision.h create mode 100644 libs/box2d/src/Tests/CollisionFiltering.h create mode 100644 libs/box2d/src/Tests/CollisionProcessing.h create mode 100644 libs/box2d/src/Tests/CompoundShapes.h create mode 100644 libs/box2d/src/Tests/Confined.h create mode 100644 libs/box2d/src/Tests/ContinuousTest.h create mode 100644 libs/box2d/src/Tests/DistanceTest.h create mode 100644 libs/box2d/src/Tests/Dominos.h create mode 100644 libs/box2d/src/Tests/DynamicTreeTest.h create mode 100644 libs/box2d/src/Tests/EdgeShapes.h create mode 100644 libs/box2d/src/Tests/EdgeTest.h create mode 100644 libs/box2d/src/Tests/Gears.h create mode 100644 libs/box2d/src/Tests/LineJoint.h create mode 100644 libs/box2d/src/Tests/OneSidedPlatform.h create mode 100644 libs/box2d/src/Tests/Pinball.h create mode 100644 libs/box2d/src/Tests/PolyCollision.h create mode 100644 libs/box2d/src/Tests/PolyShapes.h create mode 100644 libs/box2d/src/Tests/Prismatic.h create mode 100644 libs/box2d/src/Tests/Pulleys.h create mode 100644 libs/box2d/src/Tests/Pyramid.h create mode 100644 libs/box2d/src/Tests/RayCast.h create mode 100644 libs/box2d/src/Tests/Revolute.h create mode 100644 libs/box2d/src/Tests/Rope.h create mode 100644 libs/box2d/src/Tests/RopeJoint.h create mode 100644 libs/box2d/src/Tests/SensorTest.h create mode 100644 libs/box2d/src/Tests/ShapeEditing.h create mode 100644 libs/box2d/src/Tests/SliderCrank.h create mode 100644 libs/box2d/src/Tests/SphereStack.h create mode 100644 libs/box2d/src/Tests/TheoJansen.h create mode 100644 libs/box2d/src/Tests/Tiles.h create mode 100644 libs/box2d/src/Tests/TimeOfImpact.h create mode 100644 libs/box2d/src/Tests/VaryingFriction.h create mode 100644 libs/box2d/src/Tests/VaryingRestitution.h create mode 100644 libs/box2d/src/Tests/VerticalStack.h create mode 100644 libs/box2d/src/Tests/Web.h diff --git a/libs/box2d/.gitignore b/libs/box2d/.gitignore new file mode 100644 index 0000000..20ea569 --- /dev/null +++ b/libs/box2d/.gitignore @@ -0,0 +1,2 @@ +Box2D/ +Contributions/ diff --git a/libs/box2d/box2d-ios.xcodeproj/project.pbxproj b/libs/box2d/box2d-ios.xcodeproj/project.pbxproj new file mode 100644 index 0000000..edca52a --- /dev/null +++ b/libs/box2d/box2d-ios.xcodeproj/project.pbxproj @@ -0,0 +1,541 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 491330C81372616300DFB46D /* Box2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913307B1372616300DFB46D /* Box2D.h */; }; + 491330C91372616300DFB46D /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913307D1372616300DFB46D /* b2BroadPhase.cpp */; }; + 491330CA1372616300DFB46D /* b2BroadPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913307E1372616300DFB46D /* b2BroadPhase.h */; }; + 491330CB1372616300DFB46D /* b2CollideCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913307F1372616300DFB46D /* b2CollideCircle.cpp */; }; + 491330CC1372616300DFB46D /* b2CollidePolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330801372616300DFB46D /* b2CollidePolygon.cpp */; }; + 491330CD1372616300DFB46D /* b2Collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330811372616300DFB46D /* b2Collision.cpp */; }; + 491330CE1372616300DFB46D /* b2Collision.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330821372616300DFB46D /* b2Collision.h */; }; + 491330CF1372616300DFB46D /* b2Distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330831372616300DFB46D /* b2Distance.cpp */; }; + 491330D01372616300DFB46D /* b2Distance.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330841372616300DFB46D /* b2Distance.h */; }; + 491330D11372616300DFB46D /* b2DynamicTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330851372616300DFB46D /* b2DynamicTree.cpp */; }; + 491330D21372616300DFB46D /* b2DynamicTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330861372616300DFB46D /* b2DynamicTree.h */; }; + 491330D31372616300DFB46D /* b2TimeOfImpact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330871372616300DFB46D /* b2TimeOfImpact.cpp */; }; + 491330D41372616300DFB46D /* b2TimeOfImpact.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330881372616300DFB46D /* b2TimeOfImpact.h */; }; + 491330D51372616300DFB46D /* b2CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913308A1372616300DFB46D /* b2CircleShape.cpp */; }; + 491330D61372616300DFB46D /* b2CircleShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913308B1372616300DFB46D /* b2CircleShape.h */; }; + 491330D71372616300DFB46D /* b2PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913308C1372616300DFB46D /* b2PolygonShape.cpp */; }; + 491330D81372616300DFB46D /* b2PolygonShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913308D1372616300DFB46D /* b2PolygonShape.h */; }; + 491330D91372616300DFB46D /* b2Shape.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913308E1372616300DFB46D /* b2Shape.h */; }; + 491330DA1372616300DFB46D /* b2BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330901372616300DFB46D /* b2BlockAllocator.cpp */; }; + 491330DB1372616300DFB46D /* b2BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330911372616300DFB46D /* b2BlockAllocator.h */; }; + 491330DC1372616300DFB46D /* b2Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330921372616300DFB46D /* b2Math.cpp */; }; + 491330DD1372616300DFB46D /* b2Math.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330931372616300DFB46D /* b2Math.h */; }; + 491330DE1372616300DFB46D /* b2Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330941372616300DFB46D /* b2Settings.cpp */; }; + 491330DF1372616300DFB46D /* b2Settings.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330951372616300DFB46D /* b2Settings.h */; }; + 491330E01372616300DFB46D /* b2StackAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330961372616300DFB46D /* b2StackAllocator.cpp */; }; + 491330E11372616300DFB46D /* b2StackAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330971372616300DFB46D /* b2StackAllocator.h */; }; + 491330E21372616300DFB46D /* b2Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330991372616300DFB46D /* b2Body.cpp */; }; + 491330E31372616300DFB46D /* b2Body.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913309A1372616300DFB46D /* b2Body.h */; }; + 491330E41372616300DFB46D /* b2ContactManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913309B1372616300DFB46D /* b2ContactManager.cpp */; }; + 491330E51372616300DFB46D /* b2ContactManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913309C1372616300DFB46D /* b2ContactManager.h */; }; + 491330E61372616300DFB46D /* b2Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913309D1372616300DFB46D /* b2Fixture.cpp */; }; + 491330E71372616300DFB46D /* b2Fixture.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913309E1372616300DFB46D /* b2Fixture.h */; }; + 491330E81372616300DFB46D /* b2Island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4913309F1372616300DFB46D /* b2Island.cpp */; }; + 491330E91372616300DFB46D /* b2Island.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330A01372616300DFB46D /* b2Island.h */; }; + 491330EA1372616300DFB46D /* b2TimeStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330A11372616300DFB46D /* b2TimeStep.h */; }; + 491330EB1372616300DFB46D /* b2World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330A21372616300DFB46D /* b2World.cpp */; }; + 491330EC1372616300DFB46D /* b2World.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330A31372616300DFB46D /* b2World.h */; }; + 491330ED1372616300DFB46D /* b2WorldCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330A41372616300DFB46D /* b2WorldCallbacks.cpp */; }; + 491330EE1372616300DFB46D /* b2WorldCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330A51372616300DFB46D /* b2WorldCallbacks.h */; }; + 491330EF1372616300DFB46D /* b2CircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330A71372616300DFB46D /* b2CircleContact.cpp */; }; + 491330F01372616300DFB46D /* b2CircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330A81372616300DFB46D /* b2CircleContact.h */; }; + 491330F11372616300DFB46D /* b2Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330A91372616300DFB46D /* b2Contact.cpp */; }; + 491330F21372616300DFB46D /* b2Contact.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330AA1372616300DFB46D /* b2Contact.h */; }; + 491330F31372616300DFB46D /* b2ContactSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330AB1372616300DFB46D /* b2ContactSolver.cpp */; }; + 491330F41372616300DFB46D /* b2ContactSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330AC1372616300DFB46D /* b2ContactSolver.h */; }; + 491330F51372616300DFB46D /* b2PolygonAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330AD1372616300DFB46D /* b2PolygonAndCircleContact.cpp */; }; + 491330F61372616300DFB46D /* b2PolygonAndCircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330AE1372616300DFB46D /* b2PolygonAndCircleContact.h */; }; + 491330F71372616300DFB46D /* b2PolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330AF1372616300DFB46D /* b2PolygonContact.cpp */; }; + 491330F81372616300DFB46D /* b2PolygonContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330B01372616300DFB46D /* b2PolygonContact.h */; }; + 491330F91372616300DFB46D /* b2TOISolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330B11372616300DFB46D /* b2TOISolver.cpp */; }; + 491330FA1372616300DFB46D /* b2TOISolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330B21372616300DFB46D /* b2TOISolver.h */; }; + 491330FB1372616300DFB46D /* b2DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330B41372616300DFB46D /* b2DistanceJoint.cpp */; }; + 491330FC1372616300DFB46D /* b2DistanceJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330B51372616300DFB46D /* b2DistanceJoint.h */; }; + 491330FD1372616300DFB46D /* b2FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330B61372616300DFB46D /* b2FrictionJoint.cpp */; }; + 491330FE1372616300DFB46D /* b2FrictionJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330B71372616300DFB46D /* b2FrictionJoint.h */; }; + 491330FF1372616300DFB46D /* b2GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330B81372616300DFB46D /* b2GearJoint.cpp */; }; + 491331001372616300DFB46D /* b2GearJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330B91372616300DFB46D /* b2GearJoint.h */; }; + 491331011372616300DFB46D /* b2Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330BA1372616300DFB46D /* b2Joint.cpp */; }; + 491331021372616300DFB46D /* b2Joint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330BB1372616300DFB46D /* b2Joint.h */; }; + 491331031372616300DFB46D /* b2LineJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330BC1372616300DFB46D /* b2LineJoint.cpp */; }; + 491331041372616300DFB46D /* b2LineJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330BD1372616300DFB46D /* b2LineJoint.h */; }; + 491331051372616300DFB46D /* b2MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330BE1372616300DFB46D /* b2MouseJoint.cpp */; }; + 491331061372616300DFB46D /* b2MouseJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330BF1372616300DFB46D /* b2MouseJoint.h */; }; + 491331071372616300DFB46D /* b2PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330C01372616300DFB46D /* b2PrismaticJoint.cpp */; }; + 491331081372616300DFB46D /* b2PrismaticJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330C11372616300DFB46D /* b2PrismaticJoint.h */; }; + 491331091372616300DFB46D /* b2PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330C21372616300DFB46D /* b2PulleyJoint.cpp */; }; + 4913310A1372616300DFB46D /* b2PulleyJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330C31372616300DFB46D /* b2PulleyJoint.h */; }; + 4913310B1372616300DFB46D /* b2RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330C41372616300DFB46D /* b2RevoluteJoint.cpp */; }; + 4913310C1372616300DFB46D /* b2RevoluteJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330C51372616300DFB46D /* b2RevoluteJoint.h */; }; + 4913310D1372616300DFB46D /* b2WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491330C61372616300DFB46D /* b2WeldJoint.cpp */; }; + 4913310E1372616300DFB46D /* b2WeldJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 491330C71372616300DFB46D /* b2WeldJoint.h */; }; + 49133123137262F200DFB46D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49133122137262F200DFB46D /* Foundation.framework */; }; + 491331281372630700DFB46D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 491331271372630700DFB46D /* UIKit.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 4913305F1372610400DFB46D /* libBox2D.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBox2D.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 4913307B1372616300DFB46D /* Box2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = ""; }; + 4913307D1372616300DFB46D /* b2BroadPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = ""; }; + 4913307E1372616300DFB46D /* b2BroadPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = ""; }; + 4913307F1372616300DFB46D /* b2CollideCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = ""; }; + 491330801372616300DFB46D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = ""; }; + 491330811372616300DFB46D /* b2Collision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = ""; }; + 491330821372616300DFB46D /* b2Collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = ""; }; + 491330831372616300DFB46D /* b2Distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = ""; }; + 491330841372616300DFB46D /* b2Distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Distance.h; sourceTree = ""; }; + 491330851372616300DFB46D /* b2DynamicTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DynamicTree.cpp; sourceTree = ""; }; + 491330861372616300DFB46D /* b2DynamicTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DynamicTree.h; sourceTree = ""; }; + 491330871372616300DFB46D /* b2TimeOfImpact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TimeOfImpact.cpp; sourceTree = ""; }; + 491330881372616300DFB46D /* b2TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeOfImpact.h; sourceTree = ""; }; + 4913308A1372616300DFB46D /* b2CircleShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleShape.cpp; sourceTree = ""; }; + 4913308B1372616300DFB46D /* b2CircleShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = ""; }; + 4913308C1372616300DFB46D /* b2PolygonShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonShape.cpp; sourceTree = ""; }; + 4913308D1372616300DFB46D /* b2PolygonShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonShape.h; sourceTree = ""; }; + 4913308E1372616300DFB46D /* b2Shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Shape.h; sourceTree = ""; }; + 491330901372616300DFB46D /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = ""; }; + 491330911372616300DFB46D /* b2BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BlockAllocator.h; sourceTree = ""; }; + 491330921372616300DFB46D /* b2Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Math.cpp; sourceTree = ""; }; + 491330931372616300DFB46D /* b2Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Math.h; sourceTree = ""; }; + 491330941372616300DFB46D /* b2Settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Settings.cpp; sourceTree = ""; }; + 491330951372616300DFB46D /* b2Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Settings.h; sourceTree = ""; }; + 491330961372616300DFB46D /* b2StackAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2StackAllocator.cpp; sourceTree = ""; }; + 491330971372616300DFB46D /* b2StackAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = ""; }; + 491330991372616300DFB46D /* b2Body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Body.cpp; sourceTree = ""; }; + 4913309A1372616300DFB46D /* b2Body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Body.h; sourceTree = ""; }; + 4913309B1372616300DFB46D /* b2ContactManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactManager.cpp; sourceTree = ""; }; + 4913309C1372616300DFB46D /* b2ContactManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactManager.h; sourceTree = ""; }; + 4913309D1372616300DFB46D /* b2Fixture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Fixture.cpp; sourceTree = ""; }; + 4913309E1372616300DFB46D /* b2Fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = ""; }; + 4913309F1372616300DFB46D /* b2Island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = ""; }; + 491330A01372616300DFB46D /* b2Island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Island.h; sourceTree = ""; }; + 491330A11372616300DFB46D /* b2TimeStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeStep.h; sourceTree = ""; }; + 491330A21372616300DFB46D /* b2World.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2World.cpp; sourceTree = ""; }; + 491330A31372616300DFB46D /* b2World.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2World.h; sourceTree = ""; }; + 491330A41372616300DFB46D /* b2WorldCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WorldCallbacks.cpp; sourceTree = ""; }; + 491330A51372616300DFB46D /* b2WorldCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = ""; }; + 491330A71372616300DFB46D /* b2CircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = ""; }; + 491330A81372616300DFB46D /* b2CircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleContact.h; sourceTree = ""; }; + 491330A91372616300DFB46D /* b2Contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Contact.cpp; sourceTree = ""; }; + 491330AA1372616300DFB46D /* b2Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = ""; }; + 491330AB1372616300DFB46D /* b2ContactSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactSolver.cpp; sourceTree = ""; }; + 491330AC1372616300DFB46D /* b2ContactSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactSolver.h; sourceTree = ""; }; + 491330AD1372616300DFB46D /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = ""; }; + 491330AE1372616300DFB46D /* b2PolygonAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonAndCircleContact.h; sourceTree = ""; }; + 491330AF1372616300DFB46D /* b2PolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonContact.cpp; sourceTree = ""; }; + 491330B01372616300DFB46D /* b2PolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonContact.h; sourceTree = ""; }; + 491330B11372616300DFB46D /* b2TOISolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TOISolver.cpp; sourceTree = ""; }; + 491330B21372616300DFB46D /* b2TOISolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TOISolver.h; sourceTree = ""; }; + 491330B41372616300DFB46D /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = ""; }; + 491330B51372616300DFB46D /* b2DistanceJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DistanceJoint.h; sourceTree = ""; }; + 491330B61372616300DFB46D /* b2FrictionJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2FrictionJoint.cpp; sourceTree = ""; }; + 491330B71372616300DFB46D /* b2FrictionJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2FrictionJoint.h; sourceTree = ""; }; + 491330B81372616300DFB46D /* b2GearJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2GearJoint.cpp; sourceTree = ""; }; + 491330B91372616300DFB46D /* b2GearJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = ""; }; + 491330BA1372616300DFB46D /* b2Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Joint.cpp; sourceTree = ""; }; + 491330BB1372616300DFB46D /* b2Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Joint.h; sourceTree = ""; }; + 491330BC1372616300DFB46D /* b2LineJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2LineJoint.cpp; sourceTree = ""; }; + 491330BD1372616300DFB46D /* b2LineJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2LineJoint.h; sourceTree = ""; }; + 491330BE1372616300DFB46D /* b2MouseJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MouseJoint.cpp; sourceTree = ""; }; + 491330BF1372616300DFB46D /* b2MouseJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MouseJoint.h; sourceTree = ""; }; + 491330C01372616300DFB46D /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = ""; }; + 491330C11372616300DFB46D /* b2PrismaticJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PrismaticJoint.h; sourceTree = ""; }; + 491330C21372616300DFB46D /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = ""; }; + 491330C31372616300DFB46D /* b2PulleyJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PulleyJoint.h; sourceTree = ""; }; + 491330C41372616300DFB46D /* b2RevoluteJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2RevoluteJoint.cpp; sourceTree = ""; }; + 491330C51372616300DFB46D /* b2RevoluteJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2RevoluteJoint.h; sourceTree = ""; }; + 491330C61372616300DFB46D /* b2WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WeldJoint.cpp; sourceTree = ""; }; + 491330C71372616300DFB46D /* b2WeldJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = ""; }; + 49133122137262F200DFB46D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 491331271372630700DFB46D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4913305C1372610400DFB46D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 491331281372630700DFB46D /* UIKit.framework in Frameworks */, + 49133123137262F200DFB46D /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 491330541372610400DFB46D = { + isa = PBXGroup; + children = ( + 4913307A1372616300DFB46D /* Box2D */, + 491331291372630F00DFB46D /* Frameworks */, + 491330601372610400DFB46D /* Products */, + ); + sourceTree = ""; + }; + 491330601372610400DFB46D /* Products */ = { + isa = PBXGroup; + children = ( + 4913305F1372610400DFB46D /* libBox2D.a */, + ); + name = Products; + sourceTree = ""; + }; + 4913307A1372616300DFB46D /* Box2D */ = { + isa = PBXGroup; + children = ( + 4913307B1372616300DFB46D /* Box2D.h */, + 4913307C1372616300DFB46D /* Collision */, + 4913308F1372616300DFB46D /* Common */, + 491330981372616300DFB46D /* Dynamics */, + ); + name = Box2D; + path = src/Box2D; + sourceTree = ""; + }; + 4913307C1372616300DFB46D /* Collision */ = { + isa = PBXGroup; + children = ( + 4913307D1372616300DFB46D /* b2BroadPhase.cpp */, + 4913307E1372616300DFB46D /* b2BroadPhase.h */, + 4913307F1372616300DFB46D /* b2CollideCircle.cpp */, + 491330801372616300DFB46D /* b2CollidePolygon.cpp */, + 491330811372616300DFB46D /* b2Collision.cpp */, + 491330821372616300DFB46D /* b2Collision.h */, + 491330831372616300DFB46D /* b2Distance.cpp */, + 491330841372616300DFB46D /* b2Distance.h */, + 491330851372616300DFB46D /* b2DynamicTree.cpp */, + 491330861372616300DFB46D /* b2DynamicTree.h */, + 491330871372616300DFB46D /* b2TimeOfImpact.cpp */, + 491330881372616300DFB46D /* b2TimeOfImpact.h */, + 491330891372616300DFB46D /* Shapes */, + ); + path = Collision; + sourceTree = ""; + }; + 491330891372616300DFB46D /* Shapes */ = { + isa = PBXGroup; + children = ( + 4913308A1372616300DFB46D /* b2CircleShape.cpp */, + 4913308B1372616300DFB46D /* b2CircleShape.h */, + 4913308C1372616300DFB46D /* b2PolygonShape.cpp */, + 4913308D1372616300DFB46D /* b2PolygonShape.h */, + 4913308E1372616300DFB46D /* b2Shape.h */, + ); + path = Shapes; + sourceTree = ""; + }; + 4913308F1372616300DFB46D /* Common */ = { + isa = PBXGroup; + children = ( + 491330901372616300DFB46D /* b2BlockAllocator.cpp */, + 491330911372616300DFB46D /* b2BlockAllocator.h */, + 491330921372616300DFB46D /* b2Math.cpp */, + 491330931372616300DFB46D /* b2Math.h */, + 491330941372616300DFB46D /* b2Settings.cpp */, + 491330951372616300DFB46D /* b2Settings.h */, + 491330961372616300DFB46D /* b2StackAllocator.cpp */, + 491330971372616300DFB46D /* b2StackAllocator.h */, + ); + path = Common; + sourceTree = ""; + }; + 491330981372616300DFB46D /* Dynamics */ = { + isa = PBXGroup; + children = ( + 491330991372616300DFB46D /* b2Body.cpp */, + 4913309A1372616300DFB46D /* b2Body.h */, + 4913309B1372616300DFB46D /* b2ContactManager.cpp */, + 4913309C1372616300DFB46D /* b2ContactManager.h */, + 4913309D1372616300DFB46D /* b2Fixture.cpp */, + 4913309E1372616300DFB46D /* b2Fixture.h */, + 4913309F1372616300DFB46D /* b2Island.cpp */, + 491330A01372616300DFB46D /* b2Island.h */, + 491330A11372616300DFB46D /* b2TimeStep.h */, + 491330A21372616300DFB46D /* b2World.cpp */, + 491330A31372616300DFB46D /* b2World.h */, + 491330A41372616300DFB46D /* b2WorldCallbacks.cpp */, + 491330A51372616300DFB46D /* b2WorldCallbacks.h */, + 491330A61372616300DFB46D /* Contacts */, + 491330B31372616300DFB46D /* Joints */, + ); + path = Dynamics; + sourceTree = ""; + }; + 491330A61372616300DFB46D /* Contacts */ = { + isa = PBXGroup; + children = ( + 491330A71372616300DFB46D /* b2CircleContact.cpp */, + 491330A81372616300DFB46D /* b2CircleContact.h */, + 491330A91372616300DFB46D /* b2Contact.cpp */, + 491330AA1372616300DFB46D /* b2Contact.h */, + 491330AB1372616300DFB46D /* b2ContactSolver.cpp */, + 491330AC1372616300DFB46D /* b2ContactSolver.h */, + 491330AD1372616300DFB46D /* b2PolygonAndCircleContact.cpp */, + 491330AE1372616300DFB46D /* b2PolygonAndCircleContact.h */, + 491330AF1372616300DFB46D /* b2PolygonContact.cpp */, + 491330B01372616300DFB46D /* b2PolygonContact.h */, + 491330B11372616300DFB46D /* b2TOISolver.cpp */, + 491330B21372616300DFB46D /* b2TOISolver.h */, + ); + path = Contacts; + sourceTree = ""; + }; + 491330B31372616300DFB46D /* Joints */ = { + isa = PBXGroup; + children = ( + 491330B41372616300DFB46D /* b2DistanceJoint.cpp */, + 491330B51372616300DFB46D /* b2DistanceJoint.h */, + 491330B61372616300DFB46D /* b2FrictionJoint.cpp */, + 491330B71372616300DFB46D /* b2FrictionJoint.h */, + 491330B81372616300DFB46D /* b2GearJoint.cpp */, + 491330B91372616300DFB46D /* b2GearJoint.h */, + 491330BA1372616300DFB46D /* b2Joint.cpp */, + 491330BB1372616300DFB46D /* b2Joint.h */, + 491330BC1372616300DFB46D /* b2LineJoint.cpp */, + 491330BD1372616300DFB46D /* b2LineJoint.h */, + 491330BE1372616300DFB46D /* b2MouseJoint.cpp */, + 491330BF1372616300DFB46D /* b2MouseJoint.h */, + 491330C01372616300DFB46D /* b2PrismaticJoint.cpp */, + 491330C11372616300DFB46D /* b2PrismaticJoint.h */, + 491330C21372616300DFB46D /* b2PulleyJoint.cpp */, + 491330C31372616300DFB46D /* b2PulleyJoint.h */, + 491330C41372616300DFB46D /* b2RevoluteJoint.cpp */, + 491330C51372616300DFB46D /* b2RevoluteJoint.h */, + 491330C61372616300DFB46D /* b2WeldJoint.cpp */, + 491330C71372616300DFB46D /* b2WeldJoint.h */, + ); + path = Joints; + sourceTree = ""; + }; + 491331291372630F00DFB46D /* Frameworks */ = { + isa = PBXGroup; + children = ( + 491331271372630700DFB46D /* UIKit.framework */, + 49133122137262F200DFB46D /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4913305D1372610400DFB46D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 491330C81372616300DFB46D /* Box2D.h in Headers */, + 491330CA1372616300DFB46D /* b2BroadPhase.h in Headers */, + 491330CE1372616300DFB46D /* b2Collision.h in Headers */, + 491330D01372616300DFB46D /* b2Distance.h in Headers */, + 491330D21372616300DFB46D /* b2DynamicTree.h in Headers */, + 491330D41372616300DFB46D /* b2TimeOfImpact.h in Headers */, + 491330D61372616300DFB46D /* b2CircleShape.h in Headers */, + 491330D81372616300DFB46D /* b2PolygonShape.h in Headers */, + 491330D91372616300DFB46D /* b2Shape.h in Headers */, + 491330DB1372616300DFB46D /* b2BlockAllocator.h in Headers */, + 491330DD1372616300DFB46D /* b2Math.h in Headers */, + 491330DF1372616300DFB46D /* b2Settings.h in Headers */, + 491330E11372616300DFB46D /* b2StackAllocator.h in Headers */, + 491330E31372616300DFB46D /* b2Body.h in Headers */, + 491330E51372616300DFB46D /* b2ContactManager.h in Headers */, + 491330E71372616300DFB46D /* b2Fixture.h in Headers */, + 491330E91372616300DFB46D /* b2Island.h in Headers */, + 491330EA1372616300DFB46D /* b2TimeStep.h in Headers */, + 491330EC1372616300DFB46D /* b2World.h in Headers */, + 491330EE1372616300DFB46D /* b2WorldCallbacks.h in Headers */, + 491330F01372616300DFB46D /* b2CircleContact.h in Headers */, + 491330F21372616300DFB46D /* b2Contact.h in Headers */, + 491330F41372616300DFB46D /* b2ContactSolver.h in Headers */, + 491330F61372616300DFB46D /* b2PolygonAndCircleContact.h in Headers */, + 491330F81372616300DFB46D /* b2PolygonContact.h in Headers */, + 491330FA1372616300DFB46D /* b2TOISolver.h in Headers */, + 491330FC1372616300DFB46D /* b2DistanceJoint.h in Headers */, + 491330FE1372616300DFB46D /* b2FrictionJoint.h in Headers */, + 491331001372616300DFB46D /* b2GearJoint.h in Headers */, + 491331021372616300DFB46D /* b2Joint.h in Headers */, + 491331041372616300DFB46D /* b2LineJoint.h in Headers */, + 491331061372616300DFB46D /* b2MouseJoint.h in Headers */, + 491331081372616300DFB46D /* b2PrismaticJoint.h in Headers */, + 4913310A1372616300DFB46D /* b2PulleyJoint.h in Headers */, + 4913310C1372616300DFB46D /* b2RevoluteJoint.h in Headers */, + 4913310E1372616300DFB46D /* b2WeldJoint.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 4913305E1372610400DFB46D /* Box2D */ = { + isa = PBXNativeTarget; + buildConfigurationList = 491330691372610400DFB46D /* Build configuration list for PBXNativeTarget "Box2D" */; + buildPhases = ( + 4913305B1372610400DFB46D /* Sources */, + 4913305C1372610400DFB46D /* Frameworks */, + 4913305D1372610400DFB46D /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Box2D; + productName = Box2D; + productReference = 4913305F1372610400DFB46D /* libBox2D.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 491330561372610400DFB46D /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 491330591372610400DFB46D /* Build configuration list for PBXProject "box2d-ios" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 491330541372610400DFB46D; + productRefGroup = 491330601372610400DFB46D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4913305E1372610400DFB46D /* Box2D */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 4913305B1372610400DFB46D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 491330C91372616300DFB46D /* b2BroadPhase.cpp in Sources */, + 491330CB1372616300DFB46D /* b2CollideCircle.cpp in Sources */, + 491330CC1372616300DFB46D /* b2CollidePolygon.cpp in Sources */, + 491330CD1372616300DFB46D /* b2Collision.cpp in Sources */, + 491330CF1372616300DFB46D /* b2Distance.cpp in Sources */, + 491330D11372616300DFB46D /* b2DynamicTree.cpp in Sources */, + 491330D31372616300DFB46D /* b2TimeOfImpact.cpp in Sources */, + 491330D51372616300DFB46D /* b2CircleShape.cpp in Sources */, + 491330D71372616300DFB46D /* b2PolygonShape.cpp in Sources */, + 491330DA1372616300DFB46D /* b2BlockAllocator.cpp in Sources */, + 491330DC1372616300DFB46D /* b2Math.cpp in Sources */, + 491330DE1372616300DFB46D /* b2Settings.cpp in Sources */, + 491330E01372616300DFB46D /* b2StackAllocator.cpp in Sources */, + 491330E21372616300DFB46D /* b2Body.cpp in Sources */, + 491330E41372616300DFB46D /* b2ContactManager.cpp in Sources */, + 491330E61372616300DFB46D /* b2Fixture.cpp in Sources */, + 491330E81372616300DFB46D /* b2Island.cpp in Sources */, + 491330EB1372616300DFB46D /* b2World.cpp in Sources */, + 491330ED1372616300DFB46D /* b2WorldCallbacks.cpp in Sources */, + 491330EF1372616300DFB46D /* b2CircleContact.cpp in Sources */, + 491330F11372616300DFB46D /* b2Contact.cpp in Sources */, + 491330F31372616300DFB46D /* b2ContactSolver.cpp in Sources */, + 491330F51372616300DFB46D /* b2PolygonAndCircleContact.cpp in Sources */, + 491330F71372616300DFB46D /* b2PolygonContact.cpp in Sources */, + 491330F91372616300DFB46D /* b2TOISolver.cpp in Sources */, + 491330FB1372616300DFB46D /* b2DistanceJoint.cpp in Sources */, + 491330FD1372616300DFB46D /* b2FrictionJoint.cpp in Sources */, + 491330FF1372616300DFB46D /* b2GearJoint.cpp in Sources */, + 491331011372616300DFB46D /* b2Joint.cpp in Sources */, + 491331031372616300DFB46D /* b2LineJoint.cpp in Sources */, + 491331051372616300DFB46D /* b2MouseJoint.cpp in Sources */, + 491331071372616300DFB46D /* b2PrismaticJoint.cpp in Sources */, + 491331091372616300DFB46D /* b2PulleyJoint.cpp in Sources */, + 4913310B1372616300DFB46D /* b2RevoluteJoint.cpp in Sources */, + 4913310D1372616300DFB46D /* b2WeldJoint.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 491330671372610400DFB46D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = 4.2; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 491330681372610400DFB46D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_VERSION = 4.2; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; + SDKROOT = iphoneos; + }; + name = Release; + }; + 4913306A1372610400DFB46D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + DSTROOT = /tmp/Box2D.dst; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Box2D/Box2D-Prefix.pch"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "./src/**"; + }; + name = Debug; + }; + 4913306B1372610400DFB46D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + DSTROOT = /tmp/Box2D.dst; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Box2D/Box2D-Prefix.pch"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + USER_HEADER_SEARCH_PATHS = "./src/**"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 491330591372610400DFB46D /* Build configuration list for PBXProject "box2d-ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 491330671372610400DFB46D /* Debug */, + 491330681372610400DFB46D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 491330691372610400DFB46D /* Build configuration list for PBXNativeTarget "Box2D" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4913306A1372610400DFB46D /* Debug */, + 4913306B1372610400DFB46D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 491330561372610400DFB46D /* Project object */; +} diff --git a/libs/box2d/box2d-iphone.xcodeproj/project.pbxproj b/libs/box2d/box2d-iphone.xcodeproj/project.pbxproj new file mode 100644 index 0000000..354b97c --- /dev/null +++ b/libs/box2d/box2d-iphone.xcodeproj/project.pbxproj @@ -0,0 +1,560 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 4913316E1372645C00DFB46D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4913316D1372645C00DFB46D /* UIKit.framework */; }; + 491331701372645C00DFB46D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4913316F1372645C00DFB46D /* Foundation.framework */; }; + 491331721372645C00DFB46D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 491331711372645C00DFB46D /* CoreGraphics.framework */; }; + 491331A91372653600DFB46D /* Box2DAppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4913319A1372653600DFB46D /* Box2DAppDelegate.mm */; }; + 491331AA1372653600DFB46D /* Box2DView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4913319C1372653600DFB46D /* Box2DView.mm */; }; + 491331AB1372653600DFB46D /* GLES-Render.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4913319F1372653600DFB46D /* GLES-Render.mm */; }; + 491331AC1372653600DFB46D /* iPhoneTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 491331A11372653600DFB46D /* iPhoneTest.mm */; }; + 491331AD1372653600DFB46D /* iPhoneTestEntries.mm in Sources */ = {isa = PBXBuildFile; fileRef = 491331A21372653600DFB46D /* iPhoneTestEntries.mm */; }; + 491331AE1372653600DFB46D /* TestEntriesViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 491331A41372653600DFB46D /* TestEntriesViewController.mm */; }; + 491331AF1372653600DFB46D /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 491331A51372653600DFB46D /* Icon.png */; }; + 491331B01372653600DFB46D /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 491331A61372653600DFB46D /* Info.plist */; }; + 491331B11372653600DFB46D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 491331A71372653600DFB46D /* main.m */; }; + 491331B21372653600DFB46D /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 491331A81372653600DFB46D /* MainWindow.xib */; }; + 491331C11372663200DFB46D /* libBox2D.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 491331C01372663200DFB46D /* libBox2D.a */; }; + 4913323813726B1F00DFB46D /* ApplyForce.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913320D13726B1F00DFB46D /* ApplyForce.h */; }; + 4913323913726B1F00DFB46D /* BodyTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913320E13726B1F00DFB46D /* BodyTypes.h */; }; + 4913323A13726B1F00DFB46D /* Breakable.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913320F13726B1F00DFB46D /* Breakable.h */; }; + 4913323B13726B1F00DFB46D /* Bridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321013726B1F00DFB46D /* Bridge.h */; }; + 4913323C13726B1F00DFB46D /* BulletTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321113726B1F00DFB46D /* BulletTest.h */; }; + 4913323D13726B1F00DFB46D /* Cantilever.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321213726B1F00DFB46D /* Cantilever.h */; }; + 4913323E13726B1F00DFB46D /* Car.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321313726B1F00DFB46D /* Car.h */; }; + 4913323F13726B1F00DFB46D /* Chain.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321413726B1F00DFB46D /* Chain.h */; }; + 4913324013726B1F00DFB46D /* CharacterCollision.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321513726B1F00DFB46D /* CharacterCollision.h */; }; + 4913324113726B1F00DFB46D /* CollisionFiltering.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321613726B1F00DFB46D /* CollisionFiltering.h */; }; + 4913324213726B1F00DFB46D /* CollisionProcessing.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321713726B1F00DFB46D /* CollisionProcessing.h */; }; + 4913324313726B1F00DFB46D /* CompoundShapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321813726B1F00DFB46D /* CompoundShapes.h */; }; + 4913324413726B1F00DFB46D /* Confined.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321913726B1F00DFB46D /* Confined.h */; }; + 4913324513726B1F00DFB46D /* ContinuousTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321A13726B1F00DFB46D /* ContinuousTest.h */; }; + 4913324613726B1F00DFB46D /* DistanceTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321B13726B1F00DFB46D /* DistanceTest.h */; }; + 4913324713726B1F00DFB46D /* Dominos.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321C13726B1F00DFB46D /* Dominos.h */; }; + 4913324813726B1F00DFB46D /* DynamicTreeTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321D13726B1F00DFB46D /* DynamicTreeTest.h */; }; + 4913324913726B1F00DFB46D /* EdgeShapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321E13726B1F00DFB46D /* EdgeShapes.h */; }; + 4913324A13726B1F00DFB46D /* EdgeTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913321F13726B1F00DFB46D /* EdgeTest.h */; }; + 4913324B13726B1F00DFB46D /* Gears.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322013726B1F00DFB46D /* Gears.h */; }; + 4913324C13726B1F00DFB46D /* LineJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322113726B1F00DFB46D /* LineJoint.h */; }; + 4913324D13726B1F00DFB46D /* OneSidedPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322213726B1F00DFB46D /* OneSidedPlatform.h */; }; + 4913324E13726B1F00DFB46D /* Pinball.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322313726B1F00DFB46D /* Pinball.h */; }; + 4913324F13726B1F00DFB46D /* PolyCollision.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322413726B1F00DFB46D /* PolyCollision.h */; }; + 4913325013726B1F00DFB46D /* PolyShapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322513726B1F00DFB46D /* PolyShapes.h */; }; + 4913325113726B1F00DFB46D /* Prismatic.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322613726B1F00DFB46D /* Prismatic.h */; }; + 4913325213726B1F00DFB46D /* Pulleys.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322713726B1F00DFB46D /* Pulleys.h */; }; + 4913325313726B1F00DFB46D /* Pyramid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322813726B1F00DFB46D /* Pyramid.h */; }; + 4913325413726B1F00DFB46D /* RayCast.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322913726B1F00DFB46D /* RayCast.h */; }; + 4913325513726B1F00DFB46D /* Revolute.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322A13726B1F00DFB46D /* Revolute.h */; }; + 4913325613726B1F00DFB46D /* Rope.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322B13726B1F00DFB46D /* Rope.h */; }; + 4913325713726B1F00DFB46D /* RopeJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322C13726B1F00DFB46D /* RopeJoint.h */; }; + 4913325813726B1F00DFB46D /* SensorTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322D13726B1F00DFB46D /* SensorTest.h */; }; + 4913325913726B1F00DFB46D /* ShapeEditing.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322E13726B1F00DFB46D /* ShapeEditing.h */; }; + 4913325A13726B1F00DFB46D /* SliderCrank.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913322F13726B1F00DFB46D /* SliderCrank.h */; }; + 4913325B13726B1F00DFB46D /* SphereStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323013726B1F00DFB46D /* SphereStack.h */; }; + 4913325C13726B1F00DFB46D /* TheoJansen.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323113726B1F00DFB46D /* TheoJansen.h */; }; + 4913325D13726B1F00DFB46D /* Tiles.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323213726B1F00DFB46D /* Tiles.h */; }; + 4913325E13726B1F00DFB46D /* TimeOfImpact.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323313726B1F00DFB46D /* TimeOfImpact.h */; }; + 4913325F13726B1F00DFB46D /* VaryingFriction.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323413726B1F00DFB46D /* VaryingFriction.h */; }; + 4913326013726B1F00DFB46D /* VaryingRestitution.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323513726B1F00DFB46D /* VaryingRestitution.h */; }; + 4913326113726B1F00DFB46D /* VerticalStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323613726B1F00DFB46D /* VerticalStack.h */; }; + 4913326213726B1F00DFB46D /* Web.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913323713726B1F00DFB46D /* Web.h */; }; + 4913326413726B5D00DFB46D /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4913326313726B5D00DFB46D /* OpenGLES.framework */; }; + 4913326E13726BC800DFB46D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4913326D13726BC800DFB46D /* QuartzCore.framework */; }; + 4913326F13726D2F00DFB46D /* Box2DAppDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 491331991372653600DFB46D /* Box2DAppDelegate.h */; }; + 4913327013726D2F00DFB46D /* Box2DView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913319B1372653600DFB46D /* Box2DView.h */; }; + 4913327113726D2F00DFB46D /* Delegates.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913319D1372653600DFB46D /* Delegates.h */; }; + 4913327213726D2F00DFB46D /* GLES-Render.h in Headers */ = {isa = PBXBuildFile; fileRef = 4913319E1372653600DFB46D /* GLES-Render.h */; }; + 4913327313726D2F00DFB46D /* iPhoneTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 491331A01372653600DFB46D /* iPhoneTest.h */; }; + 4913327413726D2F00DFB46D /* TestEntriesViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 491331A31372653600DFB46D /* TestEntriesViewController.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 491331BB1372661700DFB46D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 491331B41372661600DFB46D /* box2d-ios.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 4913305F1372610400DFB46D; + remoteInfo = Box2D; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 491331691372645C00DFB46D /* box2d-iphone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "box2d-iphone.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4913316D1372645C00DFB46D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 4913316F1372645C00DFB46D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 491331711372645C00DFB46D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 491331971372653600DFB46D /* Box2D_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D_Prefix.pch; sourceTree = ""; }; + 491331991372653600DFB46D /* Box2DAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2DAppDelegate.h; sourceTree = ""; }; + 4913319A1372653600DFB46D /* Box2DAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Box2DAppDelegate.mm; sourceTree = ""; }; + 4913319B1372653600DFB46D /* Box2DView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2DView.h; sourceTree = ""; }; + 4913319C1372653600DFB46D /* Box2DView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Box2DView.mm; sourceTree = ""; }; + 4913319D1372653600DFB46D /* Delegates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Delegates.h; sourceTree = ""; }; + 4913319E1372653600DFB46D /* GLES-Render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GLES-Render.h"; sourceTree = ""; }; + 4913319F1372653600DFB46D /* GLES-Render.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "GLES-Render.mm"; sourceTree = ""; }; + 491331A01372653600DFB46D /* iPhoneTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneTest.h; sourceTree = ""; }; + 491331A11372653600DFB46D /* iPhoneTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iPhoneTest.mm; sourceTree = ""; }; + 491331A21372653600DFB46D /* iPhoneTestEntries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iPhoneTestEntries.mm; sourceTree = ""; }; + 491331A31372653600DFB46D /* TestEntriesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestEntriesViewController.h; sourceTree = ""; }; + 491331A41372653600DFB46D /* TestEntriesViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestEntriesViewController.mm; sourceTree = ""; }; + 491331A51372653600DFB46D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; + 491331A61372653600DFB46D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 491331A71372653600DFB46D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 491331A81372653600DFB46D /* MainWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + 491331B41372661600DFB46D /* box2d-ios.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "box2d-ios.xcodeproj"; sourceTree = SOURCE_ROOT; }; + 491331C01372663200DFB46D /* libBox2D.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libBox2D.a; sourceTree = SOURCE_ROOT; }; + 4913320D13726B1F00DFB46D /* ApplyForce.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplyForce.h; sourceTree = ""; }; + 4913320E13726B1F00DFB46D /* BodyTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BodyTypes.h; sourceTree = ""; }; + 4913320F13726B1F00DFB46D /* Breakable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakable.h; sourceTree = ""; }; + 4913321013726B1F00DFB46D /* Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridge.h; sourceTree = ""; }; + 4913321113726B1F00DFB46D /* BulletTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BulletTest.h; sourceTree = ""; }; + 4913321213726B1F00DFB46D /* Cantilever.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cantilever.h; sourceTree = ""; }; + 4913321313726B1F00DFB46D /* Car.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Car.h; sourceTree = ""; }; + 4913321413726B1F00DFB46D /* Chain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Chain.h; sourceTree = ""; }; + 4913321513726B1F00DFB46D /* CharacterCollision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterCollision.h; sourceTree = ""; }; + 4913321613726B1F00DFB46D /* CollisionFiltering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollisionFiltering.h; sourceTree = ""; }; + 4913321713726B1F00DFB46D /* CollisionProcessing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollisionProcessing.h; sourceTree = ""; }; + 4913321813726B1F00DFB46D /* CompoundShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompoundShapes.h; sourceTree = ""; }; + 4913321913726B1F00DFB46D /* Confined.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Confined.h; sourceTree = ""; }; + 4913321A13726B1F00DFB46D /* ContinuousTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContinuousTest.h; sourceTree = ""; }; + 4913321B13726B1F00DFB46D /* DistanceTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DistanceTest.h; sourceTree = ""; }; + 4913321C13726B1F00DFB46D /* Dominos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dominos.h; sourceTree = ""; }; + 4913321D13726B1F00DFB46D /* DynamicTreeTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicTreeTest.h; sourceTree = ""; }; + 4913321E13726B1F00DFB46D /* EdgeShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdgeShapes.h; sourceTree = ""; }; + 4913321F13726B1F00DFB46D /* EdgeTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdgeTest.h; sourceTree = ""; }; + 4913322013726B1F00DFB46D /* Gears.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gears.h; sourceTree = ""; }; + 4913322113726B1F00DFB46D /* LineJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineJoint.h; sourceTree = ""; }; + 4913322213726B1F00DFB46D /* OneSidedPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OneSidedPlatform.h; sourceTree = ""; }; + 4913322313726B1F00DFB46D /* Pinball.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pinball.h; sourceTree = ""; }; + 4913322413726B1F00DFB46D /* PolyCollision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyCollision.h; sourceTree = ""; }; + 4913322513726B1F00DFB46D /* PolyShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyShapes.h; sourceTree = ""; }; + 4913322613726B1F00DFB46D /* Prismatic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prismatic.h; sourceTree = ""; }; + 4913322713726B1F00DFB46D /* Pulleys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pulleys.h; sourceTree = ""; }; + 4913322813726B1F00DFB46D /* Pyramid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pyramid.h; sourceTree = ""; }; + 4913322913726B1F00DFB46D /* RayCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RayCast.h; sourceTree = ""; }; + 4913322A13726B1F00DFB46D /* Revolute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Revolute.h; sourceTree = ""; }; + 4913322B13726B1F00DFB46D /* Rope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Rope.h; sourceTree = ""; }; + 4913322C13726B1F00DFB46D /* RopeJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeJoint.h; sourceTree = ""; }; + 4913322D13726B1F00DFB46D /* SensorTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SensorTest.h; sourceTree = ""; }; + 4913322E13726B1F00DFB46D /* ShapeEditing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShapeEditing.h; sourceTree = ""; }; + 4913322F13726B1F00DFB46D /* SliderCrank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SliderCrank.h; sourceTree = ""; }; + 4913323013726B1F00DFB46D /* SphereStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SphereStack.h; sourceTree = ""; }; + 4913323113726B1F00DFB46D /* TheoJansen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TheoJansen.h; sourceTree = ""; }; + 4913323213726B1F00DFB46D /* Tiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tiles.h; sourceTree = ""; }; + 4913323313726B1F00DFB46D /* TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeOfImpact.h; sourceTree = ""; }; + 4913323413726B1F00DFB46D /* VaryingFriction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VaryingFriction.h; sourceTree = ""; }; + 4913323513726B1F00DFB46D /* VaryingRestitution.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VaryingRestitution.h; sourceTree = ""; }; + 4913323613726B1F00DFB46D /* VerticalStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VerticalStack.h; sourceTree = ""; }; + 4913323713726B1F00DFB46D /* Web.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Web.h; sourceTree = ""; }; + 4913326313726B5D00DFB46D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; + 4913326D13726BC800DFB46D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 491331661372645C00DFB46D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4913326E13726BC800DFB46D /* QuartzCore.framework in Frameworks */, + 4913326413726B5D00DFB46D /* OpenGLES.framework in Frameworks */, + 4913316E1372645C00DFB46D /* UIKit.framework in Frameworks */, + 491331701372645C00DFB46D /* Foundation.framework in Frameworks */, + 491331721372645C00DFB46D /* CoreGraphics.framework in Frameworks */, + 491331C11372663200DFB46D /* libBox2D.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4913315E1372645C00DFB46D = { + isa = PBXGroup; + children = ( + 491331B41372661600DFB46D /* box2d-ios.xcodeproj */, + 491331961372653600DFB46D /* iPhone */, + 4913320C13726B1F00DFB46D /* Tests */, + 491331B31372654900DFB46D /* Resources */, + 4913316C1372645C00DFB46D /* Frameworks */, + 4913316A1372645C00DFB46D /* Products */, + ); + sourceTree = ""; + }; + 4913316A1372645C00DFB46D /* Products */ = { + isa = PBXGroup; + children = ( + 491331691372645C00DFB46D /* box2d-iphone.app */, + ); + name = Products; + sourceTree = ""; + }; + 4913316C1372645C00DFB46D /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4913326D13726BC800DFB46D /* QuartzCore.framework */, + 4913326313726B5D00DFB46D /* OpenGLES.framework */, + 491331C01372663200DFB46D /* libBox2D.a */, + 4913316D1372645C00DFB46D /* UIKit.framework */, + 4913316F1372645C00DFB46D /* Foundation.framework */, + 491331711372645C00DFB46D /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 491331961372653600DFB46D /* iPhone */ = { + isa = PBXGroup; + children = ( + 491331971372653600DFB46D /* Box2D_Prefix.pch */, + 491331981372653600DFB46D /* Classes */, + 491331A71372653600DFB46D /* main.m */, + 491331A81372653600DFB46D /* MainWindow.xib */, + ); + path = iPhone; + sourceTree = ""; + }; + 491331981372653600DFB46D /* Classes */ = { + isa = PBXGroup; + children = ( + 491331991372653600DFB46D /* Box2DAppDelegate.h */, + 4913319A1372653600DFB46D /* Box2DAppDelegate.mm */, + 4913319B1372653600DFB46D /* Box2DView.h */, + 4913319C1372653600DFB46D /* Box2DView.mm */, + 4913319D1372653600DFB46D /* Delegates.h */, + 4913319E1372653600DFB46D /* GLES-Render.h */, + 4913319F1372653600DFB46D /* GLES-Render.mm */, + 491331A01372653600DFB46D /* iPhoneTest.h */, + 491331A11372653600DFB46D /* iPhoneTest.mm */, + 491331A21372653600DFB46D /* iPhoneTestEntries.mm */, + 491331A31372653600DFB46D /* TestEntriesViewController.h */, + 491331A41372653600DFB46D /* TestEntriesViewController.mm */, + ); + path = Classes; + sourceTree = ""; + }; + 491331B31372654900DFB46D /* Resources */ = { + isa = PBXGroup; + children = ( + 491331A51372653600DFB46D /* Icon.png */, + 491331A61372653600DFB46D /* Info.plist */, + ); + name = Resources; + path = iPhone; + sourceTree = ""; + }; + 491331B51372661600DFB46D /* Products */ = { + isa = PBXGroup; + children = ( + 491331BC1372661700DFB46D /* libBox2D.a */, + ); + name = Products; + sourceTree = ""; + }; + 4913320C13726B1F00DFB46D /* Tests */ = { + isa = PBXGroup; + children = ( + 4913320D13726B1F00DFB46D /* ApplyForce.h */, + 4913320E13726B1F00DFB46D /* BodyTypes.h */, + 4913320F13726B1F00DFB46D /* Breakable.h */, + 4913321013726B1F00DFB46D /* Bridge.h */, + 4913321113726B1F00DFB46D /* BulletTest.h */, + 4913321213726B1F00DFB46D /* Cantilever.h */, + 4913321313726B1F00DFB46D /* Car.h */, + 4913321413726B1F00DFB46D /* Chain.h */, + 4913321513726B1F00DFB46D /* CharacterCollision.h */, + 4913321613726B1F00DFB46D /* CollisionFiltering.h */, + 4913321713726B1F00DFB46D /* CollisionProcessing.h */, + 4913321813726B1F00DFB46D /* CompoundShapes.h */, + 4913321913726B1F00DFB46D /* Confined.h */, + 4913321A13726B1F00DFB46D /* ContinuousTest.h */, + 4913321B13726B1F00DFB46D /* DistanceTest.h */, + 4913321C13726B1F00DFB46D /* Dominos.h */, + 4913321D13726B1F00DFB46D /* DynamicTreeTest.h */, + 4913321E13726B1F00DFB46D /* EdgeShapes.h */, + 4913321F13726B1F00DFB46D /* EdgeTest.h */, + 4913322013726B1F00DFB46D /* Gears.h */, + 4913322113726B1F00DFB46D /* LineJoint.h */, + 4913322213726B1F00DFB46D /* OneSidedPlatform.h */, + 4913322313726B1F00DFB46D /* Pinball.h */, + 4913322413726B1F00DFB46D /* PolyCollision.h */, + 4913322513726B1F00DFB46D /* PolyShapes.h */, + 4913322613726B1F00DFB46D /* Prismatic.h */, + 4913322713726B1F00DFB46D /* Pulleys.h */, + 4913322813726B1F00DFB46D /* Pyramid.h */, + 4913322913726B1F00DFB46D /* RayCast.h */, + 4913322A13726B1F00DFB46D /* Revolute.h */, + 4913322B13726B1F00DFB46D /* Rope.h */, + 4913322C13726B1F00DFB46D /* RopeJoint.h */, + 4913322D13726B1F00DFB46D /* SensorTest.h */, + 4913322E13726B1F00DFB46D /* ShapeEditing.h */, + 4913322F13726B1F00DFB46D /* SliderCrank.h */, + 4913323013726B1F00DFB46D /* SphereStack.h */, + 4913323113726B1F00DFB46D /* TheoJansen.h */, + 4913323213726B1F00DFB46D /* Tiles.h */, + 4913323313726B1F00DFB46D /* TimeOfImpact.h */, + 4913323413726B1F00DFB46D /* VaryingFriction.h */, + 4913323513726B1F00DFB46D /* VaryingRestitution.h */, + 4913323613726B1F00DFB46D /* VerticalStack.h */, + 4913323713726B1F00DFB46D /* Web.h */, + ); + name = Tests; + path = src/Tests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 491331E71372682200DFB46D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4913326F13726D2F00DFB46D /* Box2DAppDelegate.h in Headers */, + 4913327013726D2F00DFB46D /* Box2DView.h in Headers */, + 4913327113726D2F00DFB46D /* Delegates.h in Headers */, + 4913327213726D2F00DFB46D /* GLES-Render.h in Headers */, + 4913327313726D2F00DFB46D /* iPhoneTest.h in Headers */, + 4913327413726D2F00DFB46D /* TestEntriesViewController.h in Headers */, + 4913323813726B1F00DFB46D /* ApplyForce.h in Headers */, + 4913323913726B1F00DFB46D /* BodyTypes.h in Headers */, + 4913323A13726B1F00DFB46D /* Breakable.h in Headers */, + 4913323B13726B1F00DFB46D /* Bridge.h in Headers */, + 4913323C13726B1F00DFB46D /* BulletTest.h in Headers */, + 4913323D13726B1F00DFB46D /* Cantilever.h in Headers */, + 4913323E13726B1F00DFB46D /* Car.h in Headers */, + 4913323F13726B1F00DFB46D /* Chain.h in Headers */, + 4913324013726B1F00DFB46D /* CharacterCollision.h in Headers */, + 4913324113726B1F00DFB46D /* CollisionFiltering.h in Headers */, + 4913324213726B1F00DFB46D /* CollisionProcessing.h in Headers */, + 4913324313726B1F00DFB46D /* CompoundShapes.h in Headers */, + 4913324413726B1F00DFB46D /* Confined.h in Headers */, + 4913324513726B1F00DFB46D /* ContinuousTest.h in Headers */, + 4913324613726B1F00DFB46D /* DistanceTest.h in Headers */, + 4913324713726B1F00DFB46D /* Dominos.h in Headers */, + 4913324813726B1F00DFB46D /* DynamicTreeTest.h in Headers */, + 4913324913726B1F00DFB46D /* EdgeShapes.h in Headers */, + 4913324A13726B1F00DFB46D /* EdgeTest.h in Headers */, + 4913324B13726B1F00DFB46D /* Gears.h in Headers */, + 4913324C13726B1F00DFB46D /* LineJoint.h in Headers */, + 4913324D13726B1F00DFB46D /* OneSidedPlatform.h in Headers */, + 4913324E13726B1F00DFB46D /* Pinball.h in Headers */, + 4913324F13726B1F00DFB46D /* PolyCollision.h in Headers */, + 4913325013726B1F00DFB46D /* PolyShapes.h in Headers */, + 4913325113726B1F00DFB46D /* Prismatic.h in Headers */, + 4913325213726B1F00DFB46D /* Pulleys.h in Headers */, + 4913325313726B1F00DFB46D /* Pyramid.h in Headers */, + 4913325413726B1F00DFB46D /* RayCast.h in Headers */, + 4913325513726B1F00DFB46D /* Revolute.h in Headers */, + 4913325613726B1F00DFB46D /* Rope.h in Headers */, + 4913325713726B1F00DFB46D /* RopeJoint.h in Headers */, + 4913325813726B1F00DFB46D /* SensorTest.h in Headers */, + 4913325913726B1F00DFB46D /* ShapeEditing.h in Headers */, + 4913325A13726B1F00DFB46D /* SliderCrank.h in Headers */, + 4913325B13726B1F00DFB46D /* SphereStack.h in Headers */, + 4913325C13726B1F00DFB46D /* TheoJansen.h in Headers */, + 4913325D13726B1F00DFB46D /* Tiles.h in Headers */, + 4913325E13726B1F00DFB46D /* TimeOfImpact.h in Headers */, + 4913325F13726B1F00DFB46D /* VaryingFriction.h in Headers */, + 4913326013726B1F00DFB46D /* VaryingRestitution.h in Headers */, + 4913326113726B1F00DFB46D /* VerticalStack.h in Headers */, + 4913326213726B1F00DFB46D /* Web.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 491331681372645C00DFB46D /* box2d-iphone */ = { + isa = PBXNativeTarget; + buildConfigurationList = 491331841372645C00DFB46D /* Build configuration list for PBXNativeTarget "box2d-iphone" */; + buildPhases = ( + 491331651372645C00DFB46D /* Sources */, + 491331661372645C00DFB46D /* Frameworks */, + 491331671372645C00DFB46D /* Resources */, + 491331E71372682200DFB46D /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "box2d-iphone"; + productName = "box2d-iphone"; + productReference = 491331691372645C00DFB46D /* box2d-iphone.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 491331601372645C00DFB46D /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 491331631372645C00DFB46D /* Build configuration list for PBXProject "box2d-iphone" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4913315E1372645C00DFB46D; + productRefGroup = 4913316A1372645C00DFB46D /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 491331B51372661600DFB46D /* Products */; + ProjectRef = 491331B41372661600DFB46D /* box2d-ios.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 491331681372645C00DFB46D /* box2d-iphone */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 491331BC1372661700DFB46D /* libBox2D.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libBox2D.a; + remoteRef = 491331BB1372661700DFB46D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 491331671372645C00DFB46D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 491331AF1372653600DFB46D /* Icon.png in Resources */, + 491331B01372653600DFB46D /* Info.plist in Resources */, + 491331B21372653600DFB46D /* MainWindow.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 491331651372645C00DFB46D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 491331A91372653600DFB46D /* Box2DAppDelegate.mm in Sources */, + 491331AA1372653600DFB46D /* Box2DView.mm in Sources */, + 491331AB1372653600DFB46D /* GLES-Render.mm in Sources */, + 491331AC1372653600DFB46D /* iPhoneTest.mm in Sources */, + 491331AD1372653600DFB46D /* iPhoneTestEntries.mm in Sources */, + 491331AE1372653600DFB46D /* TestEntriesViewController.mm in Sources */, + 491331B11372653600DFB46D /* main.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 491331821372645C00DFB46D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 491331831372645C00DFB46D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 4.3; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + SDKROOT = iphoneos; + }; + name = Release; + }; + 491331851372645C00DFB46D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "box2d-iphone/box2d-iphone-Prefix.pch"; + GCC_VERSION = 4.2; + HEADER_SEARCH_PATHS = "./src/**"; + INFOPLIST_FILE = "box2d-iphone/box2d-iphone-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + ); + OTHER_LDFLAGS = "-Wl,-search_paths_first"; + PREBINDING = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "./src/**"; + USE_HEADERMAP = NO; + WRAPPER_EXTENSION = app; + }; + name = Debug; + }; + 491331861372645C00DFB46D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "box2d-iphone/box2d-iphone-Prefix.pch"; + GCC_VERSION = 4.2; + HEADER_SEARCH_PATHS = "./src/**"; + INFOPLIST_FILE = "box2d-iphone/box2d-iphone-Info.plist"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)\"", + ); + OTHER_LDFLAGS = "-Wl,-search_paths_first"; + PREBINDING = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "./src/**"; + USE_HEADERMAP = NO; + VALIDATE_PRODUCT = YES; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 491331631372645C00DFB46D /* Build configuration list for PBXProject "box2d-iphone" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 491331821372645C00DFB46D /* Debug */, + 491331831372645C00DFB46D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 491331841372645C00DFB46D /* Build configuration list for PBXNativeTarget "box2d-iphone" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 491331851372645C00DFB46D /* Debug */, + 491331861372645C00DFB46D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 491331601372645C00DFB46D /* Project object */; +} diff --git a/libs/box2d/box2d-osx.xcodeproj/project.pbxproj b/libs/box2d/box2d-osx.xcodeproj/project.pbxproj new file mode 100644 index 0000000..5e35787 --- /dev/null +++ b/libs/box2d/box2d-osx.xcodeproj/project.pbxproj @@ -0,0 +1,541 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 49132FCD13725D1000DFB46D /* Box2D.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F8013725D1000DFB46D /* Box2D.h */; }; + 49132FCE13725D1000DFB46D /* b2BroadPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8213725D1000DFB46D /* b2BroadPhase.cpp */; }; + 49132FCF13725D1000DFB46D /* b2BroadPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F8313725D1000DFB46D /* b2BroadPhase.h */; }; + 49132FD013725D1000DFB46D /* b2CollideCircle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8413725D1000DFB46D /* b2CollideCircle.cpp */; }; + 49132FD113725D1000DFB46D /* b2CollidePolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8513725D1000DFB46D /* b2CollidePolygon.cpp */; }; + 49132FD213725D1000DFB46D /* b2Collision.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8613725D1000DFB46D /* b2Collision.cpp */; }; + 49132FD313725D1000DFB46D /* b2Collision.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F8713725D1000DFB46D /* b2Collision.h */; }; + 49132FD413725D1000DFB46D /* b2Distance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8813725D1000DFB46D /* b2Distance.cpp */; }; + 49132FD513725D1000DFB46D /* b2Distance.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F8913725D1000DFB46D /* b2Distance.h */; }; + 49132FD613725D1000DFB46D /* b2DynamicTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8A13725D1000DFB46D /* b2DynamicTree.cpp */; }; + 49132FD713725D1000DFB46D /* b2DynamicTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F8B13725D1000DFB46D /* b2DynamicTree.h */; }; + 49132FD813725D1000DFB46D /* b2TimeOfImpact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8C13725D1000DFB46D /* b2TimeOfImpact.cpp */; }; + 49132FD913725D1000DFB46D /* b2TimeOfImpact.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F8D13725D1000DFB46D /* b2TimeOfImpact.h */; }; + 49132FDA13725D1000DFB46D /* b2CircleShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F8F13725D1000DFB46D /* b2CircleShape.cpp */; }; + 49132FDB13725D1000DFB46D /* b2CircleShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9013725D1000DFB46D /* b2CircleShape.h */; }; + 49132FDC13725D1000DFB46D /* b2PolygonShape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F9113725D1000DFB46D /* b2PolygonShape.cpp */; }; + 49132FDD13725D1000DFB46D /* b2PolygonShape.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9213725D1000DFB46D /* b2PolygonShape.h */; }; + 49132FDE13725D1000DFB46D /* b2Shape.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9313725D1000DFB46D /* b2Shape.h */; }; + 49132FDF13725D1000DFB46D /* b2BlockAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F9513725D1000DFB46D /* b2BlockAllocator.cpp */; }; + 49132FE013725D1000DFB46D /* b2BlockAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9613725D1000DFB46D /* b2BlockAllocator.h */; }; + 49132FE113725D1000DFB46D /* b2Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F9713725D1000DFB46D /* b2Math.cpp */; }; + 49132FE213725D1000DFB46D /* b2Math.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9813725D1000DFB46D /* b2Math.h */; }; + 49132FE313725D1000DFB46D /* b2Settings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F9913725D1000DFB46D /* b2Settings.cpp */; }; + 49132FE413725D1000DFB46D /* b2Settings.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9A13725D1000DFB46D /* b2Settings.h */; }; + 49132FE513725D1000DFB46D /* b2StackAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F9B13725D1000DFB46D /* b2StackAllocator.cpp */; }; + 49132FE613725D1000DFB46D /* b2StackAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9C13725D1000DFB46D /* b2StackAllocator.h */; }; + 49132FE713725D1000DFB46D /* b2Body.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132F9E13725D1000DFB46D /* b2Body.cpp */; }; + 49132FE813725D1000DFB46D /* b2Body.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132F9F13725D1000DFB46D /* b2Body.h */; }; + 49132FE913725D1000DFB46D /* b2ContactManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FA013725D1000DFB46D /* b2ContactManager.cpp */; }; + 49132FEA13725D1000DFB46D /* b2ContactManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FA113725D1000DFB46D /* b2ContactManager.h */; }; + 49132FEB13725D1000DFB46D /* b2Fixture.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FA213725D1000DFB46D /* b2Fixture.cpp */; }; + 49132FEC13725D1000DFB46D /* b2Fixture.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FA313725D1000DFB46D /* b2Fixture.h */; }; + 49132FED13725D1000DFB46D /* b2Island.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FA413725D1000DFB46D /* b2Island.cpp */; }; + 49132FEE13725D1000DFB46D /* b2Island.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FA513725D1000DFB46D /* b2Island.h */; }; + 49132FEF13725D1000DFB46D /* b2TimeStep.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FA613725D1000DFB46D /* b2TimeStep.h */; }; + 49132FF013725D1000DFB46D /* b2World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FA713725D1000DFB46D /* b2World.cpp */; }; + 49132FF113725D1000DFB46D /* b2World.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FA813725D1000DFB46D /* b2World.h */; }; + 49132FF213725D1000DFB46D /* b2WorldCallbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FA913725D1000DFB46D /* b2WorldCallbacks.cpp */; }; + 49132FF313725D1000DFB46D /* b2WorldCallbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FAA13725D1000DFB46D /* b2WorldCallbacks.h */; }; + 49132FF413725D1000DFB46D /* b2CircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FAC13725D1000DFB46D /* b2CircleContact.cpp */; }; + 49132FF513725D1000DFB46D /* b2CircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FAD13725D1000DFB46D /* b2CircleContact.h */; }; + 49132FF613725D1000DFB46D /* b2Contact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FAE13725D1000DFB46D /* b2Contact.cpp */; }; + 49132FF713725D1000DFB46D /* b2Contact.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FAF13725D1000DFB46D /* b2Contact.h */; }; + 49132FF813725D1000DFB46D /* b2ContactSolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FB013725D1000DFB46D /* b2ContactSolver.cpp */; }; + 49132FF913725D1000DFB46D /* b2ContactSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FB113725D1000DFB46D /* b2ContactSolver.h */; }; + 49132FFA13725D1000DFB46D /* b2PolygonAndCircleContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FB213725D1000DFB46D /* b2PolygonAndCircleContact.cpp */; }; + 49132FFB13725D1000DFB46D /* b2PolygonAndCircleContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FB313725D1000DFB46D /* b2PolygonAndCircleContact.h */; }; + 49132FFC13725D1000DFB46D /* b2PolygonContact.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FB413725D1000DFB46D /* b2PolygonContact.cpp */; }; + 49132FFD13725D1000DFB46D /* b2PolygonContact.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FB513725D1000DFB46D /* b2PolygonContact.h */; }; + 49132FFE13725D1000DFB46D /* b2TOISolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FB613725D1000DFB46D /* b2TOISolver.cpp */; }; + 49132FFF13725D1000DFB46D /* b2TOISolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FB713725D1000DFB46D /* b2TOISolver.h */; }; + 4913300013725D1000DFB46D /* b2DistanceJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FB913725D1000DFB46D /* b2DistanceJoint.cpp */; }; + 4913300113725D1000DFB46D /* b2DistanceJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FBA13725D1000DFB46D /* b2DistanceJoint.h */; }; + 4913300213725D1000DFB46D /* b2FrictionJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FBB13725D1000DFB46D /* b2FrictionJoint.cpp */; }; + 4913300313725D1000DFB46D /* b2FrictionJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FBC13725D1000DFB46D /* b2FrictionJoint.h */; }; + 4913300413725D1000DFB46D /* b2GearJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FBD13725D1000DFB46D /* b2GearJoint.cpp */; }; + 4913300513725D1000DFB46D /* b2GearJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FBE13725D1000DFB46D /* b2GearJoint.h */; }; + 4913300613725D1000DFB46D /* b2Joint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FBF13725D1000DFB46D /* b2Joint.cpp */; }; + 4913300713725D1000DFB46D /* b2Joint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FC013725D1000DFB46D /* b2Joint.h */; }; + 4913300813725D1000DFB46D /* b2LineJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FC113725D1000DFB46D /* b2LineJoint.cpp */; }; + 4913300913725D1000DFB46D /* b2LineJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FC213725D1000DFB46D /* b2LineJoint.h */; }; + 4913300A13725D1000DFB46D /* b2MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FC313725D1000DFB46D /* b2MouseJoint.cpp */; }; + 4913300B13725D1000DFB46D /* b2MouseJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FC413725D1000DFB46D /* b2MouseJoint.h */; }; + 4913300C13725D1000DFB46D /* b2PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FC513725D1000DFB46D /* b2PrismaticJoint.cpp */; }; + 4913300D13725D1000DFB46D /* b2PrismaticJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FC613725D1000DFB46D /* b2PrismaticJoint.h */; }; + 4913300E13725D1000DFB46D /* b2PulleyJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FC713725D1000DFB46D /* b2PulleyJoint.cpp */; }; + 4913300F13725D1000DFB46D /* b2PulleyJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FC813725D1000DFB46D /* b2PulleyJoint.h */; }; + 4913301013725D1000DFB46D /* b2RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FC913725D1000DFB46D /* b2RevoluteJoint.cpp */; }; + 4913301113725D1000DFB46D /* b2RevoluteJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FCA13725D1000DFB46D /* b2RevoluteJoint.h */; }; + 4913301213725D1000DFB46D /* b2WeldJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49132FCB13725D1000DFB46D /* b2WeldJoint.cpp */; }; + 4913301313725D1000DFB46D /* b2WeldJoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 49132FCC13725D1000DFB46D /* b2WeldJoint.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 49132F7113725CDD00DFB46D /* Box2D.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = Box2D.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + 49132F7413725CDD00DFB46D /* Box2D-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Box2D-Prefix.pch"; sourceTree = ""; }; + 49132F7513725CDD00DFB46D /* Box2DProj.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Box2DProj.xcconfig; sourceTree = ""; }; + 49132F7613725CDD00DFB46D /* Box2DTarget.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Box2DTarget.xcconfig; sourceTree = ""; }; + 49132F8013725D1000DFB46D /* Box2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = ""; }; + 49132F8213725D1000DFB46D /* b2BroadPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = ""; }; + 49132F8313725D1000DFB46D /* b2BroadPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = ""; }; + 49132F8413725D1000DFB46D /* b2CollideCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = ""; }; + 49132F8513725D1000DFB46D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = ""; }; + 49132F8613725D1000DFB46D /* b2Collision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = ""; }; + 49132F8713725D1000DFB46D /* b2Collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = ""; }; + 49132F8813725D1000DFB46D /* b2Distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = ""; }; + 49132F8913725D1000DFB46D /* b2Distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Distance.h; sourceTree = ""; }; + 49132F8A13725D1000DFB46D /* b2DynamicTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DynamicTree.cpp; sourceTree = ""; }; + 49132F8B13725D1000DFB46D /* b2DynamicTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DynamicTree.h; sourceTree = ""; }; + 49132F8C13725D1000DFB46D /* b2TimeOfImpact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TimeOfImpact.cpp; sourceTree = ""; }; + 49132F8D13725D1000DFB46D /* b2TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeOfImpact.h; sourceTree = ""; }; + 49132F8F13725D1000DFB46D /* b2CircleShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleShape.cpp; sourceTree = ""; }; + 49132F9013725D1000DFB46D /* b2CircleShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = ""; }; + 49132F9113725D1000DFB46D /* b2PolygonShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonShape.cpp; sourceTree = ""; }; + 49132F9213725D1000DFB46D /* b2PolygonShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonShape.h; sourceTree = ""; }; + 49132F9313725D1000DFB46D /* b2Shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Shape.h; sourceTree = ""; }; + 49132F9513725D1000DFB46D /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = ""; }; + 49132F9613725D1000DFB46D /* b2BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BlockAllocator.h; sourceTree = ""; }; + 49132F9713725D1000DFB46D /* b2Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Math.cpp; sourceTree = ""; }; + 49132F9813725D1000DFB46D /* b2Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Math.h; sourceTree = ""; }; + 49132F9913725D1000DFB46D /* b2Settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Settings.cpp; sourceTree = ""; }; + 49132F9A13725D1000DFB46D /* b2Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Settings.h; sourceTree = ""; }; + 49132F9B13725D1000DFB46D /* b2StackAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2StackAllocator.cpp; sourceTree = ""; }; + 49132F9C13725D1000DFB46D /* b2StackAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = ""; }; + 49132F9E13725D1000DFB46D /* b2Body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Body.cpp; sourceTree = ""; }; + 49132F9F13725D1000DFB46D /* b2Body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Body.h; sourceTree = ""; }; + 49132FA013725D1000DFB46D /* b2ContactManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactManager.cpp; sourceTree = ""; }; + 49132FA113725D1000DFB46D /* b2ContactManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactManager.h; sourceTree = ""; }; + 49132FA213725D1000DFB46D /* b2Fixture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Fixture.cpp; sourceTree = ""; }; + 49132FA313725D1000DFB46D /* b2Fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = ""; }; + 49132FA413725D1000DFB46D /* b2Island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = ""; }; + 49132FA513725D1000DFB46D /* b2Island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Island.h; sourceTree = ""; }; + 49132FA613725D1000DFB46D /* b2TimeStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeStep.h; sourceTree = ""; }; + 49132FA713725D1000DFB46D /* b2World.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2World.cpp; sourceTree = ""; }; + 49132FA813725D1000DFB46D /* b2World.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2World.h; sourceTree = ""; }; + 49132FA913725D1000DFB46D /* b2WorldCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WorldCallbacks.cpp; sourceTree = ""; }; + 49132FAA13725D1000DFB46D /* b2WorldCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = ""; }; + 49132FAC13725D1000DFB46D /* b2CircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = ""; }; + 49132FAD13725D1000DFB46D /* b2CircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleContact.h; sourceTree = ""; }; + 49132FAE13725D1000DFB46D /* b2Contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Contact.cpp; sourceTree = ""; }; + 49132FAF13725D1000DFB46D /* b2Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = ""; }; + 49132FB013725D1000DFB46D /* b2ContactSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactSolver.cpp; sourceTree = ""; }; + 49132FB113725D1000DFB46D /* b2ContactSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactSolver.h; sourceTree = ""; }; + 49132FB213725D1000DFB46D /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = ""; }; + 49132FB313725D1000DFB46D /* b2PolygonAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonAndCircleContact.h; sourceTree = ""; }; + 49132FB413725D1000DFB46D /* b2PolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonContact.cpp; sourceTree = ""; }; + 49132FB513725D1000DFB46D /* b2PolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonContact.h; sourceTree = ""; }; + 49132FB613725D1000DFB46D /* b2TOISolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TOISolver.cpp; sourceTree = ""; }; + 49132FB713725D1000DFB46D /* b2TOISolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TOISolver.h; sourceTree = ""; }; + 49132FB913725D1000DFB46D /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = ""; }; + 49132FBA13725D1000DFB46D /* b2DistanceJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DistanceJoint.h; sourceTree = ""; }; + 49132FBB13725D1000DFB46D /* b2FrictionJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2FrictionJoint.cpp; sourceTree = ""; }; + 49132FBC13725D1000DFB46D /* b2FrictionJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2FrictionJoint.h; sourceTree = ""; }; + 49132FBD13725D1000DFB46D /* b2GearJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2GearJoint.cpp; sourceTree = ""; }; + 49132FBE13725D1000DFB46D /* b2GearJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = ""; }; + 49132FBF13725D1000DFB46D /* b2Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Joint.cpp; sourceTree = ""; }; + 49132FC013725D1000DFB46D /* b2Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Joint.h; sourceTree = ""; }; + 49132FC113725D1000DFB46D /* b2LineJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2LineJoint.cpp; sourceTree = ""; }; + 49132FC213725D1000DFB46D /* b2LineJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2LineJoint.h; sourceTree = ""; }; + 49132FC313725D1000DFB46D /* b2MouseJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MouseJoint.cpp; sourceTree = ""; }; + 49132FC413725D1000DFB46D /* b2MouseJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MouseJoint.h; sourceTree = ""; }; + 49132FC513725D1000DFB46D /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = ""; }; + 49132FC613725D1000DFB46D /* b2PrismaticJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PrismaticJoint.h; sourceTree = ""; }; + 49132FC713725D1000DFB46D /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = ""; }; + 49132FC813725D1000DFB46D /* b2PulleyJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PulleyJoint.h; sourceTree = ""; }; + 49132FC913725D1000DFB46D /* b2RevoluteJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2RevoluteJoint.cpp; sourceTree = ""; }; + 49132FCA13725D1000DFB46D /* b2RevoluteJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2RevoluteJoint.h; sourceTree = ""; }; + 49132FCB13725D1000DFB46D /* b2WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WeldJoint.cpp; sourceTree = ""; }; + 49132FCC13725D1000DFB46D /* b2WeldJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 49132F6E13725CDD00DFB46D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 49132EDD13725A9600DFB46D = { + isa = PBXGroup; + children = ( + 49132F7F13725D1000DFB46D /* Box2D */, + 49132F7113725CDD00DFB46D /* Box2D.dylib */, + 49132F7213725CDD00DFB46D /* Box2D */, + ); + sourceTree = ""; + }; + 49132F7213725CDD00DFB46D /* Box2D */ = { + isa = PBXGroup; + children = ( + 49132F7513725CDD00DFB46D /* Box2DProj.xcconfig */, + 49132F7613725CDD00DFB46D /* Box2DTarget.xcconfig */, + 49132F7313725CDD00DFB46D /* Supporting Files */, + ); + path = Box2D; + sourceTree = ""; + }; + 49132F7313725CDD00DFB46D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 49132F7413725CDD00DFB46D /* Box2D-Prefix.pch */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 49132F7F13725D1000DFB46D /* Box2D */ = { + isa = PBXGroup; + children = ( + 49132F8013725D1000DFB46D /* Box2D.h */, + 49132F8113725D1000DFB46D /* Collision */, + 49132F9413725D1000DFB46D /* Common */, + 49132F9D13725D1000DFB46D /* Dynamics */, + ); + name = Box2D; + path = src/Box2D; + sourceTree = ""; + }; + 49132F8113725D1000DFB46D /* Collision */ = { + isa = PBXGroup; + children = ( + 49132F8213725D1000DFB46D /* b2BroadPhase.cpp */, + 49132F8313725D1000DFB46D /* b2BroadPhase.h */, + 49132F8413725D1000DFB46D /* b2CollideCircle.cpp */, + 49132F8513725D1000DFB46D /* b2CollidePolygon.cpp */, + 49132F8613725D1000DFB46D /* b2Collision.cpp */, + 49132F8713725D1000DFB46D /* b2Collision.h */, + 49132F8813725D1000DFB46D /* b2Distance.cpp */, + 49132F8913725D1000DFB46D /* b2Distance.h */, + 49132F8A13725D1000DFB46D /* b2DynamicTree.cpp */, + 49132F8B13725D1000DFB46D /* b2DynamicTree.h */, + 49132F8C13725D1000DFB46D /* b2TimeOfImpact.cpp */, + 49132F8D13725D1000DFB46D /* b2TimeOfImpact.h */, + 49132F8E13725D1000DFB46D /* Shapes */, + ); + path = Collision; + sourceTree = ""; + }; + 49132F8E13725D1000DFB46D /* Shapes */ = { + isa = PBXGroup; + children = ( + 49132F8F13725D1000DFB46D /* b2CircleShape.cpp */, + 49132F9013725D1000DFB46D /* b2CircleShape.h */, + 49132F9113725D1000DFB46D /* b2PolygonShape.cpp */, + 49132F9213725D1000DFB46D /* b2PolygonShape.h */, + 49132F9313725D1000DFB46D /* b2Shape.h */, + ); + path = Shapes; + sourceTree = ""; + }; + 49132F9413725D1000DFB46D /* Common */ = { + isa = PBXGroup; + children = ( + 49132F9513725D1000DFB46D /* b2BlockAllocator.cpp */, + 49132F9613725D1000DFB46D /* b2BlockAllocator.h */, + 49132F9713725D1000DFB46D /* b2Math.cpp */, + 49132F9813725D1000DFB46D /* b2Math.h */, + 49132F9913725D1000DFB46D /* b2Settings.cpp */, + 49132F9A13725D1000DFB46D /* b2Settings.h */, + 49132F9B13725D1000DFB46D /* b2StackAllocator.cpp */, + 49132F9C13725D1000DFB46D /* b2StackAllocator.h */, + ); + path = Common; + sourceTree = ""; + }; + 49132F9D13725D1000DFB46D /* Dynamics */ = { + isa = PBXGroup; + children = ( + 49132F9E13725D1000DFB46D /* b2Body.cpp */, + 49132F9F13725D1000DFB46D /* b2Body.h */, + 49132FA013725D1000DFB46D /* b2ContactManager.cpp */, + 49132FA113725D1000DFB46D /* b2ContactManager.h */, + 49132FA213725D1000DFB46D /* b2Fixture.cpp */, + 49132FA313725D1000DFB46D /* b2Fixture.h */, + 49132FA413725D1000DFB46D /* b2Island.cpp */, + 49132FA513725D1000DFB46D /* b2Island.h */, + 49132FA613725D1000DFB46D /* b2TimeStep.h */, + 49132FA713725D1000DFB46D /* b2World.cpp */, + 49132FA813725D1000DFB46D /* b2World.h */, + 49132FA913725D1000DFB46D /* b2WorldCallbacks.cpp */, + 49132FAA13725D1000DFB46D /* b2WorldCallbacks.h */, + 49132FAB13725D1000DFB46D /* Contacts */, + 49132FB813725D1000DFB46D /* Joints */, + ); + path = Dynamics; + sourceTree = ""; + }; + 49132FAB13725D1000DFB46D /* Contacts */ = { + isa = PBXGroup; + children = ( + 49132FAC13725D1000DFB46D /* b2CircleContact.cpp */, + 49132FAD13725D1000DFB46D /* b2CircleContact.h */, + 49132FAE13725D1000DFB46D /* b2Contact.cpp */, + 49132FAF13725D1000DFB46D /* b2Contact.h */, + 49132FB013725D1000DFB46D /* b2ContactSolver.cpp */, + 49132FB113725D1000DFB46D /* b2ContactSolver.h */, + 49132FB213725D1000DFB46D /* b2PolygonAndCircleContact.cpp */, + 49132FB313725D1000DFB46D /* b2PolygonAndCircleContact.h */, + 49132FB413725D1000DFB46D /* b2PolygonContact.cpp */, + 49132FB513725D1000DFB46D /* b2PolygonContact.h */, + 49132FB613725D1000DFB46D /* b2TOISolver.cpp */, + 49132FB713725D1000DFB46D /* b2TOISolver.h */, + ); + path = Contacts; + sourceTree = ""; + }; + 49132FB813725D1000DFB46D /* Joints */ = { + isa = PBXGroup; + children = ( + 49132FB913725D1000DFB46D /* b2DistanceJoint.cpp */, + 49132FBA13725D1000DFB46D /* b2DistanceJoint.h */, + 49132FBB13725D1000DFB46D /* b2FrictionJoint.cpp */, + 49132FBC13725D1000DFB46D /* b2FrictionJoint.h */, + 49132FBD13725D1000DFB46D /* b2GearJoint.cpp */, + 49132FBE13725D1000DFB46D /* b2GearJoint.h */, + 49132FBF13725D1000DFB46D /* b2Joint.cpp */, + 49132FC013725D1000DFB46D /* b2Joint.h */, + 49132FC113725D1000DFB46D /* b2LineJoint.cpp */, + 49132FC213725D1000DFB46D /* b2LineJoint.h */, + 49132FC313725D1000DFB46D /* b2MouseJoint.cpp */, + 49132FC413725D1000DFB46D /* b2MouseJoint.h */, + 49132FC513725D1000DFB46D /* b2PrismaticJoint.cpp */, + 49132FC613725D1000DFB46D /* b2PrismaticJoint.h */, + 49132FC713725D1000DFB46D /* b2PulleyJoint.cpp */, + 49132FC813725D1000DFB46D /* b2PulleyJoint.h */, + 49132FC913725D1000DFB46D /* b2RevoluteJoint.cpp */, + 49132FCA13725D1000DFB46D /* b2RevoluteJoint.h */, + 49132FCB13725D1000DFB46D /* b2WeldJoint.cpp */, + 49132FCC13725D1000DFB46D /* b2WeldJoint.h */, + ); + path = Joints; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 49132F6F13725CDD00DFB46D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 49132FCD13725D1000DFB46D /* Box2D.h in Headers */, + 49132FCF13725D1000DFB46D /* b2BroadPhase.h in Headers */, + 49132FD313725D1000DFB46D /* b2Collision.h in Headers */, + 49132FD513725D1000DFB46D /* b2Distance.h in Headers */, + 49132FD713725D1000DFB46D /* b2DynamicTree.h in Headers */, + 49132FD913725D1000DFB46D /* b2TimeOfImpact.h in Headers */, + 49132FDB13725D1000DFB46D /* b2CircleShape.h in Headers */, + 49132FDD13725D1000DFB46D /* b2PolygonShape.h in Headers */, + 49132FDE13725D1000DFB46D /* b2Shape.h in Headers */, + 49132FE013725D1000DFB46D /* b2BlockAllocator.h in Headers */, + 49132FE213725D1000DFB46D /* b2Math.h in Headers */, + 49132FE413725D1000DFB46D /* b2Settings.h in Headers */, + 49132FE613725D1000DFB46D /* b2StackAllocator.h in Headers */, + 49132FE813725D1000DFB46D /* b2Body.h in Headers */, + 49132FEA13725D1000DFB46D /* b2ContactManager.h in Headers */, + 49132FEC13725D1000DFB46D /* b2Fixture.h in Headers */, + 49132FEE13725D1000DFB46D /* b2Island.h in Headers */, + 49132FEF13725D1000DFB46D /* b2TimeStep.h in Headers */, + 49132FF113725D1000DFB46D /* b2World.h in Headers */, + 49132FF313725D1000DFB46D /* b2WorldCallbacks.h in Headers */, + 49132FF513725D1000DFB46D /* b2CircleContact.h in Headers */, + 49132FF713725D1000DFB46D /* b2Contact.h in Headers */, + 49132FF913725D1000DFB46D /* b2ContactSolver.h in Headers */, + 49132FFB13725D1000DFB46D /* b2PolygonAndCircleContact.h in Headers */, + 49132FFD13725D1000DFB46D /* b2PolygonContact.h in Headers */, + 49132FFF13725D1000DFB46D /* b2TOISolver.h in Headers */, + 4913300113725D1000DFB46D /* b2DistanceJoint.h in Headers */, + 4913300313725D1000DFB46D /* b2FrictionJoint.h in Headers */, + 4913300513725D1000DFB46D /* b2GearJoint.h in Headers */, + 4913300713725D1000DFB46D /* b2Joint.h in Headers */, + 4913300913725D1000DFB46D /* b2LineJoint.h in Headers */, + 4913300B13725D1000DFB46D /* b2MouseJoint.h in Headers */, + 4913300D13725D1000DFB46D /* b2PrismaticJoint.h in Headers */, + 4913300F13725D1000DFB46D /* b2PulleyJoint.h in Headers */, + 4913301113725D1000DFB46D /* b2RevoluteJoint.h in Headers */, + 4913301313725D1000DFB46D /* b2WeldJoint.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 49132F7013725CDD00DFB46D /* Box2D */ = { + isa = PBXNativeTarget; + buildConfigurationList = 49132F7C13725CDD00DFB46D /* Build configuration list for PBXNativeTarget "Box2D" */; + buildPhases = ( + 49132F6D13725CDD00DFB46D /* Sources */, + 49132F6E13725CDD00DFB46D /* Frameworks */, + 49132F6F13725CDD00DFB46D /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Box2D; + productName = Box2D; + productReference = 49132F7113725CDD00DFB46D /* Box2D.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 49132EDF13725A9600DFB46D /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 49132EE213725A9600DFB46D /* Build configuration list for PBXProject "box2d" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 49132EDD13725A9600DFB46D; + productRefGroup = 49132EDD13725A9600DFB46D; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 49132F7013725CDD00DFB46D /* Box2D */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 49132F6D13725CDD00DFB46D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 49132FCE13725D1000DFB46D /* b2BroadPhase.cpp in Sources */, + 49132FD013725D1000DFB46D /* b2CollideCircle.cpp in Sources */, + 49132FD113725D1000DFB46D /* b2CollidePolygon.cpp in Sources */, + 49132FD213725D1000DFB46D /* b2Collision.cpp in Sources */, + 49132FD413725D1000DFB46D /* b2Distance.cpp in Sources */, + 49132FD613725D1000DFB46D /* b2DynamicTree.cpp in Sources */, + 49132FD813725D1000DFB46D /* b2TimeOfImpact.cpp in Sources */, + 49132FDA13725D1000DFB46D /* b2CircleShape.cpp in Sources */, + 49132FDC13725D1000DFB46D /* b2PolygonShape.cpp in Sources */, + 49132FDF13725D1000DFB46D /* b2BlockAllocator.cpp in Sources */, + 49132FE113725D1000DFB46D /* b2Math.cpp in Sources */, + 49132FE313725D1000DFB46D /* b2Settings.cpp in Sources */, + 49132FE513725D1000DFB46D /* b2StackAllocator.cpp in Sources */, + 49132FE713725D1000DFB46D /* b2Body.cpp in Sources */, + 49132FE913725D1000DFB46D /* b2ContactManager.cpp in Sources */, + 49132FEB13725D1000DFB46D /* b2Fixture.cpp in Sources */, + 49132FED13725D1000DFB46D /* b2Island.cpp in Sources */, + 49132FF013725D1000DFB46D /* b2World.cpp in Sources */, + 49132FF213725D1000DFB46D /* b2WorldCallbacks.cpp in Sources */, + 49132FF413725D1000DFB46D /* b2CircleContact.cpp in Sources */, + 49132FF613725D1000DFB46D /* b2Contact.cpp in Sources */, + 49132FF813725D1000DFB46D /* b2ContactSolver.cpp in Sources */, + 49132FFA13725D1000DFB46D /* b2PolygonAndCircleContact.cpp in Sources */, + 49132FFC13725D1000DFB46D /* b2PolygonContact.cpp in Sources */, + 49132FFE13725D1000DFB46D /* b2TOISolver.cpp in Sources */, + 4913300013725D1000DFB46D /* b2DistanceJoint.cpp in Sources */, + 4913300213725D1000DFB46D /* b2FrictionJoint.cpp in Sources */, + 4913300413725D1000DFB46D /* b2GearJoint.cpp in Sources */, + 4913300613725D1000DFB46D /* b2Joint.cpp in Sources */, + 4913300813725D1000DFB46D /* b2LineJoint.cpp in Sources */, + 4913300A13725D1000DFB46D /* b2MouseJoint.cpp in Sources */, + 4913300C13725D1000DFB46D /* b2PrismaticJoint.cpp in Sources */, + 4913300E13725D1000DFB46D /* b2PulleyJoint.cpp in Sources */, + 4913301013725D1000DFB46D /* b2RevoluteJoint.cpp in Sources */, + 4913301213725D1000DFB46D /* b2WeldJoint.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 49132EE413725A9600DFB46D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Debug; + }; + 49132EE513725A9600DFB46D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + }; + name = Release; + }; + 49132F7D13725CDD00DFB46D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = DEBUG; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_VERSION = 4.2; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "./src/**"; + }; + name = Debug; + }; + 49132F7E13725CDD00DFB46D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_VERSION = 4.2; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.6; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + USER_HEADER_SEARCH_PATHS = "./src/**"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 49132EE213725A9600DFB46D /* Build configuration list for PBXProject "box2d" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 49132EE413725A9600DFB46D /* Debug */, + 49132EE513725A9600DFB46D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 49132F7C13725CDD00DFB46D /* Build configuration list for PBXNativeTarget "Box2D" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 49132F7D13725CDD00DFB46D /* Debug */, + 49132F7E13725CDD00DFB46D /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = 49132EDF13725A9600DFB46D /* Project object */; +} diff --git a/libs/box2d/iPhone/Box2D_Prefix.pch b/libs/box2d/iPhone/Box2D_Prefix.pch new file mode 100644 index 0000000..12c45d7 --- /dev/null +++ b/libs/box2d/iPhone/Box2D_Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'Box2D' target in the 'Box2D' project +// + +#ifdef __OBJC__ +#import +#import +#endif diff --git a/libs/box2d/iPhone/Classes/Box2DAppDelegate.h b/libs/box2d/iPhone/Classes/Box2DAppDelegate.h new file mode 100644 index 0000000..f081ba3 --- /dev/null +++ b/libs/box2d/iPhone/Classes/Box2DAppDelegate.h @@ -0,0 +1,24 @@ +// +// Box2DAppDelegate.h +// Box2D +// +// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +// + +#import +#import "TestEntriesViewController.h" +#import "Delegates.h" + +@class Box2DView; + +@interface Box2DAppDelegate : NSObject { + UIWindow *window; + Box2DView *glView; + TestEntriesViewController *testEntriesView; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; +@property (nonatomic, retain) IBOutlet Box2DView *glView; + +@end + diff --git a/libs/box2d/iPhone/Classes/Box2DAppDelegate.mm b/libs/box2d/iPhone/Classes/Box2DAppDelegate.mm new file mode 100644 index 0000000..e04a09e --- /dev/null +++ b/libs/box2d/iPhone/Classes/Box2DAppDelegate.mm @@ -0,0 +1,62 @@ +// +// Box2DAppDelegate.m +// Box2D +// +// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +// + +#import +#import "Box2DAppDelegate.h" +#import "Box2DView.h" + +@implementation Box2DAppDelegate + +@synthesize window; +@synthesize glView; + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + [application setStatusBarHidden:true]; + + [glView removeFromSuperview]; + + glView.animationInterval = 1.0 / 60.0; + + testEntriesView=[[TestEntriesViewController alloc] initWithStyle:UITableViewStylePlain]; + [testEntriesView setDelegate:self]; + [glView setDelegate:self]; + + [window addSubview:[testEntriesView view]]; +} + +-(void) selectTest:(int) testIndex +{ + [[testEntriesView view] removeFromSuperview]; + [window addSubview:glView]; + [glView startAnimation]; + [glView selectTestEntry:testIndex]; +} + +-(void) leaveTest +{ + [glView stopAnimation]; + [glView removeFromSuperview]; + [window addSubview:[testEntriesView view]]; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + glView.animationInterval = 1.0 / 5.0; +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + glView.animationInterval = 1.0 / 60.0; +} + + +- (void)dealloc { + [window release]; + [glView release]; + [super dealloc]; +} + +@end diff --git a/libs/box2d/iPhone/Classes/Box2DView.h b/libs/box2d/iPhone/Classes/Box2DView.h new file mode 100644 index 0000000..81d50b3 --- /dev/null +++ b/libs/box2d/iPhone/Classes/Box2DView.h @@ -0,0 +1,63 @@ +// +// Box2DView.h +// Box2D OpenGL View +// +// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +// + + +#import +#import +#import +#import + +#import "iPhoneTest.h" +#import "Delegates.h" + +/* +This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. +The view content is basically an EAGL surface you render your OpenGL scene into. +Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. +*/ +@interface Box2DView : UIView { + +@private + /* The pixel dimensions of the backbuffer */ + GLint backingWidth; + GLint backingHeight; + + EAGLContext *context; + + /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ + GLuint viewRenderbuffer, viewFramebuffer; + + /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */ + GLuint depthRenderbuffer; + + NSTimer *animationTimer; + NSTimeInterval animationInterval; + + TestEntry* entry; + Test* test; + + // Position offset and scale + float sceneScale; + CGPoint positionOffset; + CGPoint lastWorldTouch; + CGPoint lastScreenTouch; + + bool panning; + int doubleClickValidCountdown; + + id _delegate; + +} +@property(assign) id delegate; +@property NSTimeInterval animationInterval; + +- (void)startAnimation; +- (void)stopAnimation; +- (void)drawView; +-(void) selectTestEntry:(int) testIndex; + +@end diff --git a/libs/box2d/iPhone/Classes/Box2DView.mm b/libs/box2d/iPhone/Classes/Box2DView.mm new file mode 100644 index 0000000..edbf9ef --- /dev/null +++ b/libs/box2d/iPhone/Classes/Box2DView.mm @@ -0,0 +1,299 @@ +// +// Box2DView.mm +// Box2D OpenGL View +// +// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +// + +#import +#import + +#import "Box2DView.h" + +#define USE_DEPTH_BUFFER 0 +#define kAccelerometerFrequency 30 +#define FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK 10 + +Settings settings; + +// A class extension to declare private methods +@interface Box2DView () + +@property (nonatomic, retain) EAGLContext *context; +@property (nonatomic, assign) NSTimer *animationTimer; + +- (BOOL) createFramebuffer; +- (void) destroyFramebuffer; + +@end + + +@implementation Box2DView + +@synthesize context; +@synthesize animationTimer; +@synthesize animationInterval; +@synthesize delegate=_delegate; + +// You must implement this method ++ (Class)layerClass { + return [CAEAGLLayer class]; +} + + +//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: +- (id)initWithCoder:(NSCoder*)coder { + + if ((self = [super initWithCoder:coder])) { + // Get the layer + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + + eaglLayer.opaque = YES; + eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; + + context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; + + if (!context || ![EAGLContext setCurrentContext:context]) { + [self release]; + return nil; + } + + animationInterval = 1.0 / 60.0; + sceneScale=10.0f; + positionOffset=CGPointMake(0, 0); + lastWorldTouch=CGPointMake(0, 0); + + [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)]; + [[UIAccelerometer sharedAccelerometer] setDelegate:self]; + + //[self setMultipleTouchEnabled:YES]; + } + + + return self; +} + +-(void) selectTestEntry:(int) testIndex +{ + // Destroy existing scene + delete test; + + entry = g_testEntries + testIndex; + test = entry->createFcn(); + + doubleClickValidCountdown=0; + + sceneScale=10.0f; + positionOffset=CGPointMake(0, 0); + lastWorldTouch=CGPointMake(0, 0); +} + + + +- (void)drawView { + + + + if (doubleClickValidCountdown>0) doubleClickValidCountdown--; + + [EAGLContext setCurrentContext:context]; + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glViewport(0, 0, backingWidth, backingHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glOrthof(-sceneScale, sceneScale, -sceneScale*1.5f, sceneScale*1.5f, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(positionOffset.x, positionOffset.y,0); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnableClientState(GL_VERTEX_ARRAY); + + test->Step(&settings); + + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context presentRenderbuffer:GL_RENDERBUFFER_OES]; +} + + +- (void)layoutSubviews { + [EAGLContext setCurrentContext:context]; + [self destroyFramebuffer]; + [self createFramebuffer]; + [self drawView]; +} + + +- (BOOL)createFramebuffer { + + glGenFramebuffersOES(1, &viewFramebuffer); + glGenRenderbuffersOES(1, &viewRenderbuffer); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); + [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); + + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + if (USE_DEPTH_BUFFER) { + glGenRenderbuffersOES(1, &depthRenderbuffer); + glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); + glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); + } + + if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { + NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + return NO; + } + + return YES; +} + + +- (void)destroyFramebuffer { + + glDeleteFramebuffersOES(1, &viewFramebuffer); + viewFramebuffer = 0; + glDeleteRenderbuffersOES(1, &viewRenderbuffer); + viewRenderbuffer = 0; + + if(depthRenderbuffer) { + glDeleteRenderbuffersOES(1, &depthRenderbuffer); + depthRenderbuffer = 0; + } +} + + +- (void)startAnimation { + self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES]; +} + + +- (void)stopAnimation { + self.animationTimer = nil; +} + + +- (void)setAnimationTimer:(NSTimer *)newTimer { + [animationTimer invalidate]; + animationTimer = newTimer; +} + + +- (void)setAnimationInterval:(NSTimeInterval)interval { + + animationInterval = interval; + if (animationTimer) { + [self stopAnimation]; + [self startAnimation]; + } +} + + +- (void)dealloc { + + [self stopAnimation]; + + if ([EAGLContext currentContext] == context) { + [EAGLContext setCurrentContext:nil]; + } + + [context release]; + [super dealloc]; +} + +-(CGPoint) screenSpaceToWorldSpace:(CGPoint) screenLocation +{ + screenLocation.x-=160; + screenLocation.y-=240; + screenLocation.x/=160; + screenLocation.y/=160; + screenLocation.x*=sceneScale; + screenLocation.y*=-sceneScale; + + screenLocation.x-=positionOffset.x; + screenLocation.y-=positionOffset.y; + return screenLocation; +} + +- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event +{ + + if (doubleClickValidCountdown>0) + { + [_delegate leaveTest]; + return; + } + + doubleClickValidCountdown=FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK; + + + panning=false; + for (UITouch *touch in touches) + { + CGPoint touchLocation=[touch locationInView:self]; + CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation]; + //printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y); + lastScreenTouch=touchLocation; + lastWorldTouch=worldPosition; + b2Vec2 p = b2Vec2(lastWorldTouch.x,lastWorldTouch.y); + test->MouseDown(p); + //test->ShiftMouseDown(p); + + if (!test->m_mouseJoint) panning=true; + } +} + +- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event +{ + for (UITouch *touch in touches) + { + CGPoint touchLocation=[touch locationInView:self]; + CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation]; + //printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y); + + + CGPoint screenDistanceMoved=CGPointMake(touchLocation.x-lastScreenTouch.x,touchLocation.y-lastScreenTouch.y); + if (panning) + { + screenDistanceMoved.x/=160; + screenDistanceMoved.y/=160; + screenDistanceMoved.x*=sceneScale; + screenDistanceMoved.y*=-sceneScale; + positionOffset.x+=screenDistanceMoved.x; + positionOffset.y+=screenDistanceMoved.y; + } + + lastScreenTouch=touchLocation; + lastWorldTouch=worldPosition; + test->MouseMove(b2Vec2(lastWorldTouch.x,lastWorldTouch.y)); + + } +} +- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event +{ + test->MouseUp(b2Vec2(lastWorldTouch.x,lastWorldTouch.y)); +} + +- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration +{ + // Only run for valid values + if (acceleration.y!=0 && acceleration.x!=0) + { + if (test) test->SetGravity(acceleration.x,acceleration.y); + } +} + +@end diff --git a/libs/box2d/iPhone/Classes/Delegates.h b/libs/box2d/iPhone/Classes/Delegates.h new file mode 100644 index 0000000..b4b7976 --- /dev/null +++ b/libs/box2d/iPhone/Classes/Delegates.h @@ -0,0 +1,14 @@ +/* + * Delegates.h + * Box2D + * + * Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com + * + * + */ + +@protocol TestSelectDelegate + -(void) selectTest:(int) testIndex; + -(void) leaveTest; + +@end \ No newline at end of file diff --git a/libs/box2d/iPhone/Classes/GLES-Render.h b/libs/box2d/iPhone/Classes/GLES-Render.h new file mode 100644 index 0000000..8e02a74 --- /dev/null +++ b/libs/box2d/iPhone/Classes/GLES-Render.h @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +* +* 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 RENDER_H +#define RENDER_H + +#import +#import +#import +#import + +#include + +struct b2AABB; + +// This class implements debug drawing callbacks that are invoked +// inside b2World::Step. +class GLESDebugDraw : public b2Draw +{ +public: + void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + + void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color); + + void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color); + + void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color); + + void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color); + + void DrawTransform(const b2Transform& xf); + + void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color); + + void DrawString(int x, int y, const char* string, ...); + + void DrawAABB(b2AABB* aabb, const b2Color& color); +}; + + +#endif diff --git a/libs/box2d/iPhone/Classes/GLES-Render.mm b/libs/box2d/iPhone/Classes/GLES-Render.mm new file mode 100644 index 0000000..abf5c57 --- /dev/null +++ b/libs/box2d/iPhone/Classes/GLES-Render.mm @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +* +* 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 "GLES-Render.h" + + +#include +#include + +#include + +void GLESDebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) +{ + glColor4f(color.r, color.g, color.b,1); + glVertexPointer(2, GL_FLOAT, 0, vertices); + glDrawArrays(GL_LINE_LOOP, 0, vertexCount); +} + +void GLESDebugDraw::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color) +{ + glVertexPointer(2, GL_FLOAT, 0, vertices); + + glColor4f(color.r, color.g, color.b,0.5f); + glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount); + + glColor4f(color.r, color.g, color.b,1); + glDrawArrays(GL_LINE_LOOP, 0, vertexCount); +} + +void GLESDebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color) +{ + const float32 k_segments = 16.0f; + int vertexCount=16; + const float32 k_increment = 2.0f * b2_pi / k_segments; + float32 theta = 0.0f; + + GLfloat glVertices[vertexCount*2]; + for (int32 i = 0; i < k_segments; ++i) + { + b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta)); + glVertices[i*2]=v.x; + glVertices[i*2+1]=v.y; + theta += k_increment; + } + + glColor4f(color.r, color.g, color.b,1); + glVertexPointer(2, GL_FLOAT, 0, glVertices); + + glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount); +} + +void GLESDebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) +{ + const float32 k_segments = 16.0f; + int vertexCount=16; + const float32 k_increment = 2.0f * b2_pi / k_segments; + float32 theta = 0.0f; + + GLfloat glVertices[vertexCount*2]; + for (int32 i = 0; i < k_segments; ++i) + { + b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta)); + glVertices[i*2]=v.x; + glVertices[i*2+1]=v.y; + theta += k_increment; + } + + glColor4f(color.r, color.g, color.b,0.5f); + glVertexPointer(2, GL_FLOAT, 0, glVertices); + glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount); + glColor4f(color.r, color.g, color.b,1); + glDrawArrays(GL_LINE_LOOP, 0, vertexCount); + + // Draw the axis line + DrawSegment(center,center+radius*axis,color); +} + +void GLESDebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) +{ + glColor4f(color.r, color.g, color.b,1); + GLfloat glVertices[] = { + p1.x,p1.y,p2.x,p2.y + }; + glVertexPointer(2, GL_FLOAT, 0, glVertices); + glDrawArrays(GL_LINES, 0, 2); +} + +void GLESDebugDraw::DrawTransform(const b2Transform& xf) +{ + b2Vec2 p1 = xf.position, p2; + const float32 k_axisScale = 0.4f; + + p2 = p1 + k_axisScale * xf.R.col1; + DrawSegment(p1,p2,b2Color(1,0,0)); + + p2 = p1 + k_axisScale * xf.R.col2; + DrawSegment(p1,p2,b2Color(0,1,0)); +} + +void GLESDebugDraw::DrawPoint(const b2Vec2& p, float32 size, const b2Color& color) +{ + glColor4f(color.r, color.g, color.b,1); + glPointSize(size); + GLfloat glVertices[] = { + p.x,p.y + }; + glVertexPointer(2, GL_FLOAT, 0, glVertices); + glDrawArrays(GL_POINTS, 0, 1); + glPointSize(1.0f); +} + +void GLESDebugDraw::DrawString(int x, int y, const char *string, ...) +{ + + /* Unsupported as yet. Could replace with bitmap font renderer at a later date */ +} + +void GLESDebugDraw::DrawAABB(b2AABB* aabb, const b2Color& c) +{ + + glColor4f(c.r, c.g, c.b,1); + + GLfloat glVertices[] = { + aabb->lowerBound.x, aabb->lowerBound.y, + aabb->upperBound.x, aabb->lowerBound.y, + aabb->upperBound.x, aabb->upperBound.y, + aabb->lowerBound.x, aabb->upperBound.y + }; + glVertexPointer(2, GL_FLOAT, 0, glVertices); + glDrawArrays(GL_LINE_LOOP, 0, 8); + +} diff --git a/libs/box2d/iPhone/Classes/TestEntriesViewController.h b/libs/box2d/iPhone/Classes/TestEntriesViewController.h new file mode 100644 index 0000000..d28a655 --- /dev/null +++ b/libs/box2d/iPhone/Classes/TestEntriesViewController.h @@ -0,0 +1,19 @@ +// +// TestEntriesViewController.h +// Box2D +// +// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +// + +#import +#import "iPhoneTest.h" +#import "Delegates.h" + +@interface TestEntriesViewController : UITableViewController { + int32 testCount; + id _delegate; +} + +@property(assign) id delegate; + +@end diff --git a/libs/box2d/iPhone/Classes/TestEntriesViewController.mm b/libs/box2d/iPhone/Classes/TestEntriesViewController.mm new file mode 100644 index 0000000..bb8e1ac --- /dev/null +++ b/libs/box2d/iPhone/Classes/TestEntriesViewController.mm @@ -0,0 +1,75 @@ +// +// TestEntriesViewController.m +// Box2D +// +// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +// + +#import "TestEntriesViewController.h" + + +@implementation TestEntriesViewController + +@synthesize delegate=_delegate; + +- (id)initWithStyle:(UITableViewStyle)style { + if (self = [super initWithStyle:style]) { + testCount = 0; + TestEntry* e = g_testEntries; + while (e->createFcn) + { + ++testCount; + ++e; + } + } + return self; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview + // Release anything that's not essential, such as cached data +} + +#pragma mark Table view methods + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + + +// Customize the number of rows in the table view. +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return testCount; +} + + +// Customize the appearance of table view cells. +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + + static NSString *CellIdentifier = @"Cell"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; + } + + // Set up the cell... + TestEntry* e = g_testEntries; + e+=indexPath.row; + + cell.textLabel.text = [NSString stringWithUTF8String:e->name]; + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [_delegate selectTest:indexPath.row]; +} + +- (void)dealloc { + [super dealloc]; +} + + +@end + diff --git a/libs/box2d/iPhone/Classes/iPhoneTest.h b/libs/box2d/iPhone/Classes/iPhoneTest.h new file mode 100644 index 0000000..c7c767a --- /dev/null +++ b/libs/box2d/iPhone/Classes/iPhoneTest.h @@ -0,0 +1,189 @@ +/* +* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com +* +* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +* +* 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 TEST_H +#define TEST_H + +#import +#include +#include "GLES-Render.h" + +#include + +class Test; +struct Settings; + +typedef Test* TestCreateFcn(); + +#define RAND_LIMIT 32767 + +/// Random number in range [-1,1] +inline float32 RandomFloat() +{ + float32 r = (float32)(rand() & (RAND_LIMIT)); + r /= RAND_LIMIT; + r = 2.0f * r - 1.0f; + return r; +} + +/// Random floating point number in range [lo, hi] +inline float32 RandomFloat(float32 lo, float32 hi) +{ + float32 r = (float32)(rand() & (RAND_LIMIT)); + r /= RAND_LIMIT; + r = (hi - lo) * r + lo; + return r; +} + +/// Test settings. Some can be controlled in the GUI. +struct Settings +{ + Settings() : + viewCenter(0.0f, 20.0f), + hz(60.0f), + velocityIterations(8), + positionIterations(3), + drawShapes(1), + drawJoints(1), + drawAABBs(0), + drawPairs(0), + drawContactPoints(0), + drawContactNormals(0), + drawContactForces(0), + drawFrictionForces(0), + drawCOMs(0), + drawStats(0), + enableWarmStarting(1), + enableContinuous(1), + enableSubStepping(0), + pause(0), + singleStep(0) + {} + + b2Vec2 viewCenter; + float32 hz; + int32 velocityIterations; + int32 positionIterations; + int32 drawShapes; + int32 drawJoints; + int32 drawAABBs; + int32 drawPairs; + int32 drawContactPoints; + int32 drawContactNormals; + int32 drawContactForces; + int32 drawFrictionForces; + int32 drawCOMs; + int32 drawStats; + int32 enableWarmStarting; + int32 enableContinuous; + int32 enableSubStepping; + int32 pause; + int32 singleStep; +}; + +struct TestEntry +{ + const char *name; + TestCreateFcn *createFcn; +}; + +extern TestEntry g_testEntries[]; +// This is called when a joint in the world is implicitly destroyed +// because an attached body is destroyed. This gives us a chance to +// nullify the mouse joint. +class DestructionListener : public b2DestructionListener + { + public: + void SayGoodbye(b2Fixture* fixture) { B2_NOT_USED(fixture); } + void SayGoodbye(b2Joint* joint); + + Test* test; + }; + +const int32 k_maxContactPoints = 2048; + +struct ContactPoint +{ + b2Fixture* fixtureA; + b2Fixture* fixtureB; + b2Vec2 normal; + b2Vec2 position; + b2PointState state; +}; + +class Test : public b2ContactListener + { + public: + + Test(); + virtual ~Test(); + + void SetGravity(float x,float y); + void SetTextLine(int32 line) { m_textLine = line; } + void DrawTitle(int x, int y, const char *string); + virtual void Step(Settings* settings); + virtual void Keyboard(unsigned char key) { B2_NOT_USED(key); } + void ShiftMouseDown(const b2Vec2& p); + virtual void MouseDown(const b2Vec2& p); + virtual void MouseUp(const b2Vec2& p); + void MouseMove(const b2Vec2& p); + void LaunchBomb(); + void LaunchBomb(const b2Vec2& position, const b2Vec2& velocity); + + void SpawnBomb(const b2Vec2& worldPt); + void CompleteBombSpawn(const b2Vec2& p); + + // Let derived tests know that a joint was destroyed. + virtual void JointDestroyed(b2Joint* joint) { B2_NOT_USED(joint); } + + // Callbacks for derived classes. + virtual void BeginContact(b2Contact* contact) { B2_NOT_USED(contact); } + virtual void EndContact(b2Contact* contact) { B2_NOT_USED(contact); } + virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold); + virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) + { + B2_NOT_USED(contact); + B2_NOT_USED(impulse); + } + + protected: + friend class DestructionListener; + friend class BoundaryListener; + friend class ContactListener; + + b2Body* m_groundBody; + b2AABB m_worldAABB; + ContactPoint m_points[k_maxContactPoints]; + int32 m_pointCount; + DestructionListener m_destructionListener; + GLESDebugDraw m_debugDraw; + int32 m_textLine; + b2World* m_world; + b2Body* m_bomb; + b2MouseJoint* m_mouseJoint; + b2Vec2 m_bombSpawnPoint; + bool m_bombSpawning; + b2Vec2 m_mouseWorld; + int32 m_stepCount; + }; + +#endif diff --git a/libs/box2d/iPhone/Classes/iPhoneTest.mm b/libs/box2d/iPhone/Classes/iPhoneTest.mm new file mode 100644 index 0000000..faf08df --- /dev/null +++ b/libs/box2d/iPhone/Classes/iPhoneTest.mm @@ -0,0 +1,415 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com +* +* 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 "iPhoneTest.h" +#include "GLES-Render.h" + +#include + +void DestructionListener::SayGoodbye(b2Joint* joint) +{ + if (test->m_mouseJoint == joint) + { + test->m_mouseJoint = NULL; + } + else + { + test->JointDestroyed(joint); + } +} + +Test::Test() +: m_debugDraw() +{ + b2Vec2 gravity; + gravity.Set(0.0f, -10.0f); + bool doSleep = true; + m_world = new b2World(gravity, doSleep); + m_bomb = NULL; + m_textLine = 30; + m_mouseJoint = NULL; + m_pointCount = 0; + + m_destructionListener.test = this; + m_world->SetDestructionListener(&m_destructionListener); + m_world->SetContactListener(this); + m_world->SetDebugDraw(&m_debugDraw); + + m_bombSpawning = false; + + m_stepCount = 0; + + b2BodyDef bodyDef; + m_groundBody = m_world->CreateBody(&bodyDef); +} + +Test::~Test() +{ + // By deleting the world, we delete the bomb, mouse joint, etc. + delete m_world; + m_world = NULL; + +} + +void Test::SetGravity( float x, float y) +{ + float tVectorLength=sqrt(x*x+y*y); + float newGravityX=9.81f*x/tVectorLength; + float newGravityY=9.81f*y/tVectorLength; + m_world->SetGravity(b2Vec2(newGravityX,newGravityY)); +} + +void Test::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) +{ + const b2Manifold* manifold = contact->GetManifold(); + + if (manifold->pointCount == 0) + { + return; + } + + b2Fixture* fixtureA = contact->GetFixtureA(); + b2Fixture* fixtureB = contact->GetFixtureB(); + + b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints]; + b2GetPointStates(state1, state2, oldManifold, manifold); + + b2WorldManifold worldManifold; + contact->GetWorldManifold(&worldManifold); + + for (int32 i = 0; i < manifold->pointCount && m_pointCount < k_maxContactPoints; ++i) + { + ContactPoint* cp = m_points + m_pointCount; + cp->fixtureA = fixtureA; + cp->fixtureB = fixtureB; + cp->position = worldManifold.points[i]; + cp->normal = worldManifold.normal; + cp->state = state2[i]; + ++m_pointCount; + } +} + +void Test::DrawTitle(int x, int y, const char *string) +{ + m_debugDraw.DrawString(x, y, string); +} + +class QueryCallback : public b2QueryCallback +{ +public: + QueryCallback(const b2Vec2& point) + { + m_point = point; + m_fixture = NULL; + } + + bool ReportFixture(b2Fixture* fixture) + { + b2Body* body = fixture->GetBody(); + if (body->GetType() == b2_dynamicBody) + { + bool inside = fixture->TestPoint(m_point); + if (inside) + { + m_fixture = fixture; + + // We are done, terminate the query. + return false; + } + } + + // Continue the query. + return true; + } + + b2Vec2 m_point; + b2Fixture* m_fixture; +}; + +void Test::MouseDown(const b2Vec2& p) +{ + m_mouseWorld = p; + + if (m_mouseJoint != NULL) + { + return; + } + + // Make a small box. + b2AABB aabb; + b2Vec2 d; + d.Set(0.001f, 0.001f); + aabb.lowerBound = p - d; + aabb.upperBound = p + d; + + // Query the world for overlapping shapes. + QueryCallback callback(p); + m_world->QueryAABB(&callback, aabb); + + if (callback.m_fixture) + { + b2Body* body = callback.m_fixture->GetBody(); + b2MouseJointDef md; + md.bodyA = m_groundBody; + md.bodyB = body; + md.target = p; +#ifdef TARGET_FLOAT32_IS_FIXED + md.maxForce = (body->GetMass() < 16.0)? + (1000.0f * body->GetMass()) : float32(16000.0); +#else + md.maxForce = 1000.0f * body->GetMass(); +#endif + m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md); + body->SetAwake(true); + } +} + +void Test::SpawnBomb(const b2Vec2& worldPt) +{ + m_bombSpawnPoint = worldPt; + m_bombSpawning = true; +} + +void Test::CompleteBombSpawn(const b2Vec2& p) +{ + if (m_bombSpawning == false) + { + return; + } + + const float multiplier = 30.0f; + b2Vec2 vel = m_bombSpawnPoint - p; + vel *= multiplier; + LaunchBomb(m_bombSpawnPoint,vel); + m_bombSpawning = false; +} + +void Test::ShiftMouseDown(const b2Vec2& p) +{ + m_mouseWorld = p; + + if (m_mouseJoint != NULL) + { + return; + } + + SpawnBomb(p); +} + +void Test::MouseUp(const b2Vec2& p) +{ + if (m_mouseJoint) + { + m_world->DestroyJoint(m_mouseJoint); + m_mouseJoint = NULL; + } + + if (m_bombSpawning) + { + CompleteBombSpawn(p); + } +} + +void Test::MouseMove(const b2Vec2& p) +{ + m_mouseWorld = p; + + if (m_mouseJoint) + { + m_mouseJoint->SetTarget(p); + } +} + +void Test::LaunchBomb() +{ + b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f); + b2Vec2 v = -5.0f * p; + LaunchBomb(p, v); +} + +void Test::LaunchBomb(const b2Vec2& position, const b2Vec2& velocity) +{ + if (m_bomb) + { + m_world->DestroyBody(m_bomb); + m_bomb = NULL; + } + + b2BodyDef bd; + bd.type = b2_dynamicBody; + bd.position = position; + bd.bullet = true; + m_bomb = m_world->CreateBody(&bd); + m_bomb->SetLinearVelocity(velocity); + + b2CircleShape circle; + circle.m_radius = 0.3f; + + b2FixtureDef fd; + fd.shape = &circle; + fd.density = 20.0f; + fd.restitution = 0.0f; + + b2Vec2 minV = position - b2Vec2(0.3f,0.3f); + b2Vec2 maxV = position + b2Vec2(0.3f,0.3f); + + b2AABB aabb; + aabb.lowerBound = minV; + aabb.upperBound = maxV; + + m_bomb->CreateFixture(&fd); +} + +void Test::Step(Settings* settings) +{ + float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f); + + if (settings->pause) + { + if (settings->singleStep) + { + settings->singleStep = 0; + } + else + { + timeStep = 0.0f; + } + + m_debugDraw.DrawString(5, m_textLine, "****PAUSED****"); + m_textLine += 15; + } + + uint32 flags = 0; + flags += settings->drawShapes * b2Draw::e_shapeBit; + flags += settings->drawJoints * b2Draw::e_jointBit; + flags += settings->drawAABBs * b2Draw::e_aabbBit; + flags += settings->drawPairs * b2Draw::e_pairBit; + flags += settings->drawCOMs * b2Draw::e_centerOfMassBit; + m_debugDraw.SetFlags(flags); + + m_world->SetWarmStarting(settings->enableWarmStarting > 0); + m_world->SetContinuousPhysics(settings->enableContinuous > 0); + m_world->SetSubStepping(settings->enableSubStepping > 0); + + m_pointCount = 0; + + m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations); + + m_world->DrawDebugData(); + + if (timeStep > 0.0f) + { + ++m_stepCount; + } + + if (settings->drawStats) + { + m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints/proxies = %d/%d/%d", + m_world->GetBodyCount(), m_world->GetContactCount(), m_world->GetJointCount(), m_world->GetProxyCount()); + m_textLine += 15; + } + + if (m_mouseJoint) + { + b2Vec2 p1 = m_mouseJoint->GetAnchorB(); + b2Vec2 p2 = m_mouseJoint->GetTarget(); + + glPointSize(4.0f); + glColor4f(0.0f, 1.0f, 0.0f, 1.0f); + GLbyte verts1[2 * 3] = { + p1.x, p1.y, 0.0f, + p2.x, p2.y, 0.0f + }; + glVertexPointer(3, GL_BYTE, 0, verts1); + glDrawArrays(GL_POINTS, 0, 2); + glPointSize(1.0f); + + glColor4f(0.8f, 0.8f, 0.8f, 1.0f); + GLbyte verts2[2 * 3] = { + p1.x, p1.y, 0.0f, + p2.x, p2.y, 0.0f + }; + glVertexPointer(3, GL_BYTE, 0, verts2); + glDrawArrays(GL_LINES, 0, 2); + } + + if (m_bombSpawning) + { + glPointSize(4.0f); + glColor4f(0.0f, 0.0f, 1.0f, 1.0f); + glColor4f(0.0f, 0.0f, 1.0f, 1.0f); + GLbyte verts1[1 * 3] = { + m_bombSpawnPoint.x, m_bombSpawnPoint.y, 0.0f + }; + glVertexPointer(3, GL_BYTE, 0, verts1); + glDrawArrays(GL_POINTS, 0, 1); + + glColor4f(0.8f, 0.8f, 0.8f, 1.0f); + GLbyte verts2[2 * 3] = { + m_mouseWorld.x, m_mouseWorld.y, 0.0f, + m_bombSpawnPoint.x, m_bombSpawnPoint.y, 0.0f + }; + glVertexPointer(3, GL_BYTE, 0, verts2); + glDrawArrays(GL_LINES, 0, 2); + } + + if (settings->drawContactPoints) + { + //const float32 k_impulseScale = 0.1f; + const float32 k_axisScale = 0.3f; + + for (int32 i = 0; i < m_pointCount; ++i) + { + ContactPoint* point = m_points + i; + + if (point->state == b2_addState) + { + // Add + m_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f)); + } + else if (point->state == b2_persistState) + { + // Persist + m_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f)); + } + + if (settings->drawContactNormals == 1) + { + b2Vec2 p1 = point->position; + b2Vec2 p2 = p1 + k_axisScale * point->normal; + m_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f)); + } + else if (settings->drawContactForces == 1) + { + //b2Vec2 p1 = point->position; + //b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal; + //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f)); + } + + if (settings->drawFrictionForces == 1) + { + //b2Vec2 tangent = b2Cross(point->normal, 1.0f); + //b2Vec2 p1 = point->position; + //b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent; + //DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f)); + } + } + } +} diff --git a/libs/box2d/iPhone/Classes/iPhoneTestEntries.mm b/libs/box2d/iPhone/Classes/iPhoneTestEntries.mm new file mode 100644 index 0000000..18faaa0 --- /dev/null +++ b/libs/box2d/iPhone/Classes/iPhoneTestEntries.mm @@ -0,0 +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 "iPhoneTest.h" +#include +using namespace std; + +#include "ApplyForce.h" +#include "BodyTypes.h" +#include "Breakable.h" +#include "Bridge.h" +#include "BulletTest.h" +#include "Cantilever.h" +#include "Car.h" +#include "ContinuousTest.h" +#include "Chain.h" +#include "CharacterCollision.h" +#include "CollisionFiltering.h" +#include "CollisionProcessing.h" +#include "CompoundShapes.h" +#include "Confined.h" +#include "DistanceTest.h" +#include "Dominos.h" +#include "DynamicTreeTest.h" +#include "EdgeShapes.h" +#include "EdgeTest.h" +#include "Gears.h" +#include "OneSidedPlatform.h" +#include "Pinball.h" +#include "PolyCollision.h" +#include "PolyShapes.h" +#include "Prismatic.h" +#include "Pulleys.h" +#include "Pyramid.h" +#include "RayCast.h" +#include "Revolute.h" +#include "Rope.h" +#include "RopeJoint.h" +#include "SensorTest.h" +#include "ShapeEditing.h" +#include "SliderCrank.h" +#include "SphereStack.h" +#include "TheoJansen.h" +#include "Tiles.h" +#include "TimeOfImpact.h" +#include "VaryingFriction.h" +#include "VaryingRestitution.h" +#include "VerticalStack.h" +#include "Web.h" + +TestEntry g_testEntries[] = +{ + {"Pulleys", Pulleys::Create}, + {"SphereStack", SphereStack::Create}, + {"Tiles", Tiles::Create}, + {"Polygon Shapes", PolyShapes::Create}, + {"Rope", Rope::Create}, + {"Web", Web::Create}, + {"Car", Car::Create}, + {"Vertical Stack", VerticalStack::Create}, + {"RopeJoint", RopeJoint::Create}, + {"Character Collision", CharacterCollision::Create}, + {"Edge Test", EdgeTest::Create}, + {"One-Sided Platform", OneSidedPlatform::Create}, + {"Pinball", Pinball::Create}, + {"Bullet Test", BulletTest::Create}, + {"Continuous Test", ContinuousTest::Create}, + {"Time of Impact", TimeOfImpact::Create}, + {"Ray-Cast", RayCast::Create}, + {"Confined", Confined::Create}, + {"Pyramid", Pyramid::Create}, + {"Varying Restitution", VaryingRestitution::Create}, + {"Theo Jansen's Walker", TheoJansen::Create}, + {"Body Types", BodyTypes::Create}, + {"Prismatic", Prismatic::Create}, + {"Edge Shapes", EdgeShapes::Create}, + {"PolyCollision", PolyCollision::Create}, + {"Apply Force", ApplyForce::Create}, + {"Cantilever", Cantilever::Create}, + {"Bridge", Bridge::Create}, + {"Breakable", Breakable::Create}, + {"Chain", Chain::Create}, + {"Collision Filtering", CollisionFiltering::Create}, + {"Collision Processing", CollisionProcessing::Create}, + {"Compound Shapes", CompoundShapes::Create}, + {"Distance Test", DistanceTest::Create}, + {"Dominos", Dominos::Create}, + {"Dynamic Tree", DynamicTreeTest::Create}, + {"Gears", Gears::Create}, + {"Revolute", Revolute::Create}, + {"Sensor Test", SensorTest::Create}, + {"Shape Editing", ShapeEditing::Create}, + {"Slider Crank", SliderCrank::Create}, + {"Varying Friction", VaryingFriction::Create}, + {NULL, NULL} +}; diff --git a/libs/box2d/iPhone/Icon.png b/libs/box2d/iPhone/Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fe81a597586c83190d0d70ba2b0d97a8baadf2a5 GIT binary patch literal 1951 zcmV;Q2VnS#P)JShRxkjT~t3<0SM1k2U} z)0VPzq1){D&YgSw&l$kdWtfF!M&>k~CUft(_k92Npa1{9dn+-H&a!aK@CeV^O~4OSoTMAwc(i|AS~R zaeqHG4@Ll|!2Nn{?iC&u2_tgyBrMebyzAFPE-g)ZzQyB#cf$sRPu3%L{W`)Y{(y7# zY{t%MkjG6dPNP0LDiMgBOIO|^ zB;F#5MFC1>aMoSRmr<%x8@Y9B=dJkPa;flw(A(OC zib+Wg-MJ%rA`gmEQIY!~9aE~rel%%c_W$@(N^@c@t%#gDMJ%dhwHD+)NX~|*wl>ic zcI_fr)|ix0e!P48cA;r)Q>Vc(W5zHgI|m1)AG@~t4c7F0C2Lu}f(4G$F;YH^nP%db zpVQgNBBxHXwzuA9O%o?E-`sgD($FyM^|Dqx{Z!GSag*=)jE0pQM6umEWIh+x9iM(i zE#<5b_`6Hm`xkuS+z=3<{{aU4an9&7(1J;;Z`^b zS;`Ei%PM2T^hucLQHLDUn=Yeg=Xb*8^G6*50ADWuEAA%=FIlp7jp&oyVhy_mvH^Mc zMkhY5KPLpTk|s!gSA#wznzv=v6uenEZrIjfhC&D*I|l8l57BcCgj}Z*ER)li1n1m2 zB>iTPyek);a-@-!th3MpZFKPxO1Dp{Ux041l+sovKNyM`*xh^+&6EwXk>X6(=CaLA zg~(0k(0&|1k0c&^`@&y7uMURPAd@%C<9?hidYFn3uJpfVvNdu5VH zyG%x$A>)GeL_v!5lb*yZC&* zG@sqoz>jk%$rFm9u`ft|F)kh~4F=c|(V&r+jL`9K8(WboUM|qPNxQZN!@|AX2uExya{js;R<~iqeb|JSme+R21HqSksqbDb1`dsrFjjR4Ky28(od7*}bW)~p#xL~-u&CUdF`G$2Dwc#(nB^_TM^h(= zh^Mj#IRl-vxNYaIl3xs=LUrQvnJ=QuVH=W?$-L_J^FI83`wlrRDXUuiP(K-`MHSl> zOe^+al+Bv*h53Hvg@p%+GtM7xOmM4dEl#DNN{^rlKeW2??Z%^@Nd^2b1(^s|`knOA z7|zEg2H5@GIbfq^V8{!yt^l$CvH-FG@)-ol@(ZMR*O8`f7Xvd#jLHOz$NuXOEdOHaT zQ6DnmXph8Tx7cwjY+&Q*%QWAbvdQKS&==(Y5lI$|+3sdVhAt$icZ}dbtQh0CO^Xa5 zpvMr3C0@_56dB-exMYcEfh08SwLtm_D@?N-CyUmLs9{2vY)Ji0qj=^3)mj2+_oa8( zNLHse8b(VX2ou25dfUNYCQUAK!E1LRo>ti-Sj@zninUPM{PjtF;dtlM?J_*LA>Bm3 l#?lUS)aZxTS%rTE7yx`J=+jFERxSVl002ovPDHLkV1luCmP!Bs literal 0 HcmV?d00001 diff --git a/libs/box2d/iPhone/Info.plist b/libs/box2d/iPhone/Info.plist new file mode 100644 index 0000000..fdf8340 --- /dev/null +++ b/libs/box2d/iPhone/Info.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + + diff --git a/libs/box2d/iPhone/MainWindow.xib b/libs/box2d/iPhone/MainWindow.xib new file mode 100644 index 0000000..f2e35a9 --- /dev/null +++ b/libs/box2d/iPhone/MainWindow.xib @@ -0,0 +1,232 @@ + + + + 528 + 9G55 + 677 + 949.43 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + YES + + + 1298 + {320, 480} + + + 3 + MQA + + 2 + + + NO + + + + {320, 480} + + + 1 + MSAxIDEAA + + NO + YES + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + glView + + + + 9 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + 8 + + + + + -2 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 8.CustomClassName + 8.IBPluginDependency + + + YES + UIApplication + UIResponder + + YES + + YES + + + YES + + + {{500, 343}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + Box2DAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + Box2DView + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 9 + + + + YES + + Box2DAppDelegate + NSObject + + YES + + YES + glView + window + + + YES + Box2DView + UIWindow + + + + IBProjectSource + Classes/Box2DAppDelegate.h + + + + Box2DView + UIView + + IBProjectSource + Classes/Box2DView.h + + + + + 0 + Box2D.xcodeproj + 3 + + diff --git a/libs/box2d/iPhone/main.m b/libs/box2d/iPhone/main.m new file mode 100644 index 0000000..1c48429 --- /dev/null +++ b/libs/box2d/iPhone/main.m @@ -0,0 +1,17 @@ +// +// main.m +// Box2D +// +// Created by Simon Oliver on 14/01/2009. +// Copyright HandCircus 2009. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/libs/box2d/src/Box2D/Box2D.h b/libs/box2d/src/Box2D/Box2D.h new file mode 100644 index 0000000..dc5701f --- /dev/null +++ b/libs/box2d/src/Box2D/Box2D.h @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif diff --git a/libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.cpp b/libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.cpp new file mode 100644 index 0000000..a950b0b --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.cpp @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const +{ + void* mem = allocator->Allocate(sizeof(b2CircleShape)); + b2CircleShape* clone = new (mem) b2CircleShape; + *clone = *this; + return clone; +} + +bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const +{ + b2Vec2 center = transform.position + b2Mul(transform.R, 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) const +{ + b2Vec2 position = transform.position + b2Mul(transform.R, 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) const +{ + b2Vec2 p = transform.position + b2Mul(transform.R, 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)); +} diff --git a/libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.h b/libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.h new file mode 100644 index 0000000..bb31da8 --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/Shapes/b2CircleShape.h @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 + +/// A circle shape. +class b2CircleShape : public b2Shape +{ +public: + b2CircleShape(); + + /// Implement b2Shape. + b2Shape* Clone(b2BlockAllocator* allocator) const; + + /// Implement b2Shape. + bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; + + /// Implement b2Shape. + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const; + + /// @see b2Shape::ComputeAABB + void ComputeAABB(b2AABB* aabb, const b2Transform& transform) 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 diff --git a/libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.cpp b/libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.cpp new file mode 100644 index 0000000..429e647 --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.cpp @@ -0,0 +1,434 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +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_vertexCount = 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_vertexCount = 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.position = center; + xf.R.Set(angle); + + // Transform vertices and normals. + for (int32 i = 0; i < m_vertexCount; ++i) + { + m_vertices[i] = b2Mul(xf, m_vertices[i]); + m_normals[i] = b2Mul(xf.R, m_normals[i]); + } +} + +void b2PolygonShape::SetAsEdge(const b2Vec2& v1, const b2Vec2& v2) +{ + m_vertexCount = 2; + m_vertices[0] = v1; + m_vertices[1] = v2; + m_centroid = 0.5f * (v1 + v2); + m_normals[0] = b2Cross(v2 - v1, 1.0f); + m_normals[0].Normalize(); + m_normals[1] = -m_normals[0]; +} + +static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count) +{ + b2Assert(count >= 2); + + b2Vec2 c; c.Set(0.0f, 0.0f); + float32 area = 0.0f; + + if (count == 2) + { + c = 0.5f * (vs[0] + vs[1]); + return c; + } + + // 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(2 <= count && count <= b2_maxPolygonVertices); + m_vertexCount = count; + + // Copy vertices. + for (int32 i = 0; i < m_vertexCount; ++i) + { + m_vertices[i] = vertices[i]; + } + + // Compute normals. Ensure the edges have non-zero length. + for (int32 i = 0; i < m_vertexCount; ++i) + { + int32 i1 = i; + int32 i2 = i + 1 < m_vertexCount ? 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(); + } + +#ifdef _DEBUG + // Ensure the polygon is convex and the interior + // is to the left of each edge. + for (int32 i = 0; i < m_vertexCount; ++i) + { + int32 i1 = i; + int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0; + b2Vec2 edge = m_vertices[i2] - m_vertices[i1]; + + for (int32 j = 0; j < m_vertexCount; ++j) + { + // Don't check vertices on the current edge. + if (j == i1 || j == i2) + { + continue; + } + + b2Vec2 r = m_vertices[j] - m_vertices[i1]; + + // Your polygon is non-convex (it has an indentation) or + // has colinear edges. + float32 s = b2Cross(edge, r); + b2Assert(s > 0.0f); + } + } +#endif + + // Compute the polygon centroid. + m_centroid = ComputeCentroid(m_vertices, m_vertexCount); +} + +bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const +{ + b2Vec2 pLocal = b2MulT(xf.R, p - xf.position); + + for (int32 i = 0; i < m_vertexCount; ++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) const +{ + // Put the ray into the polygon's frame of reference. + b2Vec2 p1 = b2MulT(xf.R, input.p1 - xf.position); + b2Vec2 p2 = b2MulT(xf.R, input.p2 - xf.position); + b2Vec2 d = p2 - p1; + + if (m_vertexCount == 2) + { + b2Vec2 v1 = m_vertices[0]; + b2Vec2 v2 = m_vertices[1]; + b2Vec2 normal = m_normals[0]; + + // 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 || 1.0f < 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; + } + else + { + float32 lower = 0.0f, upper = input.maxFraction; + + int32 index = -1; + + for (int32 i = 0; i < m_vertexCount; ++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.R, m_normals[index]); + return true; + } + } + + return false; +} + +void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf) const +{ + b2Vec2 lower = b2Mul(xf, m_vertices[0]); + b2Vec2 upper = lower; + + for (int32 i = 1; i < m_vertexCount; ++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_vertexCount >= 2); + + // A line segment has zero mass. + if (m_vertexCount == 2) + { + massData->center = 0.5f * (m_vertices[0] + m_vertices[1]); + massData->mass = 0.0f; + massData->I = 0.0f; + return; + } + + b2Vec2 center; center.Set(0.0f, 0.0f); + float32 area = 0.0f; + float32 I = 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 < m_vertexCount; ++i) + { + pRef += m_vertices[i]; + } + pRef *= 1.0f / count; +#endif + + const float32 k_inv3 = 1.0f / 3.0f; + + for (int32 i = 0; i < m_vertexCount; ++i) + { + // Triangle vertices. + b2Vec2 p1 = pRef; + b2Vec2 p2 = m_vertices[i]; + b2Vec2 p3 = i + 1 < m_vertexCount ? m_vertices[i+1] : m_vertices[0]; + + b2Vec2 e1 = p2 - p1; + b2Vec2 e2 = p3 - p1; + + float32 D = b2Cross(e1, e2); + + float32 triangleArea = 0.5f * D; + area += triangleArea; + + // Area weighted centroid + center += triangleArea * k_inv3 * (p1 + p2 + p3); + + float32 px = p1.x, py = p1.y; + float32 ex1 = e1.x, ey1 = e1.y; + float32 ex2 = e2.x, ey2 = e2.y; + + float32 intx2 = k_inv3 * (0.25f * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5f*px*px; + float32 inty2 = k_inv3 * (0.25f * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5f*py*py; + + I += D * (intx2 + inty2); + } + + // Total mass + massData->mass = density * area; + + // Center of mass + b2Assert(area > b2_epsilon); + center *= 1.0f / area; + massData->center = center; + + // Inertia tensor relative to the local origin. + massData->I = density * I; +} diff --git a/libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.h b/libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.h new file mode 100644 index 0000000..564d4b0 --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/Shapes/b2PolygonShape.h @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 + +/// A convex polygon. It is assumed that the interior of the polygon is to +/// the left of each edge. +class b2PolygonShape : public b2Shape +{ +public: + b2PolygonShape(); + + /// Implement b2Shape. + b2Shape* Clone(b2BlockAllocator* allocator) const; + + /// Copy vertices. This assumes the vertices define a convex polygon. + /// It is assumed that the exterior is the the right of each edge. + void Set(const b2Vec2* vertices, int32 vertexCount); + + /// Build vertices to represent an axis-aligned box. + /// @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); + + /// Set this as a single edge. + void SetAsEdge(const b2Vec2& v1, const b2Vec2& v2); + + /// @see b2Shape::TestPoint + bool TestPoint(const b2Transform& transform, const b2Vec2& p) const; + + /// Implement b2Shape. + bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const; + + /// @see b2Shape::ComputeAABB + void ComputeAABB(b2AABB* aabb, const b2Transform& transform) 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 m_vertexCount; } + + /// Get a vertex by index. + const b2Vec2& GetVertex(int32 index) const; + + b2Vec2 m_centroid; + b2Vec2 m_vertices[b2_maxPolygonVertices]; + b2Vec2 m_normals[b2_maxPolygonVertices]; + int32 m_vertexCount; +}; + +inline b2PolygonShape::b2PolygonShape() +{ + m_type = e_polygon; + m_radius = b2_polygonRadius; + m_vertexCount = 0; + m_centroid.SetZero(); +} + +inline int32 b2PolygonShape::GetSupport(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float32 bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_vertexCount; ++i) + { + float32 value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return bestIndex; +} + +inline const b2Vec2& b2PolygonShape::GetSupportVertex(const b2Vec2& d) const +{ + int32 bestIndex = 0; + float32 bestValue = b2Dot(m_vertices[0], d); + for (int32 i = 1; i < m_vertexCount; ++i) + { + float32 value = b2Dot(m_vertices[i], d); + if (value > bestValue) + { + bestIndex = i; + bestValue = value; + } + } + + return m_vertices[bestIndex]; +} + +inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const +{ + b2Assert(0 <= index && index < m_vertexCount); + return m_vertices[index]; +} + +#endif diff --git a/libs/box2d/src/Box2D/Collision/Shapes/b2Shape.h b/libs/box2d/src/Box2D/Collision/Shapes/b2Shape.h new file mode 100644 index 0000000..9082c0e --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/Shapes/b2Shape.h @@ -0,0 +1,95 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include + +/// 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. +class b2Shape +{ +public: + + enum Type + { + e_unknown= -1, + e_circle = 0, + e_polygon = 1, + e_typeCount = 2, + }; + + b2Shape() { m_type = e_unknown; } + 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; + + /// 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 this shape. + /// @param output the ray-cast results. + /// @param input the ray-cast input parameters. + /// @param transform the transform to be applied to the shape. + virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const = 0; + + /// Given a transform, compute the associated axis aligned bounding box for this shape. + /// @param aabb returns the axis aligned box. + /// @param xf the world transform of the shape. + virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf) 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 diff --git a/libs/box2d/src/Box2D/Collision/b2BroadPhase.cpp b/libs/box2d/src/Box2D/Collision/b2BroadPhase.cpp new file mode 100644 index 0000000..12c7967 --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2BroadPhase.cpp @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +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::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; + return; + } + } +} + +// 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; +} diff --git a/libs/box2d/src/Box2D/Collision/b2BroadPhase.h b/libs/box2d/src/Box2D/Collision/b2BroadPhase.h new file mode 100644 index 0000000..bff188e --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2BroadPhase.h @@ -0,0 +1,229 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include +#include + +struct b2Pair +{ + int32 proxyIdA; + int32 proxyIdB; + int32 next; +}; + +/// 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); + + /// 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 + void UpdatePairs(T* callback); + + /// Query an AABB for overlapping proxies. The callback class + /// is called for each proxy that overlaps the supplied AABB. + template + 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 + void RayCast(T* callback, const b2RayCastInput& input) const; + + /// Compute the height of the embedded tree. + int32 ComputeHeight() const; + +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::ComputeHeight() const +{ + return m_tree.ComputeHeight(); +} + +template +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 +inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const +{ + m_tree.Query(callback, aabb); +} + +template +inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const +{ + m_tree.RayCast(callback, input); +} + +#endif diff --git a/libs/box2d/src/Box2D/Collision/b2CollideCircle.cpp b/libs/box2d/src/Box2D/Collision/b2CollideCircle.cpp new file mode 100644 index 0000000..6edf89d --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2CollideCircle.cpp @@ -0,0 +1,154 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include + +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_vertexCount; + 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; + } +} diff --git a/libs/box2d/src/Box2D/Collision/b2CollidePolygon.cpp b/libs/box2d/src/Box2D/Collision/b2CollidePolygon.cpp new file mode 100644 index 0000000..b37b7ba --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2CollidePolygon.cpp @@ -0,0 +1,306 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +// 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) +{ + int32 count1 = poly1->m_vertexCount; + const b2Vec2* vertices1 = poly1->m_vertices; + const b2Vec2* normals1 = poly1->m_normals; + + int32 count2 = poly2->m_vertexCount; + const b2Vec2* vertices2 = poly2->m_vertices; + + b2Assert(0 <= edge1 && edge1 < count1); + + // Convert normal from poly1's frame into poly2's frame. + b2Vec2 normal1World = b2Mul(xf1.R, normals1[edge1]); + b2Vec2 normal1 = b2MulT(xf2.R, 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_vertexCount; + 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.R, 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) +{ + int32 count1 = poly1->m_vertexCount; + const b2Vec2* normals1 = poly1->m_normals; + + int32 count2 = poly2->m_vertexCount; + const b2Vec2* vertices2 = poly2->m_vertices; + const b2Vec2* normals2 = poly2->m_normals; + + b2Assert(0 <= edge1 && edge1 < count1); + + // Get the normal of the reference edge in poly2's frame. + b2Vec2 normal1 = b2MulT(xf2.R, b2Mul(xf1.R, 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.features.referenceEdge = (uint8)edge1; + c[0].id.features.incidentEdge = (uint8)i1; + c[0].id.features.incidentVertex = 0; + + c[1].v = b2Mul(xf2, vertices2[i2]); + c[1].id.features.referenceEdge = (uint8)edge1; + c[1].id.features.incidentEdge = (uint8)i2; + c[1].id.features.incidentVertex = 1; +} + +// 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_vertexCount; + const b2Vec2* vertices1 = poly1->m_vertices; + + b2Vec2 v11 = vertices1[edge1]; + b2Vec2 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0]; + + b2Vec2 localTangent = v12 - v11; + localTangent.Normalize(); + + b2Vec2 localNormal = b2Cross(localTangent, 1.0f); + b2Vec2 planePoint = 0.5f * (v11 + v12); + + b2Vec2 tangent = b2Mul(xf1.R, 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); + + if (np < 2) + return; + + // Clip to negative box side 1 + np = b2ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2); + + 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; + cp->id.features.flip = flip; + ++pointCount; + } + } + + manifold->pointCount = pointCount; +} diff --git a/libs/box2d/src/Box2D/Collision/b2Collision.cpp b/libs/box2d/src/Box2D/Collision/b2Collision.cpp new file mode 100644 index 0000000..a86c7c5 --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2Collision.cpp @@ -0,0 +1,250 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +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.R, 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.R, 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) +{ + // 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); + if (distance0 > 0.0f) + { + vOut[numOut].id = vIn[0].id; + } + else + { + vOut[numOut].id = vIn[1].id; + } + ++numOut; + } + + return numOut; +} + +bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB, + const b2Transform& xfA, const b2Transform& xfB) +{ + b2DistanceInput input; + input.proxyA.Set(shapeA); + input.proxyB.Set(shapeB); + 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; +} diff --git a/libs/box2d/src/Box2D/Collision/b2Collision.h b/libs/box2d/src/Box2D/Collision/b2Collision.h new file mode 100644 index 0000000..baffdbd --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2Collision.h @@ -0,0 +1,240 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +/// @file +/// Structures and functions used for computing contact points, distance +/// queries, and TOI queries. + +class b2Shape; +class b2CircleShape; +class b2PolygonShape; + +const uint8 b2_nullFeature = UCHAR_MAX; + +/// Contact ids to facilitate warm starting. +union b2ContactID +{ + /// The features that intersect to form the contact point + struct Features + { + uint8 referenceEdge; ///< The edge that defines the outward contact normal. + uint8 incidentEdge; ///< The edge most anti-parallel to the reference edge. + uint8 incidentVertex; ///< The vertex (0 or 1) on the incident edge that was clipped. + uint8 flip; ///< A value of 1 indicates that the reference edge is on shape2. + } features; + 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); + } + + /// 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* circle1, const b2Transform& xf1, + const b2CircleShape* circle2, const b2Transform& xf2); + +/// Compute the collision manifold between a polygon and a circle. +void b2CollidePolygonAndCircle(b2Manifold* manifold, + const b2PolygonShape* polygon, const b2Transform& xf1, + const b2CircleShape* circle, const b2Transform& xf2); + +/// Compute the collision manifold between two polygons. +void b2CollidePolygons(b2Manifold* manifold, + const b2PolygonShape* polygon1, const b2Transform& xf1, + const b2PolygonShape* polygon2, const b2Transform& xf2); + +/// Clipping for contact manifolds. +int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2], + const b2Vec2& normal, float32 offset); + +/// Determine if two generic shapes overlap. +bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB, + 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 diff --git a/libs/box2d/src/Box2D/Collision/b2Distance.cpp b/libs/box2d/src/Box2D/Collision/b2Distance.cpp new file mode 100644 index 0000000..f95c82f --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2Distance.cpp @@ -0,0 +1,571 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include + +// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates. +int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters; + +void b2DistanceProxy::Set(const b2Shape* shape) +{ + 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_vertexCount; + m_radius = polygon->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; + 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.0; + + 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; + + b2Vec2 closestPoint = simplex.GetClosestPoint(); + float32 distanceSqr1 = closestPoint.LengthSquared(); + 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.R, -d)); + vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA)); + b2Vec2 wBLocal; + vertex->indexB = proxyB->GetSupport(b2MulT(transformB.R, 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; + } + } +} diff --git a/libs/box2d/src/Box2D/Collision/b2Distance.h b/libs/box2d/src/Box2D/Collision/b2Distance.h new file mode 100644 index 0000000..e56ea0a --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2Distance.h @@ -0,0 +1,141 @@ + +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +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); + + /// 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; + + 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 diff --git a/libs/box2d/src/Box2D/Collision/b2DynamicTree.cpp b/libs/box2d/src/Box2D/Collision/b2DynamicTree.cpp new file mode 100644 index 0000000..d8a05eb --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2DynamicTree.cpp @@ -0,0 +1,365 @@ +/* +* Copyright (c) 2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include + +b2DynamicTree::b2DynamicTree() +{ + m_root = b2_nullNode; + + m_nodeCapacity = 16; + m_nodeCount = 0; + m_nodes = (b2DynamicTreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2DynamicTreeNode)); + memset(m_nodes, 0, m_nodeCapacity * sizeof(b2DynamicTreeNode)); + + // 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[m_nodeCapacity-1].next = b2_nullNode; + 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. + b2DynamicTreeNode* oldNodes = m_nodes; + m_nodeCapacity *= 2; + m_nodes = (b2DynamicTreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2DynamicTreeNode)); + memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2DynamicTreeNode)); + 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[m_nodeCapacity-1].next = b2_nullNode; + 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_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_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; + + InsertLeaf(proxyId); + + // Rebalance if necessary. + int32 iterationCount = m_nodeCount >> 4; + int32 tryCount = 0; + int32 height = ComputeHeight(); + while (height > 64 && tryCount < 10) + { + Rebalance(iterationCount); + height = ComputeHeight(); + ++tryCount; + } + + 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. + b2Vec2 center = m_nodes[leaf].aabb.GetCenter(); + int32 sibling = m_root; + if (m_nodes[sibling].IsLeaf() == false) + { + do + { + int32 child1 = m_nodes[sibling].child1; + int32 child2 = m_nodes[sibling].child2; + + b2Vec2 delta1 = b2Abs(m_nodes[child1].aabb.GetCenter() - center); + b2Vec2 delta2 = b2Abs(m_nodes[child2].aabb.GetCenter() - center); + + float32 norm1 = delta1.x + delta1.y; + float32 norm2 = delta2.x + delta2.y; + + if (norm1 < norm2) + { + sibling = child1; + } + else + { + sibling = child2; + } + + } + while(m_nodes[sibling].IsLeaf() == false); + } + + // Create a parent for the siblings. + int32 node1 = m_nodes[sibling].parent; + int32 node2 = AllocateNode(); + m_nodes[node2].parent = node1; + m_nodes[node2].userData = NULL; + m_nodes[node2].aabb.Combine(m_nodes[leaf].aabb, m_nodes[sibling].aabb); + + if (node1 != b2_nullNode) + { + if (m_nodes[m_nodes[sibling].parent].child1 == sibling) + { + m_nodes[node1].child1 = node2; + } + else + { + m_nodes[node1].child2 = node2; + } + + m_nodes[node2].child1 = sibling; + m_nodes[node2].child2 = leaf; + m_nodes[sibling].parent = node2; + m_nodes[leaf].parent = node2; + + do + { + if (m_nodes[node1].aabb.Contains(m_nodes[node2].aabb)) + { + break; + } + + m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb); + node2 = node1; + node1 = m_nodes[node1].parent; + } + while(node1 != b2_nullNode); + } + else + { + m_nodes[node2].child1 = sibling; + m_nodes[node2].child2 = leaf; + m_nodes[sibling].parent = node2; + m_nodes[leaf].parent = node2; + m_root = node2; + } +} + +void b2DynamicTree::RemoveLeaf(int32 leaf) +{ + if (leaf == m_root) + { + m_root = b2_nullNode; + return; + } + + int32 node2 = m_nodes[leaf].parent; + int32 node1 = m_nodes[node2].parent; + int32 sibling; + if (m_nodes[node2].child1 == leaf) + { + sibling = m_nodes[node2].child2; + } + else + { + sibling = m_nodes[node2].child1; + } + + if (node1 != b2_nullNode) + { + // Destroy node2 and connect node1 to sibling. + if (m_nodes[node1].child1 == node2) + { + m_nodes[node1].child1 = sibling; + } + else + { + m_nodes[node1].child2 = sibling; + } + m_nodes[sibling].parent = node1; + FreeNode(node2); + + // Adjust ancestor bounds. + while (node1 != b2_nullNode) + { + b2AABB oldAABB = m_nodes[node1].aabb; + m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb); + + if (oldAABB.Contains(m_nodes[node1].aabb)) + { + break; + } + + node1 = m_nodes[node1].parent; + } + } + else + { + m_root = sibling; + m_nodes[sibling].parent = b2_nullNode; + FreeNode(node2); + } +} + +void b2DynamicTree::Rebalance(int32 iterations) +{ + if (m_root == b2_nullNode) + { + return; + } + + for (int32 i = 0; i < iterations; ++i) + { + int32 node = m_root; + + uint32 bit = 0; + while (m_nodes[node].IsLeaf() == false) + { + int32* children = &m_nodes[node].child1; + node = children[(m_path >> bit) & 1]; + bit = (bit + 1) & (8* sizeof(uint32) - 1); + } + ++m_path; + + RemoveLeaf(node); + InsertLeaf(node); + } +} + +// Compute the height of a sub-tree. +int32 b2DynamicTree::ComputeHeight(int32 nodeId) const +{ + if (nodeId == b2_nullNode) + { + return 0; + } + + b2Assert(0 <= nodeId && nodeId < m_nodeCapacity); + b2DynamicTreeNode* node = m_nodes + nodeId; + int32 height1 = ComputeHeight(node->child1); + int32 height2 = ComputeHeight(node->child2); + return 1 + b2Max(height1, height2); +} + +int32 b2DynamicTree::ComputeHeight() const +{ + return ComputeHeight(m_root); +} diff --git a/libs/box2d/src/Box2D/Collision/b2DynamicTree.h b/libs/box2d/src/Box2D/Collision/b2DynamicTree.h new file mode 100644 index 0000000..b67686b --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2DynamicTree.h @@ -0,0 +1,286 @@ +/* +* Copyright (c) 2009 Erin Catto http://www.gphysics.com +* +* 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 + +/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt. + +#define b2_nullNode (-1) + +/// A node in the dynamic tree. The client does not interact with this directly. +struct b2DynamicTreeNode +{ + bool IsLeaf() const + { + return child1 == b2_nullNode; + } + + /// This is the fattened AABB. + b2AABB aabb; + + //int32 userData; + void* userData; + + union + { + int32 parent; + int32 next; + }; + + int32 child1; + int32 child2; +}; + +/// 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); + + /// Perform some iterations to re-balance the tree. + void Rebalance(int32 iterations); + + /// 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; + + /// Compute the height of the tree. + int32 ComputeHeight() const; + + /// Query an AABB for overlapping proxies. The callback class + /// is called for each proxy that overlaps the supplied AABB. + template + 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 + void RayCast(T* callback, const b2RayCastInput& input) const; + +private: + + int32 AllocateNode(); + void FreeNode(int32 node); + + void InsertLeaf(int32 node); + void RemoveLeaf(int32 node); + + int32 ComputeHeight(int32 nodeId) const; + + int32 m_root; + + b2DynamicTreeNode* m_nodes; + int32 m_nodeCount; + int32 m_nodeCapacity; + + int32 m_freeList; + + /// This is used 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 +inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const +{ + const int32 k_stackSize = 128; + int32 stack[k_stackSize]; + + int32 count = 0; + stack[count++] = m_root; + + while (count > 0) + { + int32 nodeId = stack[--count]; + if (nodeId == b2_nullNode) + { + continue; + } + + const b2DynamicTreeNode* node = m_nodes + nodeId; + + if (b2TestOverlap(node->aabb, aabb)) + { + if (node->IsLeaf()) + { + bool proceed = callback->QueryCallback(nodeId); + if (proceed == false) + { + return; + } + } + else + { + if (count < k_stackSize) + { + stack[count++] = node->child1; + } + + if (count < k_stackSize) + { + stack[count++] = node->child2; + } + } + } + } +} + +template +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); + } + + const int32 k_stackSize = 128; + int32 stack[k_stackSize]; + + int32 count = 0; + stack[count++] = m_root; + + while (count > 0) + { + int32 nodeId = stack[--count]; + if (nodeId == b2_nullNode) + { + continue; + } + + const b2DynamicTreeNode* 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 + { + if (count < k_stackSize) + { + stack[count++] = node->child1; + } + + if (count < k_stackSize) + { + stack[count++] = node->child2; + } + } + } +} + +#endif diff --git a/libs/box2d/src/Box2D/Collision/b2TimeOfImpact.cpp b/libs/box2d/src/Box2D/Collision/b2TimeOfImpact.cpp new file mode 100644 index 0000000..b1f2f4e --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2TimeOfImpact.cpp @@ -0,0 +1,483 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include +#include +#include + +#include + +int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters; +int32 b2_toiRootIters, b2_toiMaxRootIters; + +int32 b2_toiMaxOptIters; + +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) + { + 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, 0.0f); + m_sweepB.GetTransform(&xfB, 0.0f); + + 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.R, 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.R, 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.R, m_axis); + b2Vec2 axisB = b2MulT(xfB.R, -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.R, m_axis); + b2Vec2 pointA = b2Mul(xfA, m_localPoint); + + b2Vec2 axisB = b2MulT(xfB.R, -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.R, m_axis); + b2Vec2 pointB = b2Mul(xfB, m_localPoint); + + b2Vec2 axisA = b2MulT(xfA.R, -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 axisA = b2MulT(xfA.R, m_axis); + b2Vec2 axisB = b2MulT(xfB.R, -m_axis); + + 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.R, m_axis); + b2Vec2 pointA = b2Mul(xfA, m_localPoint); + + b2Vec2 axisB = b2MulT(xfB.R, -normal); + + 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.R, m_axis); + b2Vec2 pointB = b2Mul(xfB, m_localPoint); + + b2Vec2 axisA = b2MulT(xfA.R, -normal); + + 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); +#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); +} diff --git a/libs/box2d/src/Box2D/Collision/b2TimeOfImpact.h b/libs/box2d/src/Box2D/Collision/b2TimeOfImpact.h new file mode 100644 index 0000000..b59fb83 --- /dev/null +++ b/libs/box2d/src/Box2D/Collision/b2TimeOfImpact.h @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include + +/// 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 diff --git a/libs/box2d/src/Box2D/Common/b2BlockAllocator.cpp b/libs/box2d/src/Box2D/Common/b2BlockAllocator.cpp new file mode 100644 index 0000000..ba06f04 --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2BlockAllocator.cpp @@ -0,0 +1,205 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include +#include +#include +#include + +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 && size <= b2_maxBlockSize); + + 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 && size <= b2_maxBlockSize); + + 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)); +} diff --git a/libs/box2d/src/Box2D/Common/b2BlockAllocator.h b/libs/box2d/src/Box2D/Common/b2BlockAllocator.h new file mode 100644 index 0000000..93eb2e3 --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2BlockAllocator.h @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 + +const int32 b2_chunkSize = 4096; +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(); + + void* Allocate(int32 size); + 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 diff --git a/libs/box2d/src/Box2D/Common/b2Math.cpp b/libs/box2d/src/Box2D/Common/b2Math.cpp new file mode 100644 index 0000000..f15a43b --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2Math.cpp @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com +* +* 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 + +const b2Vec2 b2Vec2_zero(0.0f, 0.0f); +const b2Mat22 b2Mat22_identity(1.0f, 0.0f, 0.0f, 1.0f); +const b2Transform b2Transform_identity(b2Vec2_zero, b2Mat22_identity); + +/// 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(col1, b2Cross(col2, col3)); + if (det != 0.0f) + { + det = 1.0f / det; + } + b2Vec3 x; + x.x = det * b2Dot(b, b2Cross(col2, col3)); + x.y = det * b2Dot(col1, b2Cross(b, col3)); + x.z = det * b2Dot(col1, b2Cross(col2, 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 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.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; +} diff --git a/libs/box2d/src/Box2D/Common/b2Math.h b/libs/box2d/src/Box2D/Common/b2Math.h new file mode 100644 index 0000000..c29f594 --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2Math.h @@ -0,0 +1,624 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 + +#include +#include +#include +#include + +/// 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::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) sqrtf(x) +#define b2Atan2(y, x) atan2f(y, x) + +inline float32 b2Abs(float32 a) +{ + return a > 0.0f ? a : -a; +} + +/// 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); + } + + 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) + { + col1 = c1; + col2 = c2; + } + + /// Construct this matrix using scalars. + b2Mat22(float32 a11, float32 a12, float32 a21, float32 a22) + { + col1.x = a11; col1.y = a21; + col2.x = a12; col2.y = a22; + } + + /// Construct this matrix using an angle. This matrix becomes + /// an orthonormal rotation matrix. + explicit b2Mat22(float32 angle) + { + // TODO_ERIN compute sin+cos together. + float32 c = cosf(angle), s = sinf(angle); + col1.x = c; col2.x = -s; + col1.y = s; col2.y = c; + } + + /// Initialize this matrix using columns. + void Set(const b2Vec2& c1, const b2Vec2& c2) + { + col1 = c1; + col2 = c2; + } + + /// Initialize this matrix using an angle. This matrix becomes + /// an orthonormal rotation matrix. + void Set(float32 angle) + { + float32 c = cosf(angle), s = sinf(angle); + col1.x = c; col2.x = -s; + col1.y = s; col2.y = c; + } + + /// Set this to the identity matrix. + void SetIdentity() + { + col1.x = 1.0f; col2.x = 0.0f; + col1.y = 0.0f; col2.y = 1.0f; + } + + /// Set this matrix to all zeros. + void SetZero() + { + col1.x = 0.0f; col2.x = 0.0f; + col1.y = 0.0f; col2.y = 0.0f; + } + + /// Extract the angle from this matrix (assumed to be + /// a rotation matrix). + float32 GetAngle() const + { + return b2Atan2(col1.y, col1.x); + } + + b2Mat22 GetInverse() const + { + float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y; + b2Mat22 B; + float32 det = a * d - b * c; + if (det != 0.0f) + { + det = 1.0f / det; + } + B.col1.x = det * d; B.col2.x = -det * b; + B.col1.y = -det * c; B.col2.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 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.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 col1, col2; +}; + +/// 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) + { + col1 = c1; + col2 = c2; + col3 = c3; + } + + /// Set this matrix to all zeros. + void SetZero() + { + col1.SetZero(); + col2.SetZero(); + col3.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; + + b2Vec3 col1, col2, col3; +}; + +/// 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 (for performance). + b2Transform() {} + + /// Initialize using a position vector and a rotation matrix. + b2Transform(const b2Vec2& position, const b2Mat22& R) : position(position), R(R) {} + + /// Set this to the identity transform. + void SetIdentity() + { + position.SetZero(); + R.SetIdentity(); + } + + /// Set this based on the position and angle. + void Set(const b2Vec2& p, float32 angle) + { + position = p; + R.Set(angle); + } + + /// Calculate the angle that the rotation matrix represents. + float32 GetAngle() const + { + return b2Atan2(R.col1.y, R.col1.x); + } + + b2Vec2 position; + b2Mat22 R; +}; + +/// 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 alpha is a factor in [0,1], where 0 indicates t0. + void GetTransform(b2Transform* xf, float32 alpha) const; + + /// Advance the sweep forward, yielding a new initial state. + /// @param t the new initial time. + void Advance(float32 t); + + /// Normalize the angles. + void Normalize(); + + b2Vec2 localCenter; ///< local center of mass position + b2Vec2 c0, c; ///< center world positions + float32 a0, a; ///< world angles +}; + + +extern const b2Vec2 b2Vec2_zero; +extern const b2Mat22 b2Mat22_identity; +extern const b2Transform b2Transform_identity; + +/// 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.col1.x * v.x + A.col2.x * v.y, A.col1.y * v.x + A.col2.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.col1), b2Dot(v, A.col2)); +} + +/// 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.col1 + B.col1, A.col2 + B.col2); +} + +// A * B +inline b2Mat22 b2Mul(const b2Mat22& A, const b2Mat22& B) +{ + return b2Mat22(b2Mul(A, B.col1), b2Mul(A, B.col2)); +} + +// A^T * B +inline b2Mat22 b2MulT(const b2Mat22& A, const b2Mat22& B) +{ + b2Vec2 c1(b2Dot(A.col1, B.col1), b2Dot(A.col2, B.col1)); + b2Vec2 c2(b2Dot(A.col1, B.col2), b2Dot(A.col2, B.col2)); + return b2Mat22(c1, c2); +} + +/// Multiply a matrix times a vector. +inline b2Vec3 b2Mul(const b2Mat33& A, const b2Vec3& v) +{ + return v.x * A.col1 + v.y * A.col2 + v.z * A.col3; +} + +inline b2Vec2 b2Mul(const b2Transform& T, const b2Vec2& v) +{ + float32 x = T.position.x + T.R.col1.x * v.x + T.R.col2.x * v.y; + float32 y = T.position.y + T.R.col1.y * v.x + T.R.col2.y * v.y; + + return b2Vec2(x, y); +} + +inline b2Vec2 b2MulT(const b2Transform& T, const b2Vec2& v) +{ + return b2MulT(T.R, v - T.position); +} + +inline b2Vec2 b2Abs(const b2Vec2& a) +{ + return b2Vec2(b2Abs(a.x), b2Abs(a.y)); +} + +inline b2Mat22 b2Abs(const b2Mat22& A) +{ + return b2Mat22(b2Abs(A.col1), b2Abs(A.col2)); +} + +template +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 +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 +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 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 alpha) const +{ + xf->position = (1.0f - alpha) * c0 + alpha * c; + float32 angle = (1.0f - alpha) * a0 + alpha * a; + xf->R.Set(angle); + + // Shift to origin + xf->position -= b2Mul(xf->R, localCenter); +} + +inline void b2Sweep::Advance(float32 t) +{ + c0 = (1.0f - t) * c0 + t * c; + a0 = (1.0f - t) * a0 + t * a; +} + +/// 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 diff --git a/libs/box2d/src/Box2D/Common/b2Settings.cpp b/libs/box2d/src/Box2D/Common/b2Settings.cpp new file mode 100644 index 0000000..da30814 --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2Settings.cpp @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +b2Version b2_version = {2, 1, 2}; + +// Memory allocators. Modify these to use your own allocator. +void* b2Alloc(int32 size) +{ + return malloc(size); +} + +void b2Free(void* mem) +{ + free(mem); +} diff --git a/libs/box2d/src/Box2D/Common/b2Settings.h b/libs/box2d/src/Box2D/Common/b2Settings.h new file mode 100644 index 0000000..1aa8c26 --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2Settings.h @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +#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; + +#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. +#define b2_maxManifoldPoints 2 + +/// The maximum number of vertices on a convex polygon. +#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) + + +// 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_contactBaumgarte 0.2f + +// 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); + +/// 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; + +/// Friction mixing law. Feel free to customize this. +inline float32 b2MixFriction(float32 friction1, float32 friction2) +{ + return sqrtf(friction1 * friction2); +} + +/// Restitution mixing law. Feel free to customize this. +inline float32 b2MixRestitution(float32 restitution1, float32 restitution2) +{ + return restitution1 > restitution2 ? restitution1 : restitution2; +} + +#endif diff --git a/libs/box2d/src/Box2D/Common/b2StackAllocator.cpp b/libs/box2d/src/Box2D/Common/b2StackAllocator.cpp new file mode 100644 index 0000000..cb2c42e --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2StackAllocator.cpp @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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 +#include + +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; +} diff --git a/libs/box2d/src/Box2D/Common/b2StackAllocator.h b/libs/box2d/src/Box2D/Common/b2StackAllocator.h new file mode 100644 index 0000000..315cc02 --- /dev/null +++ b/libs/box2d/src/Box2D/Common/b2StackAllocator.h @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com +* +* 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