--- /dev/null
+Box2D/
+Contributions/
--- /dev/null
+// !$*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 = "<group>"; };
+ 4913307D1372616300DFB46D /* b2BroadPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = "<group>"; };
+ 4913307E1372616300DFB46D /* b2BroadPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = "<group>"; };
+ 4913307F1372616300DFB46D /* b2CollideCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = "<group>"; };
+ 491330801372616300DFB46D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = "<group>"; };
+ 491330811372616300DFB46D /* b2Collision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = "<group>"; };
+ 491330821372616300DFB46D /* b2Collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = "<group>"; };
+ 491330831372616300DFB46D /* b2Distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = "<group>"; };
+ 491330841372616300DFB46D /* b2Distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Distance.h; sourceTree = "<group>"; };
+ 491330851372616300DFB46D /* b2DynamicTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DynamicTree.cpp; sourceTree = "<group>"; };
+ 491330861372616300DFB46D /* b2DynamicTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DynamicTree.h; sourceTree = "<group>"; };
+ 491330871372616300DFB46D /* b2TimeOfImpact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TimeOfImpact.cpp; sourceTree = "<group>"; };
+ 491330881372616300DFB46D /* b2TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeOfImpact.h; sourceTree = "<group>"; };
+ 4913308A1372616300DFB46D /* b2CircleShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleShape.cpp; sourceTree = "<group>"; };
+ 4913308B1372616300DFB46D /* b2CircleShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = "<group>"; };
+ 4913308C1372616300DFB46D /* b2PolygonShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonShape.cpp; sourceTree = "<group>"; };
+ 4913308D1372616300DFB46D /* b2PolygonShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonShape.h; sourceTree = "<group>"; };
+ 4913308E1372616300DFB46D /* b2Shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Shape.h; sourceTree = "<group>"; };
+ 491330901372616300DFB46D /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = "<group>"; };
+ 491330911372616300DFB46D /* b2BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BlockAllocator.h; sourceTree = "<group>"; };
+ 491330921372616300DFB46D /* b2Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Math.cpp; sourceTree = "<group>"; };
+ 491330931372616300DFB46D /* b2Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Math.h; sourceTree = "<group>"; };
+ 491330941372616300DFB46D /* b2Settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Settings.cpp; sourceTree = "<group>"; };
+ 491330951372616300DFB46D /* b2Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Settings.h; sourceTree = "<group>"; };
+ 491330961372616300DFB46D /* b2StackAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2StackAllocator.cpp; sourceTree = "<group>"; };
+ 491330971372616300DFB46D /* b2StackAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = "<group>"; };
+ 491330991372616300DFB46D /* b2Body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Body.cpp; sourceTree = "<group>"; };
+ 4913309A1372616300DFB46D /* b2Body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Body.h; sourceTree = "<group>"; };
+ 4913309B1372616300DFB46D /* b2ContactManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactManager.cpp; sourceTree = "<group>"; };
+ 4913309C1372616300DFB46D /* b2ContactManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactManager.h; sourceTree = "<group>"; };
+ 4913309D1372616300DFB46D /* b2Fixture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Fixture.cpp; sourceTree = "<group>"; };
+ 4913309E1372616300DFB46D /* b2Fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = "<group>"; };
+ 4913309F1372616300DFB46D /* b2Island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = "<group>"; };
+ 491330A01372616300DFB46D /* b2Island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Island.h; sourceTree = "<group>"; };
+ 491330A11372616300DFB46D /* b2TimeStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeStep.h; sourceTree = "<group>"; };
+ 491330A21372616300DFB46D /* b2World.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2World.cpp; sourceTree = "<group>"; };
+ 491330A31372616300DFB46D /* b2World.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2World.h; sourceTree = "<group>"; };
+ 491330A41372616300DFB46D /* b2WorldCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WorldCallbacks.cpp; sourceTree = "<group>"; };
+ 491330A51372616300DFB46D /* b2WorldCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = "<group>"; };
+ 491330A71372616300DFB46D /* b2CircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = "<group>"; };
+ 491330A81372616300DFB46D /* b2CircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleContact.h; sourceTree = "<group>"; };
+ 491330A91372616300DFB46D /* b2Contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Contact.cpp; sourceTree = "<group>"; };
+ 491330AA1372616300DFB46D /* b2Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = "<group>"; };
+ 491330AB1372616300DFB46D /* b2ContactSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactSolver.cpp; sourceTree = "<group>"; };
+ 491330AC1372616300DFB46D /* b2ContactSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactSolver.h; sourceTree = "<group>"; };
+ 491330AD1372616300DFB46D /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = "<group>"; };
+ 491330AE1372616300DFB46D /* b2PolygonAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonAndCircleContact.h; sourceTree = "<group>"; };
+ 491330AF1372616300DFB46D /* b2PolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonContact.cpp; sourceTree = "<group>"; };
+ 491330B01372616300DFB46D /* b2PolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonContact.h; sourceTree = "<group>"; };
+ 491330B11372616300DFB46D /* b2TOISolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TOISolver.cpp; sourceTree = "<group>"; };
+ 491330B21372616300DFB46D /* b2TOISolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TOISolver.h; sourceTree = "<group>"; };
+ 491330B41372616300DFB46D /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = "<group>"; };
+ 491330B51372616300DFB46D /* b2DistanceJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DistanceJoint.h; sourceTree = "<group>"; };
+ 491330B61372616300DFB46D /* b2FrictionJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2FrictionJoint.cpp; sourceTree = "<group>"; };
+ 491330B71372616300DFB46D /* b2FrictionJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2FrictionJoint.h; sourceTree = "<group>"; };
+ 491330B81372616300DFB46D /* b2GearJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2GearJoint.cpp; sourceTree = "<group>"; };
+ 491330B91372616300DFB46D /* b2GearJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = "<group>"; };
+ 491330BA1372616300DFB46D /* b2Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Joint.cpp; sourceTree = "<group>"; };
+ 491330BB1372616300DFB46D /* b2Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Joint.h; sourceTree = "<group>"; };
+ 491330BC1372616300DFB46D /* b2LineJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2LineJoint.cpp; sourceTree = "<group>"; };
+ 491330BD1372616300DFB46D /* b2LineJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2LineJoint.h; sourceTree = "<group>"; };
+ 491330BE1372616300DFB46D /* b2MouseJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MouseJoint.cpp; sourceTree = "<group>"; };
+ 491330BF1372616300DFB46D /* b2MouseJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MouseJoint.h; sourceTree = "<group>"; };
+ 491330C01372616300DFB46D /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = "<group>"; };
+ 491330C11372616300DFB46D /* b2PrismaticJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PrismaticJoint.h; sourceTree = "<group>"; };
+ 491330C21372616300DFB46D /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = "<group>"; };
+ 491330C31372616300DFB46D /* b2PulleyJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PulleyJoint.h; sourceTree = "<group>"; };
+ 491330C41372616300DFB46D /* b2RevoluteJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2RevoluteJoint.cpp; sourceTree = "<group>"; };
+ 491330C51372616300DFB46D /* b2RevoluteJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2RevoluteJoint.h; sourceTree = "<group>"; };
+ 491330C61372616300DFB46D /* b2WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WeldJoint.cpp; sourceTree = "<group>"; };
+ 491330C71372616300DFB46D /* b2WeldJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = "<group>"; };
+ 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 = "<group>";
+ };
+ 491330601372610400DFB46D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 4913305F1372610400DFB46D /* libBox2D.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 4913307A1372616300DFB46D /* Box2D */ = {
+ isa = PBXGroup;
+ children = (
+ 4913307B1372616300DFB46D /* Box2D.h */,
+ 4913307C1372616300DFB46D /* Collision */,
+ 4913308F1372616300DFB46D /* Common */,
+ 491330981372616300DFB46D /* Dynamics */,
+ );
+ name = Box2D;
+ path = src/Box2D;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 491330891372616300DFB46D /* Shapes */ = {
+ isa = PBXGroup;
+ children = (
+ 4913308A1372616300DFB46D /* b2CircleShape.cpp */,
+ 4913308B1372616300DFB46D /* b2CircleShape.h */,
+ 4913308C1372616300DFB46D /* b2PolygonShape.cpp */,
+ 4913308D1372616300DFB46D /* b2PolygonShape.h */,
+ 4913308E1372616300DFB46D /* b2Shape.h */,
+ );
+ path = Shapes;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 491331291372630F00DFB46D /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 491331271372630700DFB46D /* UIKit.framework */,
+ 49133122137262F200DFB46D /* Foundation.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* 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 */;
+}
--- /dev/null
+// !$*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 = "<group>"; };
+ 491331991372653600DFB46D /* Box2DAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2DAppDelegate.h; sourceTree = "<group>"; };
+ 4913319A1372653600DFB46D /* Box2DAppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Box2DAppDelegate.mm; sourceTree = "<group>"; };
+ 4913319B1372653600DFB46D /* Box2DView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2DView.h; sourceTree = "<group>"; };
+ 4913319C1372653600DFB46D /* Box2DView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Box2DView.mm; sourceTree = "<group>"; };
+ 4913319D1372653600DFB46D /* Delegates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Delegates.h; sourceTree = "<group>"; };
+ 4913319E1372653600DFB46D /* GLES-Render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GLES-Render.h"; sourceTree = "<group>"; };
+ 4913319F1372653600DFB46D /* GLES-Render.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "GLES-Render.mm"; sourceTree = "<group>"; };
+ 491331A01372653600DFB46D /* iPhoneTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoneTest.h; sourceTree = "<group>"; };
+ 491331A11372653600DFB46D /* iPhoneTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iPhoneTest.mm; sourceTree = "<group>"; };
+ 491331A21372653600DFB46D /* iPhoneTestEntries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iPhoneTestEntries.mm; sourceTree = "<group>"; };
+ 491331A31372653600DFB46D /* TestEntriesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestEntriesViewController.h; sourceTree = "<group>"; };
+ 491331A41372653600DFB46D /* TestEntriesViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestEntriesViewController.mm; sourceTree = "<group>"; };
+ 491331A51372653600DFB46D /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = "<group>"; };
+ 491331A61372653600DFB46D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 491331A71372653600DFB46D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 491331A81372653600DFB46D /* MainWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = "<group>"; };
+ 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 = "<group>"; };
+ 4913320E13726B1F00DFB46D /* BodyTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BodyTypes.h; sourceTree = "<group>"; };
+ 4913320F13726B1F00DFB46D /* Breakable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Breakable.h; sourceTree = "<group>"; };
+ 4913321013726B1F00DFB46D /* Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridge.h; sourceTree = "<group>"; };
+ 4913321113726B1F00DFB46D /* BulletTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BulletTest.h; sourceTree = "<group>"; };
+ 4913321213726B1F00DFB46D /* Cantilever.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cantilever.h; sourceTree = "<group>"; };
+ 4913321313726B1F00DFB46D /* Car.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Car.h; sourceTree = "<group>"; };
+ 4913321413726B1F00DFB46D /* Chain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Chain.h; sourceTree = "<group>"; };
+ 4913321513726B1F00DFB46D /* CharacterCollision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterCollision.h; sourceTree = "<group>"; };
+ 4913321613726B1F00DFB46D /* CollisionFiltering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollisionFiltering.h; sourceTree = "<group>"; };
+ 4913321713726B1F00DFB46D /* CollisionProcessing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollisionProcessing.h; sourceTree = "<group>"; };
+ 4913321813726B1F00DFB46D /* CompoundShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompoundShapes.h; sourceTree = "<group>"; };
+ 4913321913726B1F00DFB46D /* Confined.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Confined.h; sourceTree = "<group>"; };
+ 4913321A13726B1F00DFB46D /* ContinuousTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContinuousTest.h; sourceTree = "<group>"; };
+ 4913321B13726B1F00DFB46D /* DistanceTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DistanceTest.h; sourceTree = "<group>"; };
+ 4913321C13726B1F00DFB46D /* Dominos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dominos.h; sourceTree = "<group>"; };
+ 4913321D13726B1F00DFB46D /* DynamicTreeTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicTreeTest.h; sourceTree = "<group>"; };
+ 4913321E13726B1F00DFB46D /* EdgeShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdgeShapes.h; sourceTree = "<group>"; };
+ 4913321F13726B1F00DFB46D /* EdgeTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EdgeTest.h; sourceTree = "<group>"; };
+ 4913322013726B1F00DFB46D /* Gears.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Gears.h; sourceTree = "<group>"; };
+ 4913322113726B1F00DFB46D /* LineJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineJoint.h; sourceTree = "<group>"; };
+ 4913322213726B1F00DFB46D /* OneSidedPlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OneSidedPlatform.h; sourceTree = "<group>"; };
+ 4913322313726B1F00DFB46D /* Pinball.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pinball.h; sourceTree = "<group>"; };
+ 4913322413726B1F00DFB46D /* PolyCollision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyCollision.h; sourceTree = "<group>"; };
+ 4913322513726B1F00DFB46D /* PolyShapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PolyShapes.h; sourceTree = "<group>"; };
+ 4913322613726B1F00DFB46D /* Prismatic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Prismatic.h; sourceTree = "<group>"; };
+ 4913322713726B1F00DFB46D /* Pulleys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pulleys.h; sourceTree = "<group>"; };
+ 4913322813726B1F00DFB46D /* Pyramid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pyramid.h; sourceTree = "<group>"; };
+ 4913322913726B1F00DFB46D /* RayCast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RayCast.h; sourceTree = "<group>"; };
+ 4913322A13726B1F00DFB46D /* Revolute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Revolute.h; sourceTree = "<group>"; };
+ 4913322B13726B1F00DFB46D /* Rope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Rope.h; sourceTree = "<group>"; };
+ 4913322C13726B1F00DFB46D /* RopeJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeJoint.h; sourceTree = "<group>"; };
+ 4913322D13726B1F00DFB46D /* SensorTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SensorTest.h; sourceTree = "<group>"; };
+ 4913322E13726B1F00DFB46D /* ShapeEditing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShapeEditing.h; sourceTree = "<group>"; };
+ 4913322F13726B1F00DFB46D /* SliderCrank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SliderCrank.h; sourceTree = "<group>"; };
+ 4913323013726B1F00DFB46D /* SphereStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SphereStack.h; sourceTree = "<group>"; };
+ 4913323113726B1F00DFB46D /* TheoJansen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TheoJansen.h; sourceTree = "<group>"; };
+ 4913323213726B1F00DFB46D /* Tiles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tiles.h; sourceTree = "<group>"; };
+ 4913323313726B1F00DFB46D /* TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TimeOfImpact.h; sourceTree = "<group>"; };
+ 4913323413726B1F00DFB46D /* VaryingFriction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VaryingFriction.h; sourceTree = "<group>"; };
+ 4913323513726B1F00DFB46D /* VaryingRestitution.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VaryingRestitution.h; sourceTree = "<group>"; };
+ 4913323613726B1F00DFB46D /* VerticalStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VerticalStack.h; sourceTree = "<group>"; };
+ 4913323713726B1F00DFB46D /* Web.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Web.h; sourceTree = "<group>"; };
+ 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 = "<group>";
+ };
+ 4913316A1372645C00DFB46D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 491331691372645C00DFB46D /* box2d-iphone.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 491331961372653600DFB46D /* iPhone */ = {
+ isa = PBXGroup;
+ children = (
+ 491331971372653600DFB46D /* Box2D_Prefix.pch */,
+ 491331981372653600DFB46D /* Classes */,
+ 491331A71372653600DFB46D /* main.m */,
+ 491331A81372653600DFB46D /* MainWindow.xib */,
+ );
+ path = iPhone;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 491331B31372654900DFB46D /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 491331A51372653600DFB46D /* Icon.png */,
+ 491331A61372653600DFB46D /* Info.plist */,
+ );
+ name = Resources;
+ path = iPhone;
+ sourceTree = "<group>";
+ };
+ 491331B51372661600DFB46D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 491331BC1372661700DFB46D /* libBox2D.a */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+/* 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 */;
+}
--- /dev/null
+// !$*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 = "<group>"; };
+ 49132F7513725CDD00DFB46D /* Box2DProj.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Box2DProj.xcconfig; sourceTree = "<group>"; };
+ 49132F7613725CDD00DFB46D /* Box2DTarget.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Box2DTarget.xcconfig; sourceTree = "<group>"; };
+ 49132F8013725D1000DFB46D /* Box2D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Box2D.h; sourceTree = "<group>"; };
+ 49132F8213725D1000DFB46D /* b2BroadPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = "<group>"; };
+ 49132F8313725D1000DFB46D /* b2BroadPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BroadPhase.h; sourceTree = "<group>"; };
+ 49132F8413725D1000DFB46D /* b2CollideCircle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollideCircle.cpp; sourceTree = "<group>"; };
+ 49132F8513725D1000DFB46D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = "<group>"; };
+ 49132F8613725D1000DFB46D /* b2Collision.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Collision.cpp; sourceTree = "<group>"; };
+ 49132F8713725D1000DFB46D /* b2Collision.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Collision.h; sourceTree = "<group>"; };
+ 49132F8813725D1000DFB46D /* b2Distance.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Distance.cpp; sourceTree = "<group>"; };
+ 49132F8913725D1000DFB46D /* b2Distance.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Distance.h; sourceTree = "<group>"; };
+ 49132F8A13725D1000DFB46D /* b2DynamicTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DynamicTree.cpp; sourceTree = "<group>"; };
+ 49132F8B13725D1000DFB46D /* b2DynamicTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DynamicTree.h; sourceTree = "<group>"; };
+ 49132F8C13725D1000DFB46D /* b2TimeOfImpact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TimeOfImpact.cpp; sourceTree = "<group>"; };
+ 49132F8D13725D1000DFB46D /* b2TimeOfImpact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeOfImpact.h; sourceTree = "<group>"; };
+ 49132F8F13725D1000DFB46D /* b2CircleShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleShape.cpp; sourceTree = "<group>"; };
+ 49132F9013725D1000DFB46D /* b2CircleShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = "<group>"; };
+ 49132F9113725D1000DFB46D /* b2PolygonShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonShape.cpp; sourceTree = "<group>"; };
+ 49132F9213725D1000DFB46D /* b2PolygonShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonShape.h; sourceTree = "<group>"; };
+ 49132F9313725D1000DFB46D /* b2Shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Shape.h; sourceTree = "<group>"; };
+ 49132F9513725D1000DFB46D /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = "<group>"; };
+ 49132F9613725D1000DFB46D /* b2BlockAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2BlockAllocator.h; sourceTree = "<group>"; };
+ 49132F9713725D1000DFB46D /* b2Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Math.cpp; sourceTree = "<group>"; };
+ 49132F9813725D1000DFB46D /* b2Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Math.h; sourceTree = "<group>"; };
+ 49132F9913725D1000DFB46D /* b2Settings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Settings.cpp; sourceTree = "<group>"; };
+ 49132F9A13725D1000DFB46D /* b2Settings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Settings.h; sourceTree = "<group>"; };
+ 49132F9B13725D1000DFB46D /* b2StackAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2StackAllocator.cpp; sourceTree = "<group>"; };
+ 49132F9C13725D1000DFB46D /* b2StackAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = "<group>"; };
+ 49132F9E13725D1000DFB46D /* b2Body.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Body.cpp; sourceTree = "<group>"; };
+ 49132F9F13725D1000DFB46D /* b2Body.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Body.h; sourceTree = "<group>"; };
+ 49132FA013725D1000DFB46D /* b2ContactManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactManager.cpp; sourceTree = "<group>"; };
+ 49132FA113725D1000DFB46D /* b2ContactManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactManager.h; sourceTree = "<group>"; };
+ 49132FA213725D1000DFB46D /* b2Fixture.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Fixture.cpp; sourceTree = "<group>"; };
+ 49132FA313725D1000DFB46D /* b2Fixture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Fixture.h; sourceTree = "<group>"; };
+ 49132FA413725D1000DFB46D /* b2Island.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Island.cpp; sourceTree = "<group>"; };
+ 49132FA513725D1000DFB46D /* b2Island.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Island.h; sourceTree = "<group>"; };
+ 49132FA613725D1000DFB46D /* b2TimeStep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TimeStep.h; sourceTree = "<group>"; };
+ 49132FA713725D1000DFB46D /* b2World.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2World.cpp; sourceTree = "<group>"; };
+ 49132FA813725D1000DFB46D /* b2World.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2World.h; sourceTree = "<group>"; };
+ 49132FA913725D1000DFB46D /* b2WorldCallbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WorldCallbacks.cpp; sourceTree = "<group>"; };
+ 49132FAA13725D1000DFB46D /* b2WorldCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WorldCallbacks.h; sourceTree = "<group>"; };
+ 49132FAC13725D1000DFB46D /* b2CircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2CircleContact.cpp; sourceTree = "<group>"; };
+ 49132FAD13725D1000DFB46D /* b2CircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2CircleContact.h; sourceTree = "<group>"; };
+ 49132FAE13725D1000DFB46D /* b2Contact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Contact.cpp; sourceTree = "<group>"; };
+ 49132FAF13725D1000DFB46D /* b2Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Contact.h; sourceTree = "<group>"; };
+ 49132FB013725D1000DFB46D /* b2ContactSolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2ContactSolver.cpp; sourceTree = "<group>"; };
+ 49132FB113725D1000DFB46D /* b2ContactSolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2ContactSolver.h; sourceTree = "<group>"; };
+ 49132FB213725D1000DFB46D /* b2PolygonAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonAndCircleContact.cpp; sourceTree = "<group>"; };
+ 49132FB313725D1000DFB46D /* b2PolygonAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonAndCircleContact.h; sourceTree = "<group>"; };
+ 49132FB413725D1000DFB46D /* b2PolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PolygonContact.cpp; sourceTree = "<group>"; };
+ 49132FB513725D1000DFB46D /* b2PolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PolygonContact.h; sourceTree = "<group>"; };
+ 49132FB613725D1000DFB46D /* b2TOISolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2TOISolver.cpp; sourceTree = "<group>"; };
+ 49132FB713725D1000DFB46D /* b2TOISolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2TOISolver.h; sourceTree = "<group>"; };
+ 49132FB913725D1000DFB46D /* b2DistanceJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2DistanceJoint.cpp; sourceTree = "<group>"; };
+ 49132FBA13725D1000DFB46D /* b2DistanceJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2DistanceJoint.h; sourceTree = "<group>"; };
+ 49132FBB13725D1000DFB46D /* b2FrictionJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2FrictionJoint.cpp; sourceTree = "<group>"; };
+ 49132FBC13725D1000DFB46D /* b2FrictionJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2FrictionJoint.h; sourceTree = "<group>"; };
+ 49132FBD13725D1000DFB46D /* b2GearJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2GearJoint.cpp; sourceTree = "<group>"; };
+ 49132FBE13725D1000DFB46D /* b2GearJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = "<group>"; };
+ 49132FBF13725D1000DFB46D /* b2Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2Joint.cpp; sourceTree = "<group>"; };
+ 49132FC013725D1000DFB46D /* b2Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2Joint.h; sourceTree = "<group>"; };
+ 49132FC113725D1000DFB46D /* b2LineJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2LineJoint.cpp; sourceTree = "<group>"; };
+ 49132FC213725D1000DFB46D /* b2LineJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2LineJoint.h; sourceTree = "<group>"; };
+ 49132FC313725D1000DFB46D /* b2MouseJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2MouseJoint.cpp; sourceTree = "<group>"; };
+ 49132FC413725D1000DFB46D /* b2MouseJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MouseJoint.h; sourceTree = "<group>"; };
+ 49132FC513725D1000DFB46D /* b2PrismaticJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PrismaticJoint.cpp; sourceTree = "<group>"; };
+ 49132FC613725D1000DFB46D /* b2PrismaticJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PrismaticJoint.h; sourceTree = "<group>"; };
+ 49132FC713725D1000DFB46D /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = "<group>"; };
+ 49132FC813725D1000DFB46D /* b2PulleyJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2PulleyJoint.h; sourceTree = "<group>"; };
+ 49132FC913725D1000DFB46D /* b2RevoluteJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2RevoluteJoint.cpp; sourceTree = "<group>"; };
+ 49132FCA13725D1000DFB46D /* b2RevoluteJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2RevoluteJoint.h; sourceTree = "<group>"; };
+ 49132FCB13725D1000DFB46D /* b2WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2WeldJoint.cpp; sourceTree = "<group>"; };
+ 49132FCC13725D1000DFB46D /* b2WeldJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = "<group>"; };
+/* 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 = "<group>";
+ };
+ 49132F7213725CDD00DFB46D /* Box2D */ = {
+ isa = PBXGroup;
+ children = (
+ 49132F7513725CDD00DFB46D /* Box2DProj.xcconfig */,
+ 49132F7613725CDD00DFB46D /* Box2DTarget.xcconfig */,
+ 49132F7313725CDD00DFB46D /* Supporting Files */,
+ );
+ path = Box2D;
+ sourceTree = "<group>";
+ };
+ 49132F7313725CDD00DFB46D /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 49132F7413725CDD00DFB46D /* Box2D-Prefix.pch */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+ 49132F7F13725D1000DFB46D /* Box2D */ = {
+ isa = PBXGroup;
+ children = (
+ 49132F8013725D1000DFB46D /* Box2D.h */,
+ 49132F8113725D1000DFB46D /* Collision */,
+ 49132F9413725D1000DFB46D /* Common */,
+ 49132F9D13725D1000DFB46D /* Dynamics */,
+ );
+ name = Box2D;
+ path = src/Box2D;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 49132F8E13725D1000DFB46D /* Shapes */ = {
+ isa = PBXGroup;
+ children = (
+ 49132F8F13725D1000DFB46D /* b2CircleShape.cpp */,
+ 49132F9013725D1000DFB46D /* b2CircleShape.h */,
+ 49132F9113725D1000DFB46D /* b2PolygonShape.cpp */,
+ 49132F9213725D1000DFB46D /* b2PolygonShape.h */,
+ 49132F9313725D1000DFB46D /* b2Shape.h */,
+ );
+ path = Shapes;
+ sourceTree = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+ 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 = "<group>";
+ };
+/* 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 */;
+}
--- /dev/null
+//
+// Prefix header for all source files of the 'Box2D' target in the 'Box2D' project
+//
+
+#ifdef __OBJC__
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#endif
--- /dev/null
+//
+// Box2DAppDelegate.h
+// Box2D
+//
+// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
+//
+
+#import <UIKit/UIKit.h>
+#import "TestEntriesViewController.h"
+#import "Delegates.h"
+
+@class Box2DView;
+
+@interface Box2DAppDelegate : NSObject <UIApplicationDelegate,TestSelectDelegate> {
+ UIWindow *window;
+ Box2DView *glView;
+ TestEntriesViewController *testEntriesView;
+}
+
+@property (nonatomic, retain) IBOutlet UIWindow *window;
+@property (nonatomic, retain) IBOutlet Box2DView *glView;
+
+@end
+
--- /dev/null
+//
+// Box2DAppDelegate.m
+// Box2D
+//
+// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
+//
+
+#import <UIKit/UIKit.h>
+#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
--- /dev/null
+//
+// Box2DView.h
+// Box2D OpenGL View
+//
+// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
+//
+
+
+#import <UIKit/UIKit.h>
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+
+#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 <UIAccelerometerDelegate> {
+
+@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<TestSelectDelegate> _delegate;
+
+}
+@property(assign) id<TestSelectDelegate> delegate;
+@property NSTimeInterval animationInterval;
+
+- (void)startAnimation;
+- (void)stopAnimation;
+- (void)drawView;
+-(void) selectTestEntry:(int) testIndex;
+
+@end
--- /dev/null
+//
+// Box2DView.mm
+// Box2D OpenGL View
+//
+// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
+//
+
+#import <QuartzCore/QuartzCore.h>
+#import <OpenGLES/EAGLDrawable.h>
+
+#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
--- /dev/null
+/*
+ * Delegates.h
+ * Box2D
+ *
+ * Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
+ *
+ *
+ */
+
+@protocol TestSelectDelegate <NSObject>
+ -(void) selectTest:(int) testIndex;
+ -(void) leaveTest;
+
+@end
\ No newline at end of file
--- /dev/null
+/*
+* 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 <UIKit/UIKit.h>
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+
+#include <Box2D/Box2D.h>
+
+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
--- /dev/null
+/*
+* 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 <cstdio>
+#include <cstdarg>
+
+#include <cstring>
+
+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);
+
+}
--- /dev/null
+//
+// TestEntriesViewController.h
+// Box2D
+//
+// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
+//
+
+#import <UIKit/UIKit.h>
+#import "iPhoneTest.h"
+#import "Delegates.h"
+
+@interface TestEntriesViewController : UITableViewController {
+ int32 testCount;
+ id<TestSelectDelegate> _delegate;
+}
+
+@property(assign) id<TestSelectDelegate> delegate;
+
+@end
--- /dev/null
+//
+// 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
+
--- /dev/null
+/*
+* 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 <UIKit/UIKit.h>
+#include <Box2D/Box2D.h>
+#include "GLES-Render.h"
+
+#include <cstdlib>
+
+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
--- /dev/null
+/*
+* 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 <cstdio>
+
+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));
+ }
+ }
+ }
+}
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include "iPhoneTest.h"\r
+#include <cstring>\r
+using namespace std;\r
+\r
+#include "ApplyForce.h"\r
+#include "BodyTypes.h"\r
+#include "Breakable.h"\r
+#include "Bridge.h"\r
+#include "BulletTest.h"\r
+#include "Cantilever.h"\r
+#include "Car.h"\r
+#include "ContinuousTest.h"\r
+#include "Chain.h"\r
+#include "CharacterCollision.h"\r
+#include "CollisionFiltering.h"\r
+#include "CollisionProcessing.h"\r
+#include "CompoundShapes.h"\r
+#include "Confined.h"\r
+#include "DistanceTest.h"\r
+#include "Dominos.h"\r
+#include "DynamicTreeTest.h"\r
+#include "EdgeShapes.h"\r
+#include "EdgeTest.h"\r
+#include "Gears.h"\r
+#include "OneSidedPlatform.h"\r
+#include "Pinball.h"\r
+#include "PolyCollision.h"\r
+#include "PolyShapes.h"\r
+#include "Prismatic.h"\r
+#include "Pulleys.h"\r
+#include "Pyramid.h"\r
+#include "RayCast.h"\r
+#include "Revolute.h"\r
+#include "Rope.h"\r
+#include "RopeJoint.h"\r
+#include "SensorTest.h"\r
+#include "ShapeEditing.h"\r
+#include "SliderCrank.h"\r
+#include "SphereStack.h"\r
+#include "TheoJansen.h"\r
+#include "Tiles.h"\r
+#include "TimeOfImpact.h"\r
+#include "VaryingFriction.h"\r
+#include "VaryingRestitution.h"\r
+#include "VerticalStack.h"\r
+#include "Web.h"\r
+\r
+TestEntry g_testEntries[] =\r
+{\r
+ {"Pulleys", Pulleys::Create},\r
+ {"SphereStack", SphereStack::Create},\r
+ {"Tiles", Tiles::Create},\r
+ {"Polygon Shapes", PolyShapes::Create},\r
+ {"Rope", Rope::Create},\r
+ {"Web", Web::Create},\r
+ {"Car", Car::Create},\r
+ {"Vertical Stack", VerticalStack::Create},\r
+ {"RopeJoint", RopeJoint::Create},\r
+ {"Character Collision", CharacterCollision::Create},\r
+ {"Edge Test", EdgeTest::Create},\r
+ {"One-Sided Platform", OneSidedPlatform::Create},\r
+ {"Pinball", Pinball::Create},\r
+ {"Bullet Test", BulletTest::Create},\r
+ {"Continuous Test", ContinuousTest::Create},\r
+ {"Time of Impact", TimeOfImpact::Create},\r
+ {"Ray-Cast", RayCast::Create},\r
+ {"Confined", Confined::Create},\r
+ {"Pyramid", Pyramid::Create},\r
+ {"Varying Restitution", VaryingRestitution::Create},\r
+ {"Theo Jansen's Walker", TheoJansen::Create},\r
+ {"Body Types", BodyTypes::Create},\r
+ {"Prismatic", Prismatic::Create},\r
+ {"Edge Shapes", EdgeShapes::Create},\r
+ {"PolyCollision", PolyCollision::Create},\r
+ {"Apply Force", ApplyForce::Create},\r
+ {"Cantilever", Cantilever::Create},\r
+ {"Bridge", Bridge::Create},\r
+ {"Breakable", Breakable::Create},\r
+ {"Chain", Chain::Create},\r
+ {"Collision Filtering", CollisionFiltering::Create},\r
+ {"Collision Processing", CollisionProcessing::Create},\r
+ {"Compound Shapes", CompoundShapes::Create},\r
+ {"Distance Test", DistanceTest::Create},\r
+ {"Dominos", Dominos::Create},\r
+ {"Dynamic Tree", DynamicTreeTest::Create},\r
+ {"Gears", Gears::Create},\r
+ {"Revolute", Revolute::Create},\r
+ {"Sensor Test", SensorTest::Create},\r
+ {"Shape Editing", ShapeEditing::Create},\r
+ {"Slider Crank", SliderCrank::Create},\r
+ {"Varying Friction", VaryingFriction::Create},\r
+ {NULL, NULL}\r
+};\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSMainNibFile</key>
+ <string>MainWindow</string>
+</dict>
+</plist>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
+ <data>
+ <int key="IBDocument.SystemTarget">528</int>
+ <string key="IBDocument.SystemVersion">9G55</string>
+ <string key="IBDocument.InterfaceBuilderVersion">677</string>
+ <string key="IBDocument.AppKitVersion">949.43</string>
+ <string key="IBDocument.HIToolboxVersion">353.00</string>
+ <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="8"/>
+ </object>
+ <object class="NSArray" key="IBDocument.PluginDependencies">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBProxyObject" id="841351856">
+ <string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
+ </object>
+ <object class="IBProxyObject" id="191355593">
+ <string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
+ </object>
+ <object class="IBUICustomObject" id="664661524"/>
+ <object class="IBUIWindow" id="380026005">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">1316</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBUIView" id="773737154">
+ <reference key="NSNextResponder" ref="380026005"/>
+ <int key="NSvFlags">1298</int>
+ <string key="NSFrameSize">{320, 480}</string>
+ <reference key="NSSuperview" ref="380026005"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ <object class="NSColorSpace" key="NSCustomColorSpace">
+ <int key="NSID">2</int>
+ </object>
+ </object>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ </object>
+ </object>
+ <object class="NSPSMatrix" key="NSFrameMatrix"/>
+ <string key="NSFrameSize">{320, 480}</string>
+ <reference key="NSSuperview"/>
+ <object class="NSColor" key="IBUIBackgroundColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEAA</bytes>
+ </object>
+ <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
+ <bool key="IBUIVisibleAtLaunch">YES</bool>
+ </object>
+ </object>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <object class="NSMutableArray" key="connectionRecords">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="841351856"/>
+ <reference key="destination" ref="664661524"/>
+ </object>
+ <int key="connectionID">4</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">window</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="380026005"/>
+ </object>
+ <int key="connectionID">5</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBCocoaTouchOutletConnection" key="connection">
+ <string key="label">glView</string>
+ <reference key="source" ref="664661524"/>
+ <reference key="destination" ref="773737154"/>
+ </object>
+ <int key="connectionID">9</int>
+ </object>
+ </object>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <object class="NSArray" key="orderedObjects">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <object class="NSArray" key="object" id="957960031">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <reference key="children" ref="1000"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="380026005"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="773737154"/>
+ </object>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="841351856"/>
+ <reference key="parent" ref="957960031"/>
+ <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">3</int>
+ <reference key="object" ref="664661524"/>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">8</int>
+ <reference key="object" ref="773737154"/>
+ <reference key="parent" ref="380026005"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="191355593"/>
+ <reference key="parent" ref="957960031"/>
+ </object>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="flattenedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>-1.CustomClassName</string>
+ <string>-2.CustomClassName</string>
+ <string>2.IBAttributePlaceholdersKey</string>
+ <string>2.IBEditorWindowLastContentRect</string>
+ <string>2.IBPluginDependency</string>
+ <string>3.CustomClassName</string>
+ <string>3.IBPluginDependency</string>
+ <string>8.CustomClassName</string>
+ <string>8.IBPluginDependency</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>UIApplication</string>
+ <string>UIResponder</string>
+ <object class="NSMutableDictionary">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <string>{{500, 343}, {320, 480}}</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>Box2DAppDelegate</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ <string>Box2DView</string>
+ <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
+ </object>
+ </object>
+ <object class="NSMutableDictionary" key="unlocalizedProperties">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="activeLocalization"/>
+ <object class="NSMutableDictionary" key="localizations">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ </object>
+ </object>
+ <nil key="sourceID"/>
+ <int key="maxID">9</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <object class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="IBPartialClassDescription">
+ <string key="className">Box2DAppDelegate</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>glView</string>
+ <string>window</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>Box2DView</string>
+ <string>UIWindow</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/Box2DAppDelegate.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">Box2DView</string>
+ <string key="superclassName">UIView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">Classes/Box2DView.h</string>
+ </object>
+ </object>
+ </object>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.LastKnownRelativeProjectPath">Box2D.xcodeproj</string>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ </data>
+</archive>
--- /dev/null
+//
+// main.m
+// Box2D
+//
+// Created by Simon Oliver on 14/01/2009.
+// Copyright HandCircus 2009. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+int main(int argc, char *argv[]) {
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ int retVal = UIApplicationMain(argc, argv, nil, nil);
+ [pool release];
+ return retVal;
+}
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef BOX2D_H\r
+#define BOX2D_H\r
+\r
+/**\r
+\mainpage Box2D API Documentation\r
+\r
+\section intro_sec Getting Started\r
+\r
+For documentation please see http://box2d.org/documentation.html\r
+\r
+For discussion please visit http://box2d.org/forum\r
+*/\r
+\r
+// These include files constitute the main Box2D API\r
+\r
+#include <Box2D/Common/b2Settings.h>\r
+\r
+#include <Box2D/Collision/Shapes/b2CircleShape.h>\r
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>\r
+\r
+#include <Box2D/Collision/b2BroadPhase.h>\r
+#include <Box2D/Collision/b2Distance.h>\r
+#include <Box2D/Collision/b2DynamicTree.h>\r
+#include <Box2D/Collision/b2TimeOfImpact.h>\r
+\r
+#include <Box2D/Dynamics/b2Body.h>\r
+#include <Box2D/Dynamics/b2Fixture.h>\r
+#include <Box2D/Dynamics/b2WorldCallbacks.h>\r
+#include <Box2D/Dynamics/b2TimeStep.h>\r
+#include <Box2D/Dynamics/b2World.h>\r
+\r
+#include <Box2D/Dynamics/Contacts/b2Contact.h>\r
+\r
+#include <Box2D/Dynamics/Joints/b2DistanceJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2FrictionJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2GearJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2LineJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2MouseJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2PrismaticJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2PulleyJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2RevoluteJoint.h>\r
+#include <Box2D/Dynamics/Joints/b2WeldJoint.h>\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/Shapes/b2CircleShape.h>\r
+#include <new>\r
+\r
+b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const\r
+{\r
+ void* mem = allocator->Allocate(sizeof(b2CircleShape));\r
+ b2CircleShape* clone = new (mem) b2CircleShape;\r
+ *clone = *this;\r
+ return clone;\r
+}\r
+\r
+bool b2CircleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const\r
+{\r
+ b2Vec2 center = transform.position + b2Mul(transform.R, m_p);\r
+ b2Vec2 d = p - center;\r
+ return b2Dot(d, d) <= m_radius * m_radius;\r
+}\r
+\r
+// Collision Detection in Interactive 3D Environments by Gino van den Bergen\r
+// From Section 3.1.2\r
+// x = s + a * r\r
+// norm(x) = radius\r
+bool b2CircleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const\r
+{\r
+ b2Vec2 position = transform.position + b2Mul(transform.R, m_p);\r
+ b2Vec2 s = input.p1 - position;\r
+ float32 b = b2Dot(s, s) - m_radius * m_radius;\r
+\r
+ // Solve quadratic equation.\r
+ b2Vec2 r = input.p2 - input.p1;\r
+ float32 c = b2Dot(s, r);\r
+ float32 rr = b2Dot(r, r);\r
+ float32 sigma = c * c - rr * b;\r
+\r
+ // Check for negative discriminant and short segment.\r
+ if (sigma < 0.0f || rr < b2_epsilon)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // Find the point of intersection of the line with the circle.\r
+ float32 a = -(c + b2Sqrt(sigma));\r
+\r
+ // Is the intersection point on the segment?\r
+ if (0.0f <= a && a <= input.maxFraction * rr)\r
+ {\r
+ a /= rr;\r
+ output->fraction = a;\r
+ output->normal = s + a * r;\r
+ output->normal.Normalize();\r
+ return true;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void b2CircleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform) const\r
+{\r
+ b2Vec2 p = transform.position + b2Mul(transform.R, m_p);\r
+ aabb->lowerBound.Set(p.x - m_radius, p.y - m_radius);\r
+ aabb->upperBound.Set(p.x + m_radius, p.y + m_radius);\r
+}\r
+\r
+void b2CircleShape::ComputeMass(b2MassData* massData, float32 density) const\r
+{\r
+ massData->mass = density * b2_pi * m_radius * m_radius;\r
+ massData->center = m_p;\r
+\r
+ // inertia about the local origin\r
+ massData->I = massData->mass * (0.5f * m_radius * m_radius + b2Dot(m_p, m_p));\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_CIRCLE_SHAPE_H\r
+#define B2_CIRCLE_SHAPE_H\r
+\r
+#include <Box2D/Collision/Shapes/b2Shape.h>\r
+\r
+/// A circle shape.\r
+class b2CircleShape : public b2Shape\r
+{\r
+public:\r
+ b2CircleShape();\r
+\r
+ /// Implement b2Shape.\r
+ b2Shape* Clone(b2BlockAllocator* allocator) const;\r
+\r
+ /// Implement b2Shape.\r
+ bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;\r
+\r
+ /// Implement b2Shape.\r
+ bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const;\r
+\r
+ /// @see b2Shape::ComputeAABB\r
+ void ComputeAABB(b2AABB* aabb, const b2Transform& transform) const;\r
+\r
+ /// @see b2Shape::ComputeMass\r
+ void ComputeMass(b2MassData* massData, float32 density) const;\r
+\r
+ /// Get the supporting vertex index in the given direction.\r
+ int32 GetSupport(const b2Vec2& d) const;\r
+\r
+ /// Get the supporting vertex in the given direction.\r
+ const b2Vec2& GetSupportVertex(const b2Vec2& d) const;\r
+\r
+ /// Get the vertex count.\r
+ int32 GetVertexCount() const { return 1; }\r
+\r
+ /// Get a vertex by index. Used by b2Distance.\r
+ const b2Vec2& GetVertex(int32 index) const;\r
+\r
+ /// Position\r
+ b2Vec2 m_p;\r
+};\r
+\r
+inline b2CircleShape::b2CircleShape()\r
+{\r
+ m_type = e_circle;\r
+ m_radius = 0.0f;\r
+ m_p.SetZero();\r
+}\r
+\r
+inline int32 b2CircleShape::GetSupport(const b2Vec2 &d) const\r
+{\r
+ B2_NOT_USED(d);\r
+ return 0;\r
+}\r
+\r
+inline const b2Vec2& b2CircleShape::GetSupportVertex(const b2Vec2 &d) const\r
+{\r
+ B2_NOT_USED(d);\r
+ return m_p;\r
+}\r
+\r
+inline const b2Vec2& b2CircleShape::GetVertex(int32 index) const\r
+{\r
+ B2_NOT_USED(index);\r
+ b2Assert(index == 0);\r
+ return m_p;\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>\r
+#include <new>\r
+\r
+b2Shape* b2PolygonShape::Clone(b2BlockAllocator* allocator) const\r
+{\r
+ void* mem = allocator->Allocate(sizeof(b2PolygonShape));\r
+ b2PolygonShape* clone = new (mem) b2PolygonShape;\r
+ *clone = *this;\r
+ return clone;\r
+}\r
+\r
+void b2PolygonShape::SetAsBox(float32 hx, float32 hy)\r
+{\r
+ m_vertexCount = 4;\r
+ m_vertices[0].Set(-hx, -hy);\r
+ m_vertices[1].Set( hx, -hy);\r
+ m_vertices[2].Set( hx, hy);\r
+ m_vertices[3].Set(-hx, hy);\r
+ m_normals[0].Set(0.0f, -1.0f);\r
+ m_normals[1].Set(1.0f, 0.0f);\r
+ m_normals[2].Set(0.0f, 1.0f);\r
+ m_normals[3].Set(-1.0f, 0.0f);\r
+ m_centroid.SetZero();\r
+}\r
+\r
+void b2PolygonShape::SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle)\r
+{\r
+ m_vertexCount = 4;\r
+ m_vertices[0].Set(-hx, -hy);\r
+ m_vertices[1].Set( hx, -hy);\r
+ m_vertices[2].Set( hx, hy);\r
+ m_vertices[3].Set(-hx, hy);\r
+ m_normals[0].Set(0.0f, -1.0f);\r
+ m_normals[1].Set(1.0f, 0.0f);\r
+ m_normals[2].Set(0.0f, 1.0f);\r
+ m_normals[3].Set(-1.0f, 0.0f);\r
+ m_centroid = center;\r
+\r
+ b2Transform xf;\r
+ xf.position = center;\r
+ xf.R.Set(angle);\r
+\r
+ // Transform vertices and normals.\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ m_vertices[i] = b2Mul(xf, m_vertices[i]);\r
+ m_normals[i] = b2Mul(xf.R, m_normals[i]);\r
+ }\r
+}\r
+\r
+void b2PolygonShape::SetAsEdge(const b2Vec2& v1, const b2Vec2& v2)\r
+{\r
+ m_vertexCount = 2;\r
+ m_vertices[0] = v1;\r
+ m_vertices[1] = v2;\r
+ m_centroid = 0.5f * (v1 + v2);\r
+ m_normals[0] = b2Cross(v2 - v1, 1.0f);\r
+ m_normals[0].Normalize();\r
+ m_normals[1] = -m_normals[0];\r
+}\r
+\r
+static b2Vec2 ComputeCentroid(const b2Vec2* vs, int32 count)\r
+{\r
+ b2Assert(count >= 2);\r
+\r
+ b2Vec2 c; c.Set(0.0f, 0.0f);\r
+ float32 area = 0.0f;\r
+\r
+ if (count == 2)\r
+ {\r
+ c = 0.5f * (vs[0] + vs[1]);\r
+ return c;\r
+ }\r
+\r
+ // pRef is the reference point for forming triangles.\r
+ // It's location doesn't change the result (except for rounding error).\r
+ b2Vec2 pRef(0.0f, 0.0f);\r
+#if 0\r
+ // This code would put the reference point inside the polygon.\r
+ for (int32 i = 0; i < count; ++i)\r
+ {\r
+ pRef += vs[i];\r
+ }\r
+ pRef *= 1.0f / count;\r
+#endif\r
+\r
+ const float32 inv3 = 1.0f / 3.0f;\r
+\r
+ for (int32 i = 0; i < count; ++i)\r
+ {\r
+ // Triangle vertices.\r
+ b2Vec2 p1 = pRef;\r
+ b2Vec2 p2 = vs[i];\r
+ b2Vec2 p3 = i + 1 < count ? vs[i+1] : vs[0];\r
+\r
+ b2Vec2 e1 = p2 - p1;\r
+ b2Vec2 e2 = p3 - p1;\r
+\r
+ float32 D = b2Cross(e1, e2);\r
+\r
+ float32 triangleArea = 0.5f * D;\r
+ area += triangleArea;\r
+\r
+ // Area weighted centroid\r
+ c += triangleArea * inv3 * (p1 + p2 + p3);\r
+ }\r
+\r
+ // Centroid\r
+ b2Assert(area > b2_epsilon);\r
+ c *= 1.0f / area;\r
+ return c;\r
+}\r
+\r
+void b2PolygonShape::Set(const b2Vec2* vertices, int32 count)\r
+{\r
+ b2Assert(2 <= count && count <= b2_maxPolygonVertices);\r
+ m_vertexCount = count;\r
+\r
+ // Copy vertices.\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ m_vertices[i] = vertices[i];\r
+ }\r
+\r
+ // Compute normals. Ensure the edges have non-zero length.\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ int32 i1 = i;\r
+ int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0;\r
+ b2Vec2 edge = m_vertices[i2] - m_vertices[i1];\r
+ b2Assert(edge.LengthSquared() > b2_epsilon * b2_epsilon);\r
+ m_normals[i] = b2Cross(edge, 1.0f);\r
+ m_normals[i].Normalize();\r
+ }\r
+\r
+#ifdef _DEBUG\r
+ // Ensure the polygon is convex and the interior\r
+ // is to the left of each edge.\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ int32 i1 = i;\r
+ int32 i2 = i + 1 < m_vertexCount ? i + 1 : 0;\r
+ b2Vec2 edge = m_vertices[i2] - m_vertices[i1];\r
+\r
+ for (int32 j = 0; j < m_vertexCount; ++j)\r
+ {\r
+ // Don't check vertices on the current edge.\r
+ if (j == i1 || j == i2)\r
+ {\r
+ continue;\r
+ }\r
+ \r
+ b2Vec2 r = m_vertices[j] - m_vertices[i1];\r
+\r
+ // Your polygon is non-convex (it has an indentation) or\r
+ // has colinear edges.\r
+ float32 s = b2Cross(edge, r);\r
+ b2Assert(s > 0.0f);\r
+ }\r
+ }\r
+#endif\r
+\r
+ // Compute the polygon centroid.\r
+ m_centroid = ComputeCentroid(m_vertices, m_vertexCount);\r
+}\r
+\r
+bool b2PolygonShape::TestPoint(const b2Transform& xf, const b2Vec2& p) const\r
+{\r
+ b2Vec2 pLocal = b2MulT(xf.R, p - xf.position);\r
+\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ float32 dot = b2Dot(m_normals[i], pLocal - m_vertices[i]);\r
+ if (dot > 0.0f)\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+bool b2PolygonShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& xf) const\r
+{\r
+ // Put the ray into the polygon's frame of reference.\r
+ b2Vec2 p1 = b2MulT(xf.R, input.p1 - xf.position);\r
+ b2Vec2 p2 = b2MulT(xf.R, input.p2 - xf.position);\r
+ b2Vec2 d = p2 - p1;\r
+\r
+ if (m_vertexCount == 2)\r
+ {\r
+ b2Vec2 v1 = m_vertices[0];\r
+ b2Vec2 v2 = m_vertices[1];\r
+ b2Vec2 normal = m_normals[0];\r
+\r
+ // q = p1 + t * d\r
+ // dot(normal, q - v1) = 0\r
+ // dot(normal, p1 - v1) + t * dot(normal, d) = 0\r
+ float32 numerator = b2Dot(normal, v1 - p1);\r
+ float32 denominator = b2Dot(normal, d);\r
+\r
+ if (denominator == 0.0f)\r
+ {\r
+ return false;\r
+ }\r
+ \r
+ float32 t = numerator / denominator;\r
+ if (t < 0.0f || 1.0f < t)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ b2Vec2 q = p1 + t * d;\r
+\r
+ // q = v1 + s * r\r
+ // s = dot(q - v1, r) / dot(r, r)\r
+ b2Vec2 r = v2 - v1;\r
+ float32 rr = b2Dot(r, r);\r
+ if (rr == 0.0f)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ float32 s = b2Dot(q - v1, r) / rr;\r
+ if (s < 0.0f || 1.0f < s)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ output->fraction = t;\r
+ if (numerator > 0.0f)\r
+ {\r
+ output->normal = -normal;\r
+ }\r
+ else\r
+ {\r
+ output->normal = normal;\r
+ }\r
+ return true;\r
+ }\r
+ else\r
+ {\r
+ float32 lower = 0.0f, upper = input.maxFraction;\r
+\r
+ int32 index = -1;\r
+\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ // p = p1 + a * d\r
+ // dot(normal, p - v) = 0\r
+ // dot(normal, p1 - v) + a * dot(normal, d) = 0\r
+ float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1);\r
+ float32 denominator = b2Dot(m_normals[i], d);\r
+\r
+ if (denominator == 0.0f)\r
+ { \r
+ if (numerator < 0.0f)\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // Note: we want this predicate without division:\r
+ // lower < numerator / denominator, where denominator < 0\r
+ // Since denominator < 0, we have to flip the inequality:\r
+ // lower < numerator / denominator <==> denominator * lower > numerator.\r
+ if (denominator < 0.0f && numerator < lower * denominator)\r
+ {\r
+ // Increase lower.\r
+ // The segment enters this half-space.\r
+ lower = numerator / denominator;\r
+ index = i;\r
+ }\r
+ else if (denominator > 0.0f && numerator < upper * denominator)\r
+ {\r
+ // Decrease upper.\r
+ // The segment exits this half-space.\r
+ upper = numerator / denominator;\r
+ }\r
+ }\r
+\r
+ // The use of epsilon here causes the assert on lower to trip\r
+ // in some cases. Apparently the use of epsilon was to make edge\r
+ // shapes work, but now those are handled separately.\r
+ //if (upper < lower - b2_epsilon)\r
+ if (upper < lower)\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ b2Assert(0.0f <= lower && lower <= input.maxFraction);\r
+\r
+ if (index >= 0)\r
+ {\r
+ output->fraction = lower;\r
+ output->normal = b2Mul(xf.R, m_normals[index]);\r
+ return true;\r
+ }\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+void b2PolygonShape::ComputeAABB(b2AABB* aabb, const b2Transform& xf) const\r
+{\r
+ b2Vec2 lower = b2Mul(xf, m_vertices[0]);\r
+ b2Vec2 upper = lower;\r
+\r
+ for (int32 i = 1; i < m_vertexCount; ++i)\r
+ {\r
+ b2Vec2 v = b2Mul(xf, m_vertices[i]);\r
+ lower = b2Min(lower, v);\r
+ upper = b2Max(upper, v);\r
+ }\r
+\r
+ b2Vec2 r(m_radius, m_radius);\r
+ aabb->lowerBound = lower - r;\r
+ aabb->upperBound = upper + r;\r
+}\r
+\r
+void b2PolygonShape::ComputeMass(b2MassData* massData, float32 density) const\r
+{\r
+ // Polygon mass, centroid, and inertia.\r
+ // Let rho be the polygon density in mass per unit area.\r
+ // Then:\r
+ // mass = rho * int(dA)\r
+ // centroid.x = (1/mass) * rho * int(x * dA)\r
+ // centroid.y = (1/mass) * rho * int(y * dA)\r
+ // I = rho * int((x*x + y*y) * dA)\r
+ //\r
+ // We can compute these integrals by summing all the integrals\r
+ // for each triangle of the polygon. To evaluate the integral\r
+ // for a single triangle, we make a change of variables to\r
+ // the (u,v) coordinates of the triangle:\r
+ // x = x0 + e1x * u + e2x * v\r
+ // y = y0 + e1y * u + e2y * v\r
+ // where 0 <= u && 0 <= v && u + v <= 1.\r
+ //\r
+ // We integrate u from [0,1-v] and then v from [0,1].\r
+ // We also need to use the Jacobian of the transformation:\r
+ // D = cross(e1, e2)\r
+ //\r
+ // Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)\r
+ //\r
+ // The rest of the derivation is handled by computer algebra.\r
+\r
+ b2Assert(m_vertexCount >= 2);\r
+\r
+ // A line segment has zero mass.\r
+ if (m_vertexCount == 2)\r
+ {\r
+ massData->center = 0.5f * (m_vertices[0] + m_vertices[1]);\r
+ massData->mass = 0.0f;\r
+ massData->I = 0.0f;\r
+ return;\r
+ }\r
+\r
+ b2Vec2 center; center.Set(0.0f, 0.0f);\r
+ float32 area = 0.0f;\r
+ float32 I = 0.0f;\r
+\r
+ // pRef is the reference point for forming triangles.\r
+ // It's location doesn't change the result (except for rounding error).\r
+ b2Vec2 pRef(0.0f, 0.0f);\r
+#if 0\r
+ // This code would put the reference point inside the polygon.\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ pRef += m_vertices[i];\r
+ }\r
+ pRef *= 1.0f / count;\r
+#endif\r
+\r
+ const float32 k_inv3 = 1.0f / 3.0f;\r
+\r
+ for (int32 i = 0; i < m_vertexCount; ++i)\r
+ {\r
+ // Triangle vertices.\r
+ b2Vec2 p1 = pRef;\r
+ b2Vec2 p2 = m_vertices[i];\r
+ b2Vec2 p3 = i + 1 < m_vertexCount ? m_vertices[i+1] : m_vertices[0];\r
+\r
+ b2Vec2 e1 = p2 - p1;\r
+ b2Vec2 e2 = p3 - p1;\r
+\r
+ float32 D = b2Cross(e1, e2);\r
+\r
+ float32 triangleArea = 0.5f * D;\r
+ area += triangleArea;\r
+\r
+ // Area weighted centroid\r
+ center += triangleArea * k_inv3 * (p1 + p2 + p3);\r
+\r
+ float32 px = p1.x, py = p1.y;\r
+ float32 ex1 = e1.x, ey1 = e1.y;\r
+ float32 ex2 = e2.x, ey2 = e2.y;\r
+\r
+ float32 intx2 = k_inv3 * (0.25f * (ex1*ex1 + ex2*ex1 + ex2*ex2) + (px*ex1 + px*ex2)) + 0.5f*px*px;\r
+ float32 inty2 = k_inv3 * (0.25f * (ey1*ey1 + ey2*ey1 + ey2*ey2) + (py*ey1 + py*ey2)) + 0.5f*py*py;\r
+\r
+ I += D * (intx2 + inty2);\r
+ }\r
+\r
+ // Total mass\r
+ massData->mass = density * area;\r
+\r
+ // Center of mass\r
+ b2Assert(area > b2_epsilon);\r
+ center *= 1.0f / area;\r
+ massData->center = center;\r
+\r
+ // Inertia tensor relative to the local origin.\r
+ massData->I = density * I;\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_POLYGON_SHAPE_H\r
+#define B2_POLYGON_SHAPE_H\r
+\r
+#include <Box2D/Collision/Shapes/b2Shape.h>\r
+\r
+/// A convex polygon. It is assumed that the interior of the polygon is to\r
+/// the left of each edge.\r
+class b2PolygonShape : public b2Shape\r
+{\r
+public:\r
+ b2PolygonShape();\r
+\r
+ /// Implement b2Shape.\r
+ b2Shape* Clone(b2BlockAllocator* allocator) const;\r
+\r
+ /// Copy vertices. This assumes the vertices define a convex polygon.\r
+ /// It is assumed that the exterior is the the right of each edge.\r
+ void Set(const b2Vec2* vertices, int32 vertexCount);\r
+\r
+ /// Build vertices to represent an axis-aligned box.\r
+ /// @param hx the half-width.\r
+ /// @param hy the half-height.\r
+ void SetAsBox(float32 hx, float32 hy);\r
+\r
+ /// Build vertices to represent an oriented box.\r
+ /// @param hx the half-width.\r
+ /// @param hy the half-height.\r
+ /// @param center the center of the box in local coordinates.\r
+ /// @param angle the rotation of the box in local coordinates.\r
+ void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);\r
+\r
+ /// Set this as a single edge.\r
+ void SetAsEdge(const b2Vec2& v1, const b2Vec2& v2);\r
+\r
+ /// @see b2Shape::TestPoint\r
+ bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;\r
+\r
+ /// Implement b2Shape.\r
+ bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const;\r
+\r
+ /// @see b2Shape::ComputeAABB\r
+ void ComputeAABB(b2AABB* aabb, const b2Transform& transform) const;\r
+\r
+ /// @see b2Shape::ComputeMass\r
+ void ComputeMass(b2MassData* massData, float32 density) const;\r
+\r
+ /// Get the supporting vertex index in the given direction.\r
+ int32 GetSupport(const b2Vec2& d) const;\r
+\r
+ /// Get the supporting vertex in the given direction.\r
+ const b2Vec2& GetSupportVertex(const b2Vec2& d) const;\r
+\r
+ /// Get the vertex count.\r
+ int32 GetVertexCount() const { return m_vertexCount; }\r
+\r
+ /// Get a vertex by index.\r
+ const b2Vec2& GetVertex(int32 index) const;\r
+\r
+ b2Vec2 m_centroid;\r
+ b2Vec2 m_vertices[b2_maxPolygonVertices];\r
+ b2Vec2 m_normals[b2_maxPolygonVertices];\r
+ int32 m_vertexCount;\r
+};\r
+\r
+inline b2PolygonShape::b2PolygonShape()\r
+{\r
+ m_type = e_polygon;\r
+ m_radius = b2_polygonRadius;\r
+ m_vertexCount = 0;\r
+ m_centroid.SetZero();\r
+}\r
+\r
+inline int32 b2PolygonShape::GetSupport(const b2Vec2& d) const\r
+{\r
+ int32 bestIndex = 0;\r
+ float32 bestValue = b2Dot(m_vertices[0], d);\r
+ for (int32 i = 1; i < m_vertexCount; ++i)\r
+ {\r
+ float32 value = b2Dot(m_vertices[i], d);\r
+ if (value > bestValue)\r
+ {\r
+ bestIndex = i;\r
+ bestValue = value;\r
+ }\r
+ }\r
+\r
+ return bestIndex;\r
+}\r
+\r
+inline const b2Vec2& b2PolygonShape::GetSupportVertex(const b2Vec2& d) const\r
+{\r
+ int32 bestIndex = 0;\r
+ float32 bestValue = b2Dot(m_vertices[0], d);\r
+ for (int32 i = 1; i < m_vertexCount; ++i)\r
+ {\r
+ float32 value = b2Dot(m_vertices[i], d);\r
+ if (value > bestValue)\r
+ {\r
+ bestIndex = i;\r
+ bestValue = value;\r
+ }\r
+ }\r
+\r
+ return m_vertices[bestIndex];\r
+}\r
+\r
+inline const b2Vec2& b2PolygonShape::GetVertex(int32 index) const\r
+{\r
+ b2Assert(0 <= index && index < m_vertexCount);\r
+ return m_vertices[index];\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_SHAPE_H\r
+#define B2_SHAPE_H\r
+\r
+#include <Box2D/Common/b2BlockAllocator.h>\r
+#include <Box2D/Common/b2Math.h>\r
+#include <Box2D/Collision/b2Collision.h>\r
+\r
+/// This holds the mass data computed for a shape.\r
+struct b2MassData\r
+{\r
+ /// The mass of the shape, usually in kilograms.\r
+ float32 mass;\r
+\r
+ /// The position of the shape's centroid relative to the shape's origin.\r
+ b2Vec2 center;\r
+\r
+ /// The rotational inertia of the shape about the local origin.\r
+ float32 I;\r
+};\r
+\r
+/// A shape is used for collision detection. You can create a shape however you like.\r
+/// Shapes used for simulation in b2World are created automatically when a b2Fixture\r
+/// is created.\r
+class b2Shape\r
+{\r
+public:\r
+ \r
+ enum Type\r
+ {\r
+ e_unknown= -1,\r
+ e_circle = 0,\r
+ e_polygon = 1,\r
+ e_typeCount = 2,\r
+ };\r
+\r
+ b2Shape() { m_type = e_unknown; }\r
+ virtual ~b2Shape() {}\r
+\r
+ /// Clone the concrete shape using the provided allocator.\r
+ virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;\r
+\r
+ /// Get the type of this shape. You can use this to down cast to the concrete shape.\r
+ /// @return the shape type.\r
+ Type GetType() const;\r
+\r
+ /// Test a point for containment in this shape. This only works for convex shapes.\r
+ /// @param xf the shape world transform.\r
+ /// @param p a point in world coordinates.\r
+ virtual bool TestPoint(const b2Transform& xf, const b2Vec2& p) const = 0;\r
+\r
+ /// Cast a ray against this shape.\r
+ /// @param output the ray-cast results.\r
+ /// @param input the ray-cast input parameters.\r
+ /// @param transform the transform to be applied to the shape.\r
+ virtual bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const = 0;\r
+\r
+ /// Given a transform, compute the associated axis aligned bounding box for this shape.\r
+ /// @param aabb returns the axis aligned box.\r
+ /// @param xf the world transform of the shape.\r
+ virtual void ComputeAABB(b2AABB* aabb, const b2Transform& xf) const = 0;\r
+\r
+ /// Compute the mass properties of this shape using its dimensions and density.\r
+ /// The inertia tensor is computed about the local origin.\r
+ /// @param massData returns the mass data for this shape.\r
+ /// @param density the density in kilograms per meter squared.\r
+ virtual void ComputeMass(b2MassData* massData, float32 density) const = 0;\r
+\r
+ Type m_type;\r
+ float32 m_radius;\r
+};\r
+\r
+inline b2Shape::Type b2Shape::GetType() const\r
+{\r
+ return m_type;\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2BroadPhase.h>\r
+#include <cstring>\r
+\r
+b2BroadPhase::b2BroadPhase()\r
+{\r
+ m_proxyCount = 0;\r
+\r
+ m_pairCapacity = 16;\r
+ m_pairCount = 0;\r
+ m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));\r
+\r
+ m_moveCapacity = 16;\r
+ m_moveCount = 0;\r
+ m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));\r
+}\r
+\r
+b2BroadPhase::~b2BroadPhase()\r
+{\r
+ b2Free(m_moveBuffer);\r
+ b2Free(m_pairBuffer);\r
+}\r
+\r
+int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData)\r
+{\r
+ int32 proxyId = m_tree.CreateProxy(aabb, userData);\r
+ ++m_proxyCount;\r
+ BufferMove(proxyId);\r
+ return proxyId;\r
+}\r
+\r
+void b2BroadPhase::DestroyProxy(int32 proxyId)\r
+{\r
+ UnBufferMove(proxyId);\r
+ --m_proxyCount;\r
+ m_tree.DestroyProxy(proxyId);\r
+}\r
+\r
+void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)\r
+{\r
+ bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement);\r
+ if (buffer)\r
+ {\r
+ BufferMove(proxyId);\r
+ }\r
+}\r
+\r
+void b2BroadPhase::BufferMove(int32 proxyId)\r
+{\r
+ if (m_moveCount == m_moveCapacity)\r
+ {\r
+ int32* oldBuffer = m_moveBuffer;\r
+ m_moveCapacity *= 2;\r
+ m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32));\r
+ memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32));\r
+ b2Free(oldBuffer);\r
+ }\r
+\r
+ m_moveBuffer[m_moveCount] = proxyId;\r
+ ++m_moveCount;\r
+}\r
+\r
+void b2BroadPhase::UnBufferMove(int32 proxyId)\r
+{\r
+ for (int32 i = 0; i < m_moveCount; ++i)\r
+ {\r
+ if (m_moveBuffer[i] == proxyId)\r
+ {\r
+ m_moveBuffer[i] = e_nullProxy;\r
+ return;\r
+ }\r
+ }\r
+}\r
+\r
+// This is called from b2DynamicTree::Query when we are gathering pairs.\r
+bool b2BroadPhase::QueryCallback(int32 proxyId)\r
+{\r
+ // A proxy cannot form a pair with itself.\r
+ if (proxyId == m_queryProxyId)\r
+ {\r
+ return true;\r
+ }\r
+\r
+ // Grow the pair buffer as needed.\r
+ if (m_pairCount == m_pairCapacity)\r
+ {\r
+ b2Pair* oldBuffer = m_pairBuffer;\r
+ m_pairCapacity *= 2;\r
+ m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair));\r
+ memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair));\r
+ b2Free(oldBuffer);\r
+ }\r
+\r
+ m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId);\r
+ m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId);\r
+ ++m_pairCount;\r
+\r
+ return true;\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_BROAD_PHASE_H\r
+#define B2_BROAD_PHASE_H\r
+\r
+#include <Box2D/Common/b2Settings.h>\r
+#include <Box2D/Collision/b2Collision.h>\r
+#include <Box2D/Collision/b2DynamicTree.h>\r
+#include <algorithm>\r
+\r
+struct b2Pair\r
+{\r
+ int32 proxyIdA;\r
+ int32 proxyIdB;\r
+ int32 next;\r
+};\r
+\r
+/// The broad-phase is used for computing pairs and performing volume queries and ray casts.\r
+/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.\r
+/// It is up to the client to consume the new pairs and to track subsequent overlap.\r
+class b2BroadPhase\r
+{\r
+public:\r
+\r
+ enum\r
+ {\r
+ e_nullProxy = -1,\r
+ };\r
+\r
+ b2BroadPhase();\r
+ ~b2BroadPhase();\r
+\r
+ /// Create a proxy with an initial AABB. Pairs are not reported until\r
+ /// UpdatePairs is called.\r
+ int32 CreateProxy(const b2AABB& aabb, void* userData);\r
+\r
+ /// Destroy a proxy. It is up to the client to remove any pairs.\r
+ void DestroyProxy(int32 proxyId);\r
+\r
+ /// Call MoveProxy as many times as you like, then when you are done\r
+ /// call UpdatePairs to finalized the proxy pairs (for your time step).\r
+ void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);\r
+\r
+ /// Get the fat AABB for a proxy.\r
+ const b2AABB& GetFatAABB(int32 proxyId) const;\r
+\r
+ /// Get user data from a proxy. Returns NULL if the id is invalid.\r
+ void* GetUserData(int32 proxyId) const;\r
+\r
+ /// Test overlap of fat AABBs.\r
+ bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;\r
+\r
+ /// Get the number of proxies.\r
+ int32 GetProxyCount() const;\r
+\r
+ /// Update the pairs. This results in pair callbacks. This can only add pairs.\r
+ template <typename T>\r
+ void UpdatePairs(T* callback);\r
+\r
+ /// Query an AABB for overlapping proxies. The callback class\r
+ /// is called for each proxy that overlaps the supplied AABB.\r
+ template <typename T>\r
+ void Query(T* callback, const b2AABB& aabb) const;\r
+\r
+ /// Ray-cast against the proxies in the tree. This relies on the callback\r
+ /// to perform a exact ray-cast in the case were the proxy contains a shape.\r
+ /// The callback also performs the any collision filtering. This has performance\r
+ /// roughly equal to k * log(n), where k is the number of collisions and n is the\r
+ /// number of proxies in the tree.\r
+ /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).\r
+ /// @param callback a callback class that is called for each proxy that is hit by the ray.\r
+ template <typename T>\r
+ void RayCast(T* callback, const b2RayCastInput& input) const;\r
+\r
+ /// Compute the height of the embedded tree.\r
+ int32 ComputeHeight() const;\r
+\r
+private:\r
+\r
+ friend class b2DynamicTree;\r
+\r
+ void BufferMove(int32 proxyId);\r
+ void UnBufferMove(int32 proxyId);\r
+\r
+ bool QueryCallback(int32 proxyId);\r
+\r
+ b2DynamicTree m_tree;\r
+\r
+ int32 m_proxyCount;\r
+\r
+ int32* m_moveBuffer;\r
+ int32 m_moveCapacity;\r
+ int32 m_moveCount;\r
+\r
+ b2Pair* m_pairBuffer;\r
+ int32 m_pairCapacity;\r
+ int32 m_pairCount;\r
+\r
+ int32 m_queryProxyId;\r
+};\r
+\r
+/// This is used to sort pairs.\r
+inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)\r
+{\r
+ if (pair1.proxyIdA < pair2.proxyIdA)\r
+ {\r
+ return true;\r
+ }\r
+\r
+ if (pair1.proxyIdA == pair2.proxyIdA)\r
+ {\r
+ return pair1.proxyIdB < pair2.proxyIdB;\r
+ }\r
+\r
+ return false;\r
+}\r
+\r
+inline void* b2BroadPhase::GetUserData(int32 proxyId) const\r
+{\r
+ return m_tree.GetUserData(proxyId);\r
+}\r
+\r
+inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const\r
+{\r
+ const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);\r
+ const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);\r
+ return b2TestOverlap(aabbA, aabbB);\r
+}\r
+\r
+inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const\r
+{\r
+ return m_tree.GetFatAABB(proxyId);\r
+}\r
+\r
+inline int32 b2BroadPhase::GetProxyCount() const\r
+{\r
+ return m_proxyCount;\r
+}\r
+\r
+inline int32 b2BroadPhase::ComputeHeight() const\r
+{\r
+ return m_tree.ComputeHeight();\r
+}\r
+\r
+template <typename T>\r
+void b2BroadPhase::UpdatePairs(T* callback)\r
+{\r
+ // Reset pair buffer\r
+ m_pairCount = 0;\r
+\r
+ // Perform tree queries for all moving proxies.\r
+ for (int32 i = 0; i < m_moveCount; ++i)\r
+ {\r
+ m_queryProxyId = m_moveBuffer[i];\r
+ if (m_queryProxyId == e_nullProxy)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ // We have to query the tree with the fat AABB so that\r
+ // we don't fail to create a pair that may touch later.\r
+ const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);\r
+\r
+ // Query tree, create pairs and add them pair buffer.\r
+ m_tree.Query(this, fatAABB);\r
+ }\r
+\r
+ // Reset move buffer\r
+ m_moveCount = 0;\r
+\r
+ // Sort the pair buffer to expose duplicates.\r
+ std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);\r
+\r
+ // Send the pairs back to the client.\r
+ int32 i = 0;\r
+ while (i < m_pairCount)\r
+ {\r
+ b2Pair* primaryPair = m_pairBuffer + i;\r
+ void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);\r
+ void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);\r
+\r
+ callback->AddPair(userDataA, userDataB);\r
+ ++i;\r
+\r
+ // Skip any duplicate pairs.\r
+ while (i < m_pairCount)\r
+ {\r
+ b2Pair* pair = m_pairBuffer + i;\r
+ if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)\r
+ {\r
+ break;\r
+ }\r
+ ++i;\r
+ }\r
+ }\r
+\r
+ // Try to keep the tree balanced.\r
+ m_tree.Rebalance(4);\r
+}\r
+\r
+template <typename T>\r
+inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const\r
+{\r
+ m_tree.Query(callback, aabb);\r
+}\r
+\r
+template <typename T>\r
+inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const\r
+{\r
+ m_tree.RayCast(callback, input);\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2Collision.h>\r
+#include <Box2D/Collision/Shapes/b2CircleShape.h>\r
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>\r
+\r
+void b2CollideCircles(\r
+ b2Manifold* manifold,\r
+ const b2CircleShape* circleA, const b2Transform& xfA,\r
+ const b2CircleShape* circleB, const b2Transform& xfB)\r
+{\r
+ manifold->pointCount = 0;\r
+\r
+ b2Vec2 pA = b2Mul(xfA, circleA->m_p);\r
+ b2Vec2 pB = b2Mul(xfB, circleB->m_p);\r
+\r
+ b2Vec2 d = pB - pA;\r
+ float32 distSqr = b2Dot(d, d);\r
+ float32 rA = circleA->m_radius, rB = circleB->m_radius;\r
+ float32 radius = rA + rB;\r
+ if (distSqr > radius * radius)\r
+ {\r
+ return;\r
+ }\r
+\r
+ manifold->type = b2Manifold::e_circles;\r
+ manifold->localPoint = circleA->m_p;\r
+ manifold->localNormal.SetZero();\r
+ manifold->pointCount = 1;\r
+\r
+ manifold->points[0].localPoint = circleB->m_p;\r
+ manifold->points[0].id.key = 0;\r
+}\r
+\r
+void b2CollidePolygonAndCircle(\r
+ b2Manifold* manifold,\r
+ const b2PolygonShape* polygonA, const b2Transform& xfA,\r
+ const b2CircleShape* circleB, const b2Transform& xfB)\r
+{\r
+ manifold->pointCount = 0;\r
+\r
+ // Compute circle position in the frame of the polygon.\r
+ b2Vec2 c = b2Mul(xfB, circleB->m_p);\r
+ b2Vec2 cLocal = b2MulT(xfA, c);\r
+\r
+ // Find the min separating edge.\r
+ int32 normalIndex = 0;\r
+ float32 separation = -b2_maxFloat;\r
+ float32 radius = polygonA->m_radius + circleB->m_radius;\r
+ int32 vertexCount = polygonA->m_vertexCount;\r
+ const b2Vec2* vertices = polygonA->m_vertices;\r
+ const b2Vec2* normals = polygonA->m_normals;\r
+\r
+ for (int32 i = 0; i < vertexCount; ++i)\r
+ {\r
+ float32 s = b2Dot(normals[i], cLocal - vertices[i]);\r
+\r
+ if (s > radius)\r
+ {\r
+ // Early out.\r
+ return;\r
+ }\r
+\r
+ if (s > separation)\r
+ {\r
+ separation = s;\r
+ normalIndex = i;\r
+ }\r
+ }\r
+\r
+ // Vertices that subtend the incident face.\r
+ int32 vertIndex1 = normalIndex;\r
+ int32 vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;\r
+ b2Vec2 v1 = vertices[vertIndex1];\r
+ b2Vec2 v2 = vertices[vertIndex2];\r
+\r
+ // If the center is inside the polygon ...\r
+ if (separation < b2_epsilon)\r
+ {\r
+ manifold->pointCount = 1;\r
+ manifold->type = b2Manifold::e_faceA;\r
+ manifold->localNormal = normals[normalIndex];\r
+ manifold->localPoint = 0.5f * (v1 + v2);\r
+ manifold->points[0].localPoint = circleB->m_p;\r
+ manifold->points[0].id.key = 0;\r
+ return;\r
+ }\r
+\r
+ // Compute barycentric coordinates\r
+ float32 u1 = b2Dot(cLocal - v1, v2 - v1);\r
+ float32 u2 = b2Dot(cLocal - v2, v1 - v2);\r
+ if (u1 <= 0.0f)\r
+ {\r
+ if (b2DistanceSquared(cLocal, v1) > radius * radius)\r
+ {\r
+ return;\r
+ }\r
+\r
+ manifold->pointCount = 1;\r
+ manifold->type = b2Manifold::e_faceA;\r
+ manifold->localNormal = cLocal - v1;\r
+ manifold->localNormal.Normalize();\r
+ manifold->localPoint = v1;\r
+ manifold->points[0].localPoint = circleB->m_p;\r
+ manifold->points[0].id.key = 0;\r
+ }\r
+ else if (u2 <= 0.0f)\r
+ {\r
+ if (b2DistanceSquared(cLocal, v2) > radius * radius)\r
+ {\r
+ return;\r
+ }\r
+\r
+ manifold->pointCount = 1;\r
+ manifold->type = b2Manifold::e_faceA;\r
+ manifold->localNormal = cLocal - v2;\r
+ manifold->localNormal.Normalize();\r
+ manifold->localPoint = v2;\r
+ manifold->points[0].localPoint = circleB->m_p;\r
+ manifold->points[0].id.key = 0;\r
+ }\r
+ else\r
+ {\r
+ b2Vec2 faceCenter = 0.5f * (v1 + v2);\r
+ float32 separation = b2Dot(cLocal - faceCenter, normals[vertIndex1]);\r
+ if (separation > radius)\r
+ {\r
+ return;\r
+ }\r
+\r
+ manifold->pointCount = 1;\r
+ manifold->type = b2Manifold::e_faceA;\r
+ manifold->localNormal = normals[vertIndex1];\r
+ manifold->localPoint = faceCenter;\r
+ manifold->points[0].localPoint = circleB->m_p;\r
+ manifold->points[0].id.key = 0;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2Collision.h>\r
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>\r
+\r
+// Find the separation between poly1 and poly2 for a give edge normal on poly1.\r
+static float32 b2EdgeSeparation(const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,\r
+ const b2PolygonShape* poly2, const b2Transform& xf2)\r
+{\r
+ int32 count1 = poly1->m_vertexCount;\r
+ const b2Vec2* vertices1 = poly1->m_vertices;\r
+ const b2Vec2* normals1 = poly1->m_normals;\r
+\r
+ int32 count2 = poly2->m_vertexCount;\r
+ const b2Vec2* vertices2 = poly2->m_vertices;\r
+\r
+ b2Assert(0 <= edge1 && edge1 < count1);\r
+\r
+ // Convert normal from poly1's frame into poly2's frame.\r
+ b2Vec2 normal1World = b2Mul(xf1.R, normals1[edge1]);\r
+ b2Vec2 normal1 = b2MulT(xf2.R, normal1World);\r
+\r
+ // Find support vertex on poly2 for -normal.\r
+ int32 index = 0;\r
+ float32 minDot = b2_maxFloat;\r
+\r
+ for (int32 i = 0; i < count2; ++i)\r
+ {\r
+ float32 dot = b2Dot(vertices2[i], normal1);\r
+ if (dot < minDot)\r
+ {\r
+ minDot = dot;\r
+ index = i;\r
+ }\r
+ }\r
+\r
+ b2Vec2 v1 = b2Mul(xf1, vertices1[edge1]);\r
+ b2Vec2 v2 = b2Mul(xf2, vertices2[index]);\r
+ float32 separation = b2Dot(v2 - v1, normal1World);\r
+ return separation;\r
+}\r
+\r
+// Find the max separation between poly1 and poly2 using edge normals from poly1.\r
+static float32 b2FindMaxSeparation(int32* edgeIndex,\r
+ const b2PolygonShape* poly1, const b2Transform& xf1,\r
+ const b2PolygonShape* poly2, const b2Transform& xf2)\r
+{\r
+ int32 count1 = poly1->m_vertexCount;\r
+ const b2Vec2* normals1 = poly1->m_normals;\r
+\r
+ // Vector pointing from the centroid of poly1 to the centroid of poly2.\r
+ b2Vec2 d = b2Mul(xf2, poly2->m_centroid) - b2Mul(xf1, poly1->m_centroid);\r
+ b2Vec2 dLocal1 = b2MulT(xf1.R, d);\r
+\r
+ // Find edge normal on poly1 that has the largest projection onto d.\r
+ int32 edge = 0;\r
+ float32 maxDot = -b2_maxFloat;\r
+ for (int32 i = 0; i < count1; ++i)\r
+ {\r
+ float32 dot = b2Dot(normals1[i], dLocal1);\r
+ if (dot > maxDot)\r
+ {\r
+ maxDot = dot;\r
+ edge = i;\r
+ }\r
+ }\r
+\r
+ // Get the separation for the edge normal.\r
+ float32 s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2);\r
+\r
+ // Check the separation for the previous edge normal.\r
+ int32 prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;\r
+ float32 sPrev = b2EdgeSeparation(poly1, xf1, prevEdge, poly2, xf2);\r
+\r
+ // Check the separation for the next edge normal.\r
+ int32 nextEdge = edge + 1 < count1 ? edge + 1 : 0;\r
+ float32 sNext = b2EdgeSeparation(poly1, xf1, nextEdge, poly2, xf2);\r
+\r
+ // Find the best edge and the search direction.\r
+ int32 bestEdge;\r
+ float32 bestSeparation;\r
+ int32 increment;\r
+ if (sPrev > s && sPrev > sNext)\r
+ {\r
+ increment = -1;\r
+ bestEdge = prevEdge;\r
+ bestSeparation = sPrev;\r
+ }\r
+ else if (sNext > s)\r
+ {\r
+ increment = 1;\r
+ bestEdge = nextEdge;\r
+ bestSeparation = sNext;\r
+ }\r
+ else\r
+ {\r
+ *edgeIndex = edge;\r
+ return s;\r
+ }\r
+\r
+ // Perform a local search for the best edge normal.\r
+ for ( ; ; )\r
+ {\r
+ if (increment == -1)\r
+ edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;\r
+ else\r
+ edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;\r
+\r
+ s = b2EdgeSeparation(poly1, xf1, edge, poly2, xf2);\r
+\r
+ if (s > bestSeparation)\r
+ {\r
+ bestEdge = edge;\r
+ bestSeparation = s;\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+\r
+ *edgeIndex = bestEdge;\r
+ return bestSeparation;\r
+}\r
+\r
+static void b2FindIncidentEdge(b2ClipVertex c[2],\r
+ const b2PolygonShape* poly1, const b2Transform& xf1, int32 edge1,\r
+ const b2PolygonShape* poly2, const b2Transform& xf2)\r
+{\r
+ int32 count1 = poly1->m_vertexCount;\r
+ const b2Vec2* normals1 = poly1->m_normals;\r
+\r
+ int32 count2 = poly2->m_vertexCount;\r
+ const b2Vec2* vertices2 = poly2->m_vertices;\r
+ const b2Vec2* normals2 = poly2->m_normals;\r
+\r
+ b2Assert(0 <= edge1 && edge1 < count1);\r
+\r
+ // Get the normal of the reference edge in poly2's frame.\r
+ b2Vec2 normal1 = b2MulT(xf2.R, b2Mul(xf1.R, normals1[edge1]));\r
+\r
+ // Find the incident edge on poly2.\r
+ int32 index = 0;\r
+ float32 minDot = b2_maxFloat;\r
+ for (int32 i = 0; i < count2; ++i)\r
+ {\r
+ float32 dot = b2Dot(normal1, normals2[i]);\r
+ if (dot < minDot)\r
+ {\r
+ minDot = dot;\r
+ index = i;\r
+ }\r
+ }\r
+\r
+ // Build the clip vertices for the incident edge.\r
+ int32 i1 = index;\r
+ int32 i2 = i1 + 1 < count2 ? i1 + 1 : 0;\r
+\r
+ c[0].v = b2Mul(xf2, vertices2[i1]);\r
+ c[0].id.features.referenceEdge = (uint8)edge1;\r
+ c[0].id.features.incidentEdge = (uint8)i1;\r
+ c[0].id.features.incidentVertex = 0;\r
+\r
+ c[1].v = b2Mul(xf2, vertices2[i2]);\r
+ c[1].id.features.referenceEdge = (uint8)edge1;\r
+ c[1].id.features.incidentEdge = (uint8)i2;\r
+ c[1].id.features.incidentVertex = 1;\r
+}\r
+\r
+// Find edge normal of max separation on A - return if separating axis is found\r
+// Find edge normal of max separation on B - return if separation axis is found\r
+// Choose reference edge as min(minA, minB)\r
+// Find incident edge\r
+// Clip\r
+\r
+// The normal points from 1 to 2\r
+void b2CollidePolygons(b2Manifold* manifold,\r
+ const b2PolygonShape* polyA, const b2Transform& xfA,\r
+ const b2PolygonShape* polyB, const b2Transform& xfB)\r
+{\r
+ manifold->pointCount = 0;\r
+ float32 totalRadius = polyA->m_radius + polyB->m_radius;\r
+\r
+ int32 edgeA = 0;\r
+ float32 separationA = b2FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB);\r
+ if (separationA > totalRadius)\r
+ return;\r
+\r
+ int32 edgeB = 0;\r
+ float32 separationB = b2FindMaxSeparation(&edgeB, polyB, xfB, polyA, xfA);\r
+ if (separationB > totalRadius)\r
+ return;\r
+\r
+ const b2PolygonShape* poly1; // reference polygon\r
+ const b2PolygonShape* poly2; // incident polygon\r
+ b2Transform xf1, xf2;\r
+ int32 edge1; // reference edge\r
+ uint8 flip;\r
+ const float32 k_relativeTol = 0.98f;\r
+ const float32 k_absoluteTol = 0.001f;\r
+\r
+ if (separationB > k_relativeTol * separationA + k_absoluteTol)\r
+ {\r
+ poly1 = polyB;\r
+ poly2 = polyA;\r
+ xf1 = xfB;\r
+ xf2 = xfA;\r
+ edge1 = edgeB;\r
+ manifold->type = b2Manifold::e_faceB;\r
+ flip = 1;\r
+ }\r
+ else\r
+ {\r
+ poly1 = polyA;\r
+ poly2 = polyB;\r
+ xf1 = xfA;\r
+ xf2 = xfB;\r
+ edge1 = edgeA;\r
+ manifold->type = b2Manifold::e_faceA;\r
+ flip = 0;\r
+ }\r
+\r
+ b2ClipVertex incidentEdge[2];\r
+ b2FindIncidentEdge(incidentEdge, poly1, xf1, edge1, poly2, xf2);\r
+\r
+ int32 count1 = poly1->m_vertexCount;\r
+ const b2Vec2* vertices1 = poly1->m_vertices;\r
+\r
+ b2Vec2 v11 = vertices1[edge1];\r
+ b2Vec2 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0];\r
+\r
+ b2Vec2 localTangent = v12 - v11;\r
+ localTangent.Normalize();\r
+ \r
+ b2Vec2 localNormal = b2Cross(localTangent, 1.0f);\r
+ b2Vec2 planePoint = 0.5f * (v11 + v12);\r
+\r
+ b2Vec2 tangent = b2Mul(xf1.R, localTangent);\r
+ b2Vec2 normal = b2Cross(tangent, 1.0f);\r
+ \r
+ v11 = b2Mul(xf1, v11);\r
+ v12 = b2Mul(xf1, v12);\r
+\r
+ // Face offset.\r
+ float32 frontOffset = b2Dot(normal, v11);\r
+\r
+ // Side offsets, extended by polytope skin thickness.\r
+ float32 sideOffset1 = -b2Dot(tangent, v11) + totalRadius;\r
+ float32 sideOffset2 = b2Dot(tangent, v12) + totalRadius;\r
+\r
+ // Clip incident edge against extruded edge1 side edges.\r
+ b2ClipVertex clipPoints1[2];\r
+ b2ClipVertex clipPoints2[2];\r
+ int np;\r
+\r
+ // Clip to box side 1\r
+ np = b2ClipSegmentToLine(clipPoints1, incidentEdge, -tangent, sideOffset1);\r
+\r
+ if (np < 2)\r
+ return;\r
+\r
+ // Clip to negative box side 1\r
+ np = b2ClipSegmentToLine(clipPoints2, clipPoints1, tangent, sideOffset2);\r
+\r
+ if (np < 2)\r
+ {\r
+ return;\r
+ }\r
+\r
+ // Now clipPoints2 contains the clipped points.\r
+ manifold->localNormal = localNormal;\r
+ manifold->localPoint = planePoint;\r
+\r
+ int32 pointCount = 0;\r
+ for (int32 i = 0; i < b2_maxManifoldPoints; ++i)\r
+ {\r
+ float32 separation = b2Dot(normal, clipPoints2[i].v) - frontOffset;\r
+\r
+ if (separation <= totalRadius)\r
+ {\r
+ b2ManifoldPoint* cp = manifold->points + pointCount;\r
+ cp->localPoint = b2MulT(xf2, clipPoints2[i].v);\r
+ cp->id = clipPoints2[i].id;\r
+ cp->id.features.flip = flip;\r
+ ++pointCount;\r
+ }\r
+ }\r
+\r
+ manifold->pointCount = pointCount;\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2Collision.h>\r
+#include <Box2D/Collision/b2Distance.h>\r
+\r
+void b2WorldManifold::Initialize(const b2Manifold* manifold,\r
+ const b2Transform& xfA, float32 radiusA,\r
+ const b2Transform& xfB, float32 radiusB)\r
+{\r
+ if (manifold->pointCount == 0)\r
+ {\r
+ return;\r
+ }\r
+\r
+ switch (manifold->type)\r
+ {\r
+ case b2Manifold::e_circles:\r
+ {\r
+ normal.Set(1.0f, 0.0f);\r
+ b2Vec2 pointA = b2Mul(xfA, manifold->localPoint);\r
+ b2Vec2 pointB = b2Mul(xfB, manifold->points[0].localPoint);\r
+ if (b2DistanceSquared(pointA, pointB) > b2_epsilon * b2_epsilon)\r
+ {\r
+ normal = pointB - pointA;\r
+ normal.Normalize();\r
+ }\r
+\r
+ b2Vec2 cA = pointA + radiusA * normal;\r
+ b2Vec2 cB = pointB - radiusB * normal;\r
+ points[0] = 0.5f * (cA + cB);\r
+ }\r
+ break;\r
+\r
+ case b2Manifold::e_faceA:\r
+ {\r
+ normal = b2Mul(xfA.R, manifold->localNormal);\r
+ b2Vec2 planePoint = b2Mul(xfA, manifold->localPoint);\r
+ \r
+ for (int32 i = 0; i < manifold->pointCount; ++i)\r
+ {\r
+ b2Vec2 clipPoint = b2Mul(xfB, manifold->points[i].localPoint);\r
+ b2Vec2 cA = clipPoint + (radiusA - b2Dot(clipPoint - planePoint, normal)) * normal;\r
+ b2Vec2 cB = clipPoint - radiusB * normal;\r
+ points[i] = 0.5f * (cA + cB);\r
+ }\r
+ }\r
+ break;\r
+\r
+ case b2Manifold::e_faceB:\r
+ {\r
+ normal = b2Mul(xfB.R, manifold->localNormal);\r
+ b2Vec2 planePoint = b2Mul(xfB, manifold->localPoint);\r
+\r
+ for (int32 i = 0; i < manifold->pointCount; ++i)\r
+ {\r
+ b2Vec2 clipPoint = b2Mul(xfA, manifold->points[i].localPoint);\r
+ b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;\r
+ b2Vec2 cA = clipPoint - radiusA * normal;\r
+ points[i] = 0.5f * (cA + cB);\r
+ }\r
+\r
+ // Ensure normal points from A to B.\r
+ normal = -normal;\r
+ }\r
+ break;\r
+ }\r
+}\r
+\r
+void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],\r
+ const b2Manifold* manifold1, const b2Manifold* manifold2)\r
+{\r
+ for (int32 i = 0; i < b2_maxManifoldPoints; ++i)\r
+ {\r
+ state1[i] = b2_nullState;\r
+ state2[i] = b2_nullState;\r
+ }\r
+\r
+ // Detect persists and removes.\r
+ for (int32 i = 0; i < manifold1->pointCount; ++i)\r
+ {\r
+ b2ContactID id = manifold1->points[i].id;\r
+\r
+ state1[i] = b2_removeState;\r
+\r
+ for (int32 j = 0; j < manifold2->pointCount; ++j)\r
+ {\r
+ if (manifold2->points[j].id.key == id.key)\r
+ {\r
+ state1[i] = b2_persistState;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ // Detect persists and adds.\r
+ for (int32 i = 0; i < manifold2->pointCount; ++i)\r
+ {\r
+ b2ContactID id = manifold2->points[i].id;\r
+\r
+ state2[i] = b2_addState;\r
+\r
+ for (int32 j = 0; j < manifold1->pointCount; ++j)\r
+ {\r
+ if (manifold1->points[j].id.key == id.key)\r
+ {\r
+ state2[i] = b2_persistState;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+// From Real-time Collision Detection, p179.\r
+bool b2AABB::RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const\r
+{\r
+ float32 tmin = -b2_maxFloat;\r
+ float32 tmax = b2_maxFloat;\r
+\r
+ b2Vec2 p = input.p1;\r
+ b2Vec2 d = input.p2 - input.p1;\r
+ b2Vec2 absD = b2Abs(d);\r
+\r
+ b2Vec2 normal;\r
+\r
+ for (int32 i = 0; i < 2; ++i)\r
+ {\r
+ if (absD(i) < b2_epsilon)\r
+ {\r
+ // Parallel.\r
+ if (p(i) < lowerBound(i) || upperBound(i) < p(i))\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ float32 inv_d = 1.0f / d(i);\r
+ float32 t1 = (lowerBound(i) - p(i)) * inv_d;\r
+ float32 t2 = (upperBound(i) - p(i)) * inv_d;\r
+\r
+ // Sign of the normal vector.\r
+ float32 s = -1.0f;\r
+\r
+ if (t1 > t2)\r
+ {\r
+ b2Swap(t1, t2);\r
+ s = 1.0f;\r
+ }\r
+\r
+ // Push the min up\r
+ if (t1 > tmin)\r
+ {\r
+ normal.SetZero();\r
+ normal(i) = s;\r
+ tmin = t1;\r
+ }\r
+\r
+ // Pull the max down\r
+ tmax = b2Min(tmax, t2);\r
+\r
+ if (tmin > tmax)\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+\r
+ // Does the ray start inside the box?\r
+ // Does the ray intersect beyond the max fraction?\r
+ if (tmin < 0.0f || input.maxFraction < tmin)\r
+ {\r
+ return false;\r
+ }\r
+\r
+ // Intersection.\r
+ output->fraction = tmin;\r
+ output->normal = normal;\r
+ return true;\r
+}\r
+\r
+// Sutherland-Hodgman clipping.\r
+int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],\r
+ const b2Vec2& normal, float32 offset)\r
+{\r
+ // Start with no output points\r
+ int32 numOut = 0;\r
+\r
+ // Calculate the distance of end points to the line\r
+ float32 distance0 = b2Dot(normal, vIn[0].v) - offset;\r
+ float32 distance1 = b2Dot(normal, vIn[1].v) - offset;\r
+\r
+ // If the points are behind the plane\r
+ if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];\r
+ if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];\r
+\r
+ // If the points are on different sides of the plane\r
+ if (distance0 * distance1 < 0.0f)\r
+ {\r
+ // Find intersection point of edge and plane\r
+ float32 interp = distance0 / (distance0 - distance1);\r
+ vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);\r
+ if (distance0 > 0.0f)\r
+ {\r
+ vOut[numOut].id = vIn[0].id;\r
+ }\r
+ else\r
+ {\r
+ vOut[numOut].id = vIn[1].id;\r
+ }\r
+ ++numOut;\r
+ }\r
+\r
+ return numOut;\r
+}\r
+\r
+bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB,\r
+ const b2Transform& xfA, const b2Transform& xfB)\r
+{\r
+ b2DistanceInput input;\r
+ input.proxyA.Set(shapeA);\r
+ input.proxyB.Set(shapeB);\r
+ input.transformA = xfA;\r
+ input.transformB = xfB;\r
+ input.useRadii = true;\r
+\r
+ b2SimplexCache cache;\r
+ cache.count = 0;\r
+\r
+ b2DistanceOutput output;\r
+\r
+ b2Distance(&output, &cache, &input);\r
+\r
+ return output.distance < 10.0f * b2_epsilon;\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_COLLISION_H\r
+#define B2_COLLISION_H\r
+\r
+#include <Box2D/Common/b2Math.h>\r
+#include <climits>\r
+\r
+/// @file\r
+/// Structures and functions used for computing contact points, distance\r
+/// queries, and TOI queries.\r
+\r
+class b2Shape;\r
+class b2CircleShape;\r
+class b2PolygonShape;\r
+\r
+const uint8 b2_nullFeature = UCHAR_MAX;\r
+\r
+/// Contact ids to facilitate warm starting.\r
+union b2ContactID\r
+{\r
+ /// The features that intersect to form the contact point\r
+ struct Features\r
+ {\r
+ uint8 referenceEdge; ///< The edge that defines the outward contact normal.\r
+ uint8 incidentEdge; ///< The edge most anti-parallel to the reference edge.\r
+ uint8 incidentVertex; ///< The vertex (0 or 1) on the incident edge that was clipped.\r
+ uint8 flip; ///< A value of 1 indicates that the reference edge is on shape2.\r
+ } features;\r
+ uint32 key; ///< Used to quickly compare contact ids.\r
+};\r
+\r
+/// A manifold point is a contact point belonging to a contact\r
+/// manifold. It holds details related to the geometry and dynamics\r
+/// of the contact points.\r
+/// The local point usage depends on the manifold type:\r
+/// -e_circles: the local center of circleB\r
+/// -e_faceA: the local center of cirlceB or the clip point of polygonB\r
+/// -e_faceB: the clip point of polygonA\r
+/// This structure is stored across time steps, so we keep it small.\r
+/// Note: the impulses are used for internal caching and may not\r
+/// provide reliable contact forces, especially for high speed collisions.\r
+struct b2ManifoldPoint\r
+{\r
+ b2Vec2 localPoint; ///< usage depends on manifold type\r
+ float32 normalImpulse; ///< the non-penetration impulse\r
+ float32 tangentImpulse; ///< the friction impulse\r
+ b2ContactID id; ///< uniquely identifies a contact point between two shapes\r
+};\r
+\r
+/// A manifold for two touching convex shapes.\r
+/// Box2D supports multiple types of contact:\r
+/// - clip point versus plane with radius\r
+/// - point versus point with radius (circles)\r
+/// The local point usage depends on the manifold type:\r
+/// -e_circles: the local center of circleA\r
+/// -e_faceA: the center of faceA\r
+/// -e_faceB: the center of faceB\r
+/// Similarly the local normal usage:\r
+/// -e_circles: not used\r
+/// -e_faceA: the normal on polygonA\r
+/// -e_faceB: the normal on polygonB\r
+/// We store contacts in this way so that position correction can\r
+/// account for movement, which is critical for continuous physics.\r
+/// All contact scenarios must be expressed in one of these types.\r
+/// This structure is stored across time steps, so we keep it small.\r
+struct b2Manifold\r
+{\r
+ enum Type\r
+ {\r
+ e_circles,\r
+ e_faceA,\r
+ e_faceB\r
+ };\r
+\r
+ b2ManifoldPoint points[b2_maxManifoldPoints]; ///< the points of contact\r
+ b2Vec2 localNormal; ///< not use for Type::e_points\r
+ b2Vec2 localPoint; ///< usage depends on manifold type\r
+ Type type;\r
+ int32 pointCount; ///< the number of manifold points\r
+};\r
+\r
+/// This is used to compute the current state of a contact manifold.\r
+struct b2WorldManifold\r
+{\r
+ /// Evaluate the manifold with supplied transforms. This assumes\r
+ /// modest motion from the original state. This does not change the\r
+ /// point count, impulses, etc. The radii must come from the shapes\r
+ /// that generated the manifold.\r
+ void Initialize(const b2Manifold* manifold,\r
+ const b2Transform& xfA, float32 radiusA,\r
+ const b2Transform& xfB, float32 radiusB);\r
+\r
+ b2Vec2 normal; ///< world vector pointing from A to B\r
+ b2Vec2 points[b2_maxManifoldPoints]; ///< world contact point (point of intersection)\r
+};\r
+\r
+/// This is used for determining the state of contact points.\r
+enum b2PointState\r
+{\r
+ b2_nullState, ///< point does not exist\r
+ b2_addState, ///< point was added in the update\r
+ b2_persistState, ///< point persisted across the update\r
+ b2_removeState ///< point was removed in the update\r
+};\r
+\r
+/// Compute the point states given two manifolds. The states pertain to the transition from manifold1\r
+/// to manifold2. So state1 is either persist or remove while state2 is either add or persist.\r
+void b2GetPointStates(b2PointState state1[b2_maxManifoldPoints], b2PointState state2[b2_maxManifoldPoints],\r
+ const b2Manifold* manifold1, const b2Manifold* manifold2);\r
+\r
+/// Used for computing contact manifolds.\r
+struct b2ClipVertex\r
+{\r
+ b2Vec2 v;\r
+ b2ContactID id;\r
+};\r
+\r
+/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).\r
+struct b2RayCastInput\r
+{\r
+ b2Vec2 p1, p2;\r
+ float32 maxFraction;\r
+};\r
+\r
+/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2\r
+/// come from b2RayCastInput.\r
+struct b2RayCastOutput\r
+{\r
+ b2Vec2 normal;\r
+ float32 fraction;\r
+};\r
+\r
+/// An axis aligned bounding box.\r
+struct b2AABB\r
+{\r
+ /// Verify that the bounds are sorted.\r
+ bool IsValid() const;\r
+\r
+ /// Get the center of the AABB.\r
+ b2Vec2 GetCenter() const\r
+ {\r
+ return 0.5f * (lowerBound + upperBound);\r
+ }\r
+\r
+ /// Get the extents of the AABB (half-widths).\r
+ b2Vec2 GetExtents() const\r
+ {\r
+ return 0.5f * (upperBound - lowerBound);\r
+ }\r
+\r
+ /// Combine two AABBs into this one.\r
+ void Combine(const b2AABB& aabb1, const b2AABB& aabb2)\r
+ {\r
+ lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);\r
+ upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);\r
+ }\r
+\r
+ /// Does this aabb contain the provided AABB.\r
+ bool Contains(const b2AABB& aabb) const\r
+ {\r
+ bool result = true;\r
+ result = result && lowerBound.x <= aabb.lowerBound.x;\r
+ result = result && lowerBound.y <= aabb.lowerBound.y;\r
+ result = result && aabb.upperBound.x <= upperBound.x;\r
+ result = result && aabb.upperBound.y <= upperBound.y;\r
+ return result;\r
+ }\r
+\r
+ bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;\r
+\r
+ b2Vec2 lowerBound; ///< the lower vertex\r
+ b2Vec2 upperBound; ///< the upper vertex\r
+};\r
+\r
+/// Compute the collision manifold between two circles.\r
+void b2CollideCircles(b2Manifold* manifold,\r
+ const b2CircleShape* circle1, const b2Transform& xf1,\r
+ const b2CircleShape* circle2, const b2Transform& xf2);\r
+\r
+/// Compute the collision manifold between a polygon and a circle.\r
+void b2CollidePolygonAndCircle(b2Manifold* manifold,\r
+ const b2PolygonShape* polygon, const b2Transform& xf1,\r
+ const b2CircleShape* circle, const b2Transform& xf2);\r
+\r
+/// Compute the collision manifold between two polygons.\r
+void b2CollidePolygons(b2Manifold* manifold,\r
+ const b2PolygonShape* polygon1, const b2Transform& xf1,\r
+ const b2PolygonShape* polygon2, const b2Transform& xf2);\r
+\r
+/// Clipping for contact manifolds.\r
+int32 b2ClipSegmentToLine(b2ClipVertex vOut[2], const b2ClipVertex vIn[2],\r
+ const b2Vec2& normal, float32 offset);\r
+\r
+/// Determine if two generic shapes overlap.\r
+bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB,\r
+ const b2Transform& xfA, const b2Transform& xfB);\r
+\r
+// ---------------- Inline Functions ------------------------------------------\r
+\r
+inline bool b2AABB::IsValid() const\r
+{\r
+ b2Vec2 d = upperBound - lowerBound;\r
+ bool valid = d.x >= 0.0f && d.y >= 0.0f;\r
+ valid = valid && lowerBound.IsValid() && upperBound.IsValid();\r
+ return valid;\r
+}\r
+\r
+inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)\r
+{\r
+ b2Vec2 d1, d2;\r
+ d1 = b.lowerBound - a.upperBound;\r
+ d2 = a.lowerBound - b.upperBound;\r
+\r
+ if (d1.x > 0.0f || d1.y > 0.0f)\r
+ return false;\r
+\r
+ if (d2.x > 0.0f || d2.y > 0.0f)\r
+ return false;\r
+\r
+ return true;\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2Distance.h>\r
+#include <Box2D/Collision/Shapes/b2CircleShape.h>\r
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>\r
+\r
+// GJK using Voronoi regions (Christer Ericson) and Barycentric coordinates.\r
+int32 b2_gjkCalls, b2_gjkIters, b2_gjkMaxIters;\r
+\r
+void b2DistanceProxy::Set(const b2Shape* shape)\r
+{\r
+ switch (shape->GetType())\r
+ {\r
+ case b2Shape::e_circle:\r
+ {\r
+ const b2CircleShape* circle = (b2CircleShape*)shape;\r
+ m_vertices = &circle->m_p;\r
+ m_count = 1;\r
+ m_radius = circle->m_radius;\r
+ }\r
+ break;\r
+\r
+ case b2Shape::e_polygon:\r
+ {\r
+ const b2PolygonShape* polygon = (b2PolygonShape*)shape;\r
+ m_vertices = polygon->m_vertices;\r
+ m_count = polygon->m_vertexCount;\r
+ m_radius = polygon->m_radius;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ b2Assert(false);\r
+ }\r
+}\r
+\r
+\r
+struct b2SimplexVertex\r
+{\r
+ b2Vec2 wA; // support point in proxyA\r
+ b2Vec2 wB; // support point in proxyB\r
+ b2Vec2 w; // wB - wA\r
+ float32 a; // barycentric coordinate for closest point\r
+ int32 indexA; // wA index\r
+ int32 indexB; // wB index\r
+};\r
+\r
+struct b2Simplex\r
+{\r
+ void ReadCache( const b2SimplexCache* cache,\r
+ const b2DistanceProxy* proxyA, const b2Transform& transformA,\r
+ const b2DistanceProxy* proxyB, const b2Transform& transformB)\r
+ {\r
+ b2Assert(cache->count <= 3);\r
+ \r
+ // Copy data from cache.\r
+ m_count = cache->count;\r
+ b2SimplexVertex* vertices = &m_v1;\r
+ for (int32 i = 0; i < m_count; ++i)\r
+ {\r
+ b2SimplexVertex* v = vertices + i;\r
+ v->indexA = cache->indexA[i];\r
+ v->indexB = cache->indexB[i];\r
+ b2Vec2 wALocal = proxyA->GetVertex(v->indexA);\r
+ b2Vec2 wBLocal = proxyB->GetVertex(v->indexB);\r
+ v->wA = b2Mul(transformA, wALocal);\r
+ v->wB = b2Mul(transformB, wBLocal);\r
+ v->w = v->wB - v->wA;\r
+ v->a = 0.0f;\r
+ }\r
+\r
+ // Compute the new simplex metric, if it is substantially different than\r
+ // old metric then flush the simplex.\r
+ if (m_count > 1)\r
+ {\r
+ float32 metric1 = cache->metric;\r
+ float32 metric2 = GetMetric();\r
+ if (metric2 < 0.5f * metric1 || 2.0f * metric1 < metric2 || metric2 < b2_epsilon)\r
+ {\r
+ // Reset the simplex.\r
+ m_count = 0;\r
+ }\r
+ }\r
+\r
+ // If the cache is empty or invalid ...\r
+ if (m_count == 0)\r
+ {\r
+ b2SimplexVertex* v = vertices + 0;\r
+ v->indexA = 0;\r
+ v->indexB = 0;\r
+ b2Vec2 wALocal = proxyA->GetVertex(0);\r
+ b2Vec2 wBLocal = proxyB->GetVertex(0);\r
+ v->wA = b2Mul(transformA, wALocal);\r
+ v->wB = b2Mul(transformB, wBLocal);\r
+ v->w = v->wB - v->wA;\r
+ m_count = 1;\r
+ }\r
+ }\r
+\r
+ void WriteCache(b2SimplexCache* cache) const\r
+ {\r
+ cache->metric = GetMetric();\r
+ cache->count = uint16(m_count);\r
+ const b2SimplexVertex* vertices = &m_v1;\r
+ for (int32 i = 0; i < m_count; ++i)\r
+ {\r
+ cache->indexA[i] = uint8(vertices[i].indexA);\r
+ cache->indexB[i] = uint8(vertices[i].indexB);\r
+ }\r
+ }\r
+\r
+ b2Vec2 GetSearchDirection() const\r
+ {\r
+ switch (m_count)\r
+ {\r
+ case 1:\r
+ return -m_v1.w;\r
+\r
+ case 2:\r
+ {\r
+ b2Vec2 e12 = m_v2.w - m_v1.w;\r
+ float32 sgn = b2Cross(e12, -m_v1.w);\r
+ if (sgn > 0.0f)\r
+ {\r
+ // Origin is left of e12.\r
+ return b2Cross(1.0f, e12);\r
+ }\r
+ else\r
+ {\r
+ // Origin is right of e12.\r
+ return b2Cross(e12, 1.0f);\r
+ }\r
+ }\r
+\r
+ default:\r
+ b2Assert(false);\r
+ return b2Vec2_zero;\r
+ }\r
+ }\r
+\r
+ b2Vec2 GetClosestPoint() const\r
+ {\r
+ switch (m_count)\r
+ {\r
+ case 0:\r
+ b2Assert(false);\r
+ return b2Vec2_zero;\r
+\r
+ case 1:\r
+ return m_v1.w;\r
+\r
+ case 2:\r
+ return m_v1.a * m_v1.w + m_v2.a * m_v2.w;\r
+\r
+ case 3:\r
+ return b2Vec2_zero;\r
+\r
+ default:\r
+ b2Assert(false);\r
+ return b2Vec2_zero;\r
+ }\r
+ }\r
+\r
+ void GetWitnessPoints(b2Vec2* pA, b2Vec2* pB) const\r
+ {\r
+ switch (m_count)\r
+ {\r
+ case 0:\r
+ b2Assert(false);\r
+ break;\r
+\r
+ case 1:\r
+ *pA = m_v1.wA;\r
+ *pB = m_v1.wB;\r
+ break;\r
+\r
+ case 2:\r
+ *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA;\r
+ *pB = m_v1.a * m_v1.wB + m_v2.a * m_v2.wB;\r
+ break;\r
+\r
+ case 3:\r
+ *pA = m_v1.a * m_v1.wA + m_v2.a * m_v2.wA + m_v3.a * m_v3.wA;\r
+ *pB = *pA;\r
+ break;\r
+\r
+ default:\r
+ b2Assert(false);\r
+ break;\r
+ }\r
+ }\r
+\r
+ float32 GetMetric() const\r
+ {\r
+ switch (m_count)\r
+ {\r
+ case 0:\r
+ b2Assert(false);\r
+ return 0.0;\r
+\r
+ case 1:\r
+ return 0.0f;\r
+\r
+ case 2:\r
+ return b2Distance(m_v1.w, m_v2.w);\r
+\r
+ case 3:\r
+ return b2Cross(m_v2.w - m_v1.w, m_v3.w - m_v1.w);\r
+\r
+ default:\r
+ b2Assert(false);\r
+ return 0.0f;\r
+ }\r
+ }\r
+\r
+ void Solve2();\r
+ void Solve3();\r
+\r
+ b2SimplexVertex m_v1, m_v2, m_v3;\r
+ int32 m_count;\r
+};\r
+\r
+\r
+// Solve a line segment using barycentric coordinates.\r
+//\r
+// p = a1 * w1 + a2 * w2\r
+// a1 + a2 = 1\r
+//\r
+// The vector from the origin to the closest point on the line is\r
+// perpendicular to the line.\r
+// e12 = w2 - w1\r
+// dot(p, e) = 0\r
+// a1 * dot(w1, e) + a2 * dot(w2, e) = 0\r
+//\r
+// 2-by-2 linear system\r
+// [1 1 ][a1] = [1]\r
+// [w1.e12 w2.e12][a2] = [0]\r
+//\r
+// Define\r
+// d12_1 = dot(w2, e12)\r
+// d12_2 = -dot(w1, e12)\r
+// d12 = d12_1 + d12_2\r
+//\r
+// Solution\r
+// a1 = d12_1 / d12\r
+// a2 = d12_2 / d12\r
+void b2Simplex::Solve2()\r
+{\r
+ b2Vec2 w1 = m_v1.w;\r
+ b2Vec2 w2 = m_v2.w;\r
+ b2Vec2 e12 = w2 - w1;\r
+\r
+ // w1 region\r
+ float32 d12_2 = -b2Dot(w1, e12);\r
+ if (d12_2 <= 0.0f)\r
+ {\r
+ // a2 <= 0, so we clamp it to 0\r
+ m_v1.a = 1.0f;\r
+ m_count = 1;\r
+ return;\r
+ }\r
+\r
+ // w2 region\r
+ float32 d12_1 = b2Dot(w2, e12);\r
+ if (d12_1 <= 0.0f)\r
+ {\r
+ // a1 <= 0, so we clamp it to 0\r
+ m_v2.a = 1.0f;\r
+ m_count = 1;\r
+ m_v1 = m_v2;\r
+ return;\r
+ }\r
+\r
+ // Must be in e12 region.\r
+ float32 inv_d12 = 1.0f / (d12_1 + d12_2);\r
+ m_v1.a = d12_1 * inv_d12;\r
+ m_v2.a = d12_2 * inv_d12;\r
+ m_count = 2;\r
+}\r
+\r
+// Possible regions:\r
+// - points[2]\r
+// - edge points[0]-points[2]\r
+// - edge points[1]-points[2]\r
+// - inside the triangle\r
+void b2Simplex::Solve3()\r
+{\r
+ b2Vec2 w1 = m_v1.w;\r
+ b2Vec2 w2 = m_v2.w;\r
+ b2Vec2 w3 = m_v3.w;\r
+\r
+ // Edge12\r
+ // [1 1 ][a1] = [1]\r
+ // [w1.e12 w2.e12][a2] = [0]\r
+ // a3 = 0\r
+ b2Vec2 e12 = w2 - w1;\r
+ float32 w1e12 = b2Dot(w1, e12);\r
+ float32 w2e12 = b2Dot(w2, e12);\r
+ float32 d12_1 = w2e12;\r
+ float32 d12_2 = -w1e12;\r
+\r
+ // Edge13\r
+ // [1 1 ][a1] = [1]\r
+ // [w1.e13 w3.e13][a3] = [0]\r
+ // a2 = 0\r
+ b2Vec2 e13 = w3 - w1;\r
+ float32 w1e13 = b2Dot(w1, e13);\r
+ float32 w3e13 = b2Dot(w3, e13);\r
+ float32 d13_1 = w3e13;\r
+ float32 d13_2 = -w1e13;\r
+\r
+ // Edge23\r
+ // [1 1 ][a2] = [1]\r
+ // [w2.e23 w3.e23][a3] = [0]\r
+ // a1 = 0\r
+ b2Vec2 e23 = w3 - w2;\r
+ float32 w2e23 = b2Dot(w2, e23);\r
+ float32 w3e23 = b2Dot(w3, e23);\r
+ float32 d23_1 = w3e23;\r
+ float32 d23_2 = -w2e23;\r
+ \r
+ // Triangle123\r
+ float32 n123 = b2Cross(e12, e13);\r
+\r
+ float32 d123_1 = n123 * b2Cross(w2, w3);\r
+ float32 d123_2 = n123 * b2Cross(w3, w1);\r
+ float32 d123_3 = n123 * b2Cross(w1, w2);\r
+\r
+ // w1 region\r
+ if (d12_2 <= 0.0f && d13_2 <= 0.0f)\r
+ {\r
+ m_v1.a = 1.0f;\r
+ m_count = 1;\r
+ return;\r
+ }\r
+\r
+ // e12\r
+ if (d12_1 > 0.0f && d12_2 > 0.0f && d123_3 <= 0.0f)\r
+ {\r
+ float32 inv_d12 = 1.0f / (d12_1 + d12_2);\r
+ m_v1.a = d12_1 * inv_d12;\r
+ m_v2.a = d12_2 * inv_d12;\r
+ m_count = 2;\r
+ return;\r
+ }\r
+\r
+ // e13\r
+ if (d13_1 > 0.0f && d13_2 > 0.0f && d123_2 <= 0.0f)\r
+ {\r
+ float32 inv_d13 = 1.0f / (d13_1 + d13_2);\r
+ m_v1.a = d13_1 * inv_d13;\r
+ m_v3.a = d13_2 * inv_d13;\r
+ m_count = 2;\r
+ m_v2 = m_v3;\r
+ return;\r
+ }\r
+\r
+ // w2 region\r
+ if (d12_1 <= 0.0f && d23_2 <= 0.0f)\r
+ {\r
+ m_v2.a = 1.0f;\r
+ m_count = 1;\r
+ m_v1 = m_v2;\r
+ return;\r
+ }\r
+\r
+ // w3 region\r
+ if (d13_1 <= 0.0f && d23_1 <= 0.0f)\r
+ {\r
+ m_v3.a = 1.0f;\r
+ m_count = 1;\r
+ m_v1 = m_v3;\r
+ return;\r
+ }\r
+\r
+ // e23\r
+ if (d23_1 > 0.0f && d23_2 > 0.0f && d123_1 <= 0.0f)\r
+ {\r
+ float32 inv_d23 = 1.0f / (d23_1 + d23_2);\r
+ m_v2.a = d23_1 * inv_d23;\r
+ m_v3.a = d23_2 * inv_d23;\r
+ m_count = 2;\r
+ m_v1 = m_v3;\r
+ return;\r
+ }\r
+\r
+ // Must be in triangle123\r
+ float32 inv_d123 = 1.0f / (d123_1 + d123_2 + d123_3);\r
+ m_v1.a = d123_1 * inv_d123;\r
+ m_v2.a = d123_2 * inv_d123;\r
+ m_v3.a = d123_3 * inv_d123;\r
+ m_count = 3;\r
+}\r
+\r
+void b2Distance(b2DistanceOutput* output,\r
+ b2SimplexCache* cache,\r
+ const b2DistanceInput* input)\r
+{\r
+ ++b2_gjkCalls;\r
+\r
+ const b2DistanceProxy* proxyA = &input->proxyA;\r
+ const b2DistanceProxy* proxyB = &input->proxyB;\r
+\r
+ b2Transform transformA = input->transformA;\r
+ b2Transform transformB = input->transformB;\r
+\r
+ // Initialize the simplex.\r
+ b2Simplex simplex;\r
+ simplex.ReadCache(cache, proxyA, transformA, proxyB, transformB);\r
+\r
+ // Get simplex vertices as an array.\r
+ b2SimplexVertex* vertices = &simplex.m_v1;\r
+ const int32 k_maxIters = 20;\r
+\r
+ // These store the vertices of the last simplex so that we\r
+ // can check for duplicates and prevent cycling.\r
+ int32 saveA[3], saveB[3];\r
+ int32 saveCount = 0;\r
+\r
+ b2Vec2 closestPoint = simplex.GetClosestPoint();\r
+ float32 distanceSqr1 = closestPoint.LengthSquared();\r
+ float32 distanceSqr2 = distanceSqr1;\r
+\r
+ // Main iteration loop.\r
+ int32 iter = 0;\r
+ while (iter < k_maxIters)\r
+ {\r
+ // Copy simplex so we can identify duplicates.\r
+ saveCount = simplex.m_count;\r
+ for (int32 i = 0; i < saveCount; ++i)\r
+ {\r
+ saveA[i] = vertices[i].indexA;\r
+ saveB[i] = vertices[i].indexB;\r
+ }\r
+\r
+ switch (simplex.m_count)\r
+ {\r
+ case 1:\r
+ break;\r
+\r
+ case 2:\r
+ simplex.Solve2();\r
+ break;\r
+\r
+ case 3:\r
+ simplex.Solve3();\r
+ break;\r
+\r
+ default:\r
+ b2Assert(false);\r
+ }\r
+\r
+ // If we have 3 points, then the origin is in the corresponding triangle.\r
+ if (simplex.m_count == 3)\r
+ {\r
+ break;\r
+ }\r
+\r
+ // Compute closest point.\r
+ b2Vec2 p = simplex.GetClosestPoint();\r
+ distanceSqr2 = p.LengthSquared();\r
+\r
+ // Ensure progress\r
+ if (distanceSqr2 >= distanceSqr1)\r
+ {\r
+ //break;\r
+ }\r
+ distanceSqr1 = distanceSqr2;\r
+\r
+ // Get search direction.\r
+ b2Vec2 d = simplex.GetSearchDirection();\r
+\r
+ // Ensure the search direction is numerically fit.\r
+ if (d.LengthSquared() < b2_epsilon * b2_epsilon)\r
+ {\r
+ // The origin is probably contained by a line segment\r
+ // or triangle. Thus the shapes are overlapped.\r
+\r
+ // We can't return zero here even though there may be overlap.\r
+ // In case the simplex is a point, segment, or triangle it is difficult\r
+ // to determine if the origin is contained in the CSO or very close to it.\r
+ break;\r
+ }\r
+\r
+ // Compute a tentative new simplex vertex using support points.\r
+ b2SimplexVertex* vertex = vertices + simplex.m_count;\r
+ vertex->indexA = proxyA->GetSupport(b2MulT(transformA.R, -d));\r
+ vertex->wA = b2Mul(transformA, proxyA->GetVertex(vertex->indexA));\r
+ b2Vec2 wBLocal;\r
+ vertex->indexB = proxyB->GetSupport(b2MulT(transformB.R, d));\r
+ vertex->wB = b2Mul(transformB, proxyB->GetVertex(vertex->indexB));\r
+ vertex->w = vertex->wB - vertex->wA;\r
+\r
+ // Iteration count is equated to the number of support point calls.\r
+ ++iter;\r
+ ++b2_gjkIters;\r
+\r
+ // Check for duplicate support points. This is the main termination criteria.\r
+ bool duplicate = false;\r
+ for (int32 i = 0; i < saveCount; ++i)\r
+ {\r
+ if (vertex->indexA == saveA[i] && vertex->indexB == saveB[i])\r
+ {\r
+ duplicate = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ // If we found a duplicate support point we must exit to avoid cycling.\r
+ if (duplicate)\r
+ {\r
+ break;\r
+ }\r
+\r
+ // New vertex is ok and needed.\r
+ ++simplex.m_count;\r
+ }\r
+\r
+ b2_gjkMaxIters = b2Max(b2_gjkMaxIters, iter);\r
+\r
+ // Prepare output.\r
+ simplex.GetWitnessPoints(&output->pointA, &output->pointB);\r
+ output->distance = b2Distance(output->pointA, output->pointB);\r
+ output->iterations = iter;\r
+\r
+ // Cache the simplex.\r
+ simplex.WriteCache(cache);\r
+\r
+ // Apply radii if requested.\r
+ if (input->useRadii)\r
+ {\r
+ float32 rA = proxyA->m_radius;\r
+ float32 rB = proxyB->m_radius;\r
+\r
+ if (output->distance > rA + rB && output->distance > b2_epsilon)\r
+ {\r
+ // Shapes are still no overlapped.\r
+ // Move the witness points to the outer surface.\r
+ output->distance -= rA + rB;\r
+ b2Vec2 normal = output->pointB - output->pointA;\r
+ normal.Normalize();\r
+ output->pointA += rA * normal;\r
+ output->pointB -= rB * normal;\r
+ }\r
+ else\r
+ {\r
+ // Shapes are overlapped when radii are considered.\r
+ // Move the witness points to the middle.\r
+ b2Vec2 p = 0.5f * (output->pointA + output->pointB);\r
+ output->pointA = p;\r
+ output->pointB = p;\r
+ output->distance = 0.0f;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+\r
+/*\r
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_DISTANCE_H\r
+#define B2_DISTANCE_H\r
+\r
+#include <Box2D/Common/b2Math.h>\r
+#include <climits>\r
+\r
+class b2Shape;\r
+\r
+/// A distance proxy is used by the GJK algorithm.\r
+/// It encapsulates any shape.\r
+struct b2DistanceProxy\r
+{\r
+ b2DistanceProxy() : m_vertices(NULL), m_count(0), m_radius(0.0f) {}\r
+\r
+ /// Initialize the proxy using the given shape. The shape\r
+ /// must remain in scope while the proxy is in use.\r
+ void Set(const b2Shape* shape);\r
+\r
+ /// Get the supporting vertex index in the given direction.\r
+ int32 GetSupport(const b2Vec2& d) const;\r
+\r
+ /// Get the supporting vertex in the given direction.\r
+ const b2Vec2& GetSupportVertex(const b2Vec2& d) const;\r
+\r
+ /// Get the vertex count.\r
+ int32 GetVertexCount() const;\r
+\r
+ /// Get a vertex by index. Used by b2Distance.\r
+ const b2Vec2& GetVertex(int32 index) const;\r
+\r
+ const b2Vec2* m_vertices;\r
+ int32 m_count;\r
+ float32 m_radius;\r
+};\r
+\r
+/// Used to warm start b2Distance.\r
+/// Set count to zero on first call.\r
+struct b2SimplexCache\r
+{\r
+ float32 metric; ///< length or area\r
+ uint16 count;\r
+ uint8 indexA[3]; ///< vertices on shape A\r
+ uint8 indexB[3]; ///< vertices on shape B\r
+};\r
+\r
+/// Input for b2Distance.\r
+/// You have to option to use the shape radii\r
+/// in the computation. Even \r
+struct b2DistanceInput\r
+{\r
+ b2DistanceProxy proxyA;\r
+ b2DistanceProxy proxyB;\r
+ b2Transform transformA;\r
+ b2Transform transformB;\r
+ bool useRadii;\r
+};\r
+\r
+/// Output for b2Distance.\r
+struct b2DistanceOutput\r
+{\r
+ b2Vec2 pointA; ///< closest point on shapeA\r
+ b2Vec2 pointB; ///< closest point on shapeB\r
+ float32 distance;\r
+ int32 iterations; ///< number of GJK iterations used\r
+};\r
+\r
+/// Compute the closest points between two shapes. Supports any combination of:\r
+/// b2CircleShape, b2PolygonShape, b2EdgeShape. The simplex cache is input/output.\r
+/// On the first call set b2SimplexCache.count to zero.\r
+void b2Distance(b2DistanceOutput* output,\r
+ b2SimplexCache* cache, \r
+ const b2DistanceInput* input);\r
+\r
+\r
+//////////////////////////////////////////////////////////////////////////\r
+\r
+inline int32 b2DistanceProxy::GetVertexCount() const\r
+{\r
+ return m_count;\r
+}\r
+\r
+inline const b2Vec2& b2DistanceProxy::GetVertex(int32 index) const\r
+{\r
+ b2Assert(0 <= index && index < m_count);\r
+ return m_vertices[index];\r
+}\r
+\r
+inline int32 b2DistanceProxy::GetSupport(const b2Vec2& d) const\r
+{\r
+ int32 bestIndex = 0;\r
+ float32 bestValue = b2Dot(m_vertices[0], d);\r
+ for (int32 i = 1; i < m_count; ++i)\r
+ {\r
+ float32 value = b2Dot(m_vertices[i], d);\r
+ if (value > bestValue)\r
+ {\r
+ bestIndex = i;\r
+ bestValue = value;\r
+ }\r
+ }\r
+\r
+ return bestIndex;\r
+}\r
+\r
+inline const b2Vec2& b2DistanceProxy::GetSupportVertex(const b2Vec2& d) const\r
+{\r
+ int32 bestIndex = 0;\r
+ float32 bestValue = b2Dot(m_vertices[0], d);\r
+ for (int32 i = 1; i < m_count; ++i)\r
+ {\r
+ float32 value = b2Dot(m_vertices[i], d);\r
+ if (value > bestValue)\r
+ {\r
+ bestIndex = i;\r
+ bestValue = value;\r
+ }\r
+ }\r
+\r
+ return m_vertices[bestIndex];\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2DynamicTree.h>\r
+#include <cstring>\r
+#include <cfloat>\r
+\r
+b2DynamicTree::b2DynamicTree()\r
+{\r
+ m_root = b2_nullNode;\r
+\r
+ m_nodeCapacity = 16;\r
+ m_nodeCount = 0;\r
+ m_nodes = (b2DynamicTreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2DynamicTreeNode));\r
+ memset(m_nodes, 0, m_nodeCapacity * sizeof(b2DynamicTreeNode));\r
+\r
+ // Build a linked list for the free list.\r
+ for (int32 i = 0; i < m_nodeCapacity - 1; ++i)\r
+ {\r
+ m_nodes[i].next = i + 1;\r
+ }\r
+ m_nodes[m_nodeCapacity-1].next = b2_nullNode;\r
+ m_freeList = 0;\r
+\r
+ m_path = 0;\r
+\r
+ m_insertionCount = 0;\r
+}\r
+\r
+b2DynamicTree::~b2DynamicTree()\r
+{\r
+ // This frees the entire tree in one shot.\r
+ b2Free(m_nodes);\r
+}\r
+\r
+// Allocate a node from the pool. Grow the pool if necessary.\r
+int32 b2DynamicTree::AllocateNode()\r
+{\r
+ // Expand the node pool as needed.\r
+ if (m_freeList == b2_nullNode)\r
+ {\r
+ b2Assert(m_nodeCount == m_nodeCapacity);\r
+\r
+ // The free list is empty. Rebuild a bigger pool.\r
+ b2DynamicTreeNode* oldNodes = m_nodes;\r
+ m_nodeCapacity *= 2;\r
+ m_nodes = (b2DynamicTreeNode*)b2Alloc(m_nodeCapacity * sizeof(b2DynamicTreeNode));\r
+ memcpy(m_nodes, oldNodes, m_nodeCount * sizeof(b2DynamicTreeNode));\r
+ b2Free(oldNodes);\r
+\r
+ // Build a linked list for the free list. The parent\r
+ // pointer becomes the "next" pointer.\r
+ for (int32 i = m_nodeCount; i < m_nodeCapacity - 1; ++i)\r
+ {\r
+ m_nodes[i].next = i + 1;\r
+ }\r
+ m_nodes[m_nodeCapacity-1].next = b2_nullNode;\r
+ m_freeList = m_nodeCount;\r
+ }\r
+\r
+ // Peel a node off the free list.\r
+ int32 nodeId = m_freeList;\r
+ m_freeList = m_nodes[nodeId].next;\r
+ m_nodes[nodeId].parent = b2_nullNode;\r
+ m_nodes[nodeId].child1 = b2_nullNode;\r
+ m_nodes[nodeId].child2 = b2_nullNode;\r
+ ++m_nodeCount;\r
+ return nodeId;\r
+}\r
+\r
+// Return a node to the pool.\r
+void b2DynamicTree::FreeNode(int32 nodeId)\r
+{\r
+ b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);\r
+ b2Assert(0 < m_nodeCount);\r
+ m_nodes[nodeId].next = m_freeList;\r
+ m_freeList = nodeId;\r
+ --m_nodeCount;\r
+}\r
+\r
+// Create a proxy in the tree as a leaf node. We return the index\r
+// of the node instead of a pointer so that we can grow\r
+// the node pool.\r
+int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)\r
+{\r
+ int32 proxyId = AllocateNode();\r
+\r
+ // Fatten the aabb.\r
+ b2Vec2 r(b2_aabbExtension, b2_aabbExtension);\r
+ m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;\r
+ m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;\r
+ m_nodes[proxyId].userData = userData;\r
+\r
+ InsertLeaf(proxyId);\r
+\r
+ // Rebalance if necessary.\r
+ int32 iterationCount = m_nodeCount >> 4;\r
+ int32 tryCount = 0;\r
+ int32 height = ComputeHeight();\r
+ while (height > 64 && tryCount < 10)\r
+ {\r
+ Rebalance(iterationCount);\r
+ height = ComputeHeight();\r
+ ++tryCount;\r
+ }\r
+\r
+ return proxyId;\r
+}\r
+\r
+void b2DynamicTree::DestroyProxy(int32 proxyId)\r
+{\r
+ b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);\r
+ b2Assert(m_nodes[proxyId].IsLeaf());\r
+\r
+ RemoveLeaf(proxyId);\r
+ FreeNode(proxyId);\r
+}\r
+\r
+bool b2DynamicTree::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement)\r
+{\r
+ b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);\r
+\r
+ b2Assert(m_nodes[proxyId].IsLeaf());\r
+\r
+ if (m_nodes[proxyId].aabb.Contains(aabb))\r
+ {\r
+ return false;\r
+ }\r
+\r
+ RemoveLeaf(proxyId);\r
+\r
+ // Extend AABB.\r
+ b2AABB b = aabb;\r
+ b2Vec2 r(b2_aabbExtension, b2_aabbExtension);\r
+ b.lowerBound = b.lowerBound - r;\r
+ b.upperBound = b.upperBound + r;\r
+\r
+ // Predict AABB displacement.\r
+ b2Vec2 d = b2_aabbMultiplier * displacement;\r
+\r
+ if (d.x < 0.0f)\r
+ {\r
+ b.lowerBound.x += d.x;\r
+ }\r
+ else\r
+ {\r
+ b.upperBound.x += d.x;\r
+ }\r
+\r
+ if (d.y < 0.0f)\r
+ {\r
+ b.lowerBound.y += d.y;\r
+ }\r
+ else\r
+ {\r
+ b.upperBound.y += d.y;\r
+ }\r
+\r
+ m_nodes[proxyId].aabb = b;\r
+\r
+ InsertLeaf(proxyId);\r
+ return true;\r
+}\r
+\r
+void b2DynamicTree::InsertLeaf(int32 leaf)\r
+{\r
+ ++m_insertionCount;\r
+\r
+ if (m_root == b2_nullNode)\r
+ {\r
+ m_root = leaf;\r
+ m_nodes[m_root].parent = b2_nullNode;\r
+ return;\r
+ }\r
+\r
+ // Find the best sibling for this node.\r
+ b2Vec2 center = m_nodes[leaf].aabb.GetCenter();\r
+ int32 sibling = m_root;\r
+ if (m_nodes[sibling].IsLeaf() == false)\r
+ {\r
+ do \r
+ {\r
+ int32 child1 = m_nodes[sibling].child1;\r
+ int32 child2 = m_nodes[sibling].child2;\r
+\r
+ b2Vec2 delta1 = b2Abs(m_nodes[child1].aabb.GetCenter() - center);\r
+ b2Vec2 delta2 = b2Abs(m_nodes[child2].aabb.GetCenter() - center);\r
+\r
+ float32 norm1 = delta1.x + delta1.y;\r
+ float32 norm2 = delta2.x + delta2.y;\r
+\r
+ if (norm1 < norm2)\r
+ {\r
+ sibling = child1;\r
+ }\r
+ else\r
+ {\r
+ sibling = child2;\r
+ }\r
+\r
+ }\r
+ while(m_nodes[sibling].IsLeaf() == false);\r
+ }\r
+\r
+ // Create a parent for the siblings.\r
+ int32 node1 = m_nodes[sibling].parent;\r
+ int32 node2 = AllocateNode();\r
+ m_nodes[node2].parent = node1;\r
+ m_nodes[node2].userData = NULL;\r
+ m_nodes[node2].aabb.Combine(m_nodes[leaf].aabb, m_nodes[sibling].aabb);\r
+\r
+ if (node1 != b2_nullNode)\r
+ {\r
+ if (m_nodes[m_nodes[sibling].parent].child1 == sibling)\r
+ {\r
+ m_nodes[node1].child1 = node2;\r
+ }\r
+ else\r
+ {\r
+ m_nodes[node1].child2 = node2;\r
+ }\r
+\r
+ m_nodes[node2].child1 = sibling;\r
+ m_nodes[node2].child2 = leaf;\r
+ m_nodes[sibling].parent = node2;\r
+ m_nodes[leaf].parent = node2;\r
+\r
+ do \r
+ {\r
+ if (m_nodes[node1].aabb.Contains(m_nodes[node2].aabb))\r
+ {\r
+ break;\r
+ }\r
+\r
+ m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb);\r
+ node2 = node1;\r
+ node1 = m_nodes[node1].parent;\r
+ }\r
+ while(node1 != b2_nullNode);\r
+ }\r
+ else\r
+ {\r
+ m_nodes[node2].child1 = sibling;\r
+ m_nodes[node2].child2 = leaf;\r
+ m_nodes[sibling].parent = node2;\r
+ m_nodes[leaf].parent = node2;\r
+ m_root = node2;\r
+ }\r
+}\r
+\r
+void b2DynamicTree::RemoveLeaf(int32 leaf)\r
+{\r
+ if (leaf == m_root)\r
+ {\r
+ m_root = b2_nullNode;\r
+ return;\r
+ }\r
+\r
+ int32 node2 = m_nodes[leaf].parent;\r
+ int32 node1 = m_nodes[node2].parent;\r
+ int32 sibling;\r
+ if (m_nodes[node2].child1 == leaf)\r
+ {\r
+ sibling = m_nodes[node2].child2;\r
+ }\r
+ else\r
+ {\r
+ sibling = m_nodes[node2].child1;\r
+ }\r
+\r
+ if (node1 != b2_nullNode)\r
+ {\r
+ // Destroy node2 and connect node1 to sibling.\r
+ if (m_nodes[node1].child1 == node2)\r
+ {\r
+ m_nodes[node1].child1 = sibling;\r
+ }\r
+ else\r
+ {\r
+ m_nodes[node1].child2 = sibling;\r
+ }\r
+ m_nodes[sibling].parent = node1;\r
+ FreeNode(node2);\r
+\r
+ // Adjust ancestor bounds.\r
+ while (node1 != b2_nullNode)\r
+ {\r
+ b2AABB oldAABB = m_nodes[node1].aabb;\r
+ m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb);\r
+\r
+ if (oldAABB.Contains(m_nodes[node1].aabb))\r
+ {\r
+ break;\r
+ }\r
+\r
+ node1 = m_nodes[node1].parent;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ m_root = sibling;\r
+ m_nodes[sibling].parent = b2_nullNode;\r
+ FreeNode(node2);\r
+ }\r
+}\r
+\r
+void b2DynamicTree::Rebalance(int32 iterations)\r
+{\r
+ if (m_root == b2_nullNode)\r
+ {\r
+ return;\r
+ }\r
+\r
+ for (int32 i = 0; i < iterations; ++i)\r
+ {\r
+ int32 node = m_root;\r
+\r
+ uint32 bit = 0;\r
+ while (m_nodes[node].IsLeaf() == false)\r
+ {\r
+ int32* children = &m_nodes[node].child1;\r
+ node = children[(m_path >> bit) & 1];\r
+ bit = (bit + 1) & (8* sizeof(uint32) - 1);\r
+ }\r
+ ++m_path;\r
+\r
+ RemoveLeaf(node);\r
+ InsertLeaf(node);\r
+ }\r
+}\r
+\r
+// Compute the height of a sub-tree.\r
+int32 b2DynamicTree::ComputeHeight(int32 nodeId) const\r
+{\r
+ if (nodeId == b2_nullNode)\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ b2Assert(0 <= nodeId && nodeId < m_nodeCapacity);\r
+ b2DynamicTreeNode* node = m_nodes + nodeId;\r
+ int32 height1 = ComputeHeight(node->child1);\r
+ int32 height2 = ComputeHeight(node->child2);\r
+ return 1 + b2Max(height1, height2);\r
+}\r
+\r
+int32 b2DynamicTree::ComputeHeight() const\r
+{\r
+ return ComputeHeight(m_root);\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#ifndef B2_DYNAMIC_TREE_H\r
+#define B2_DYNAMIC_TREE_H\r
+\r
+#include <Box2D/Collision/b2Collision.h>\r
+\r
+/// A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt.\r
+\r
+#define b2_nullNode (-1)\r
+\r
+/// A node in the dynamic tree. The client does not interact with this directly.\r
+struct b2DynamicTreeNode\r
+{\r
+ bool IsLeaf() const\r
+ {\r
+ return child1 == b2_nullNode;\r
+ }\r
+\r
+ /// This is the fattened AABB.\r
+ b2AABB aabb;\r
+\r
+ //int32 userData;\r
+ void* userData;\r
+\r
+ union\r
+ {\r
+ int32 parent;\r
+ int32 next;\r
+ };\r
+\r
+ int32 child1;\r
+ int32 child2;\r
+};\r
+\r
+/// A dynamic tree arranges data in a binary tree to accelerate\r
+/// queries such as volume queries and ray casts. Leafs are proxies\r
+/// with an AABB. In the tree we expand the proxy AABB by b2_fatAABBFactor\r
+/// so that the proxy AABB is bigger than the client object. This allows the client\r
+/// object to move by small amounts without triggering a tree update.\r
+///\r
+/// Nodes are pooled and relocatable, so we use node indices rather than pointers.\r
+class b2DynamicTree\r
+{\r
+public:\r
+\r
+ /// Constructing the tree initializes the node pool.\r
+ b2DynamicTree();\r
+\r
+ /// Destroy the tree, freeing the node pool.\r
+ ~b2DynamicTree();\r
+\r
+ /// Create a proxy. Provide a tight fitting AABB and a userData pointer.\r
+ int32 CreateProxy(const b2AABB& aabb, void* userData);\r
+\r
+ /// Destroy a proxy. This asserts if the id is invalid.\r
+ void DestroyProxy(int32 proxyId);\r
+\r
+ /// Move a proxy with a swepted AABB. If the proxy has moved outside of its fattened AABB,\r
+ /// then the proxy is removed from the tree and re-inserted. Otherwise\r
+ /// the function returns immediately.\r
+ /// @return true if the proxy was re-inserted.\r
+ bool MoveProxy(int32 proxyId, const b2AABB& aabb1, const b2Vec2& displacement);\r
+\r
+ /// Perform some iterations to re-balance the tree.\r
+ void Rebalance(int32 iterations);\r
+\r
+ /// Get proxy user data.\r
+ /// @return the proxy user data or 0 if the id is invalid.\r
+ void* GetUserData(int32 proxyId) const;\r
+\r
+ /// Get the fat AABB for a proxy.\r
+ const b2AABB& GetFatAABB(int32 proxyId) const;\r
+\r
+ /// Compute the height of the tree.\r
+ int32 ComputeHeight() const;\r
+\r
+ /// Query an AABB for overlapping proxies. The callback class\r
+ /// is called for each proxy that overlaps the supplied AABB.\r
+ template <typename T>\r
+ void Query(T* callback, const b2AABB& aabb) const;\r
+\r
+ /// Ray-cast against the proxies in the tree. This relies on the callback\r
+ /// to perform a exact ray-cast in the case were the proxy contains a shape.\r
+ /// The callback also performs the any collision filtering. This has performance\r
+ /// roughly equal to k * log(n), where k is the number of collisions and n is the\r
+ /// number of proxies in the tree.\r
+ /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).\r
+ /// @param callback a callback class that is called for each proxy that is hit by the ray.\r
+ template <typename T>\r
+ void RayCast(T* callback, const b2RayCastInput& input) const;\r
+\r
+private:\r
+\r
+ int32 AllocateNode();\r
+ void FreeNode(int32 node);\r
+\r
+ void InsertLeaf(int32 node);\r
+ void RemoveLeaf(int32 node);\r
+\r
+ int32 ComputeHeight(int32 nodeId) const;\r
+\r
+ int32 m_root;\r
+\r
+ b2DynamicTreeNode* m_nodes;\r
+ int32 m_nodeCount;\r
+ int32 m_nodeCapacity;\r
+\r
+ int32 m_freeList;\r
+\r
+ /// This is used incrementally traverse the tree for re-balancing.\r
+ uint32 m_path;\r
+\r
+ int32 m_insertionCount;\r
+};\r
+\r
+inline void* b2DynamicTree::GetUserData(int32 proxyId) const\r
+{\r
+ b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);\r
+ return m_nodes[proxyId].userData;\r
+}\r
+\r
+inline const b2AABB& b2DynamicTree::GetFatAABB(int32 proxyId) const\r
+{\r
+ b2Assert(0 <= proxyId && proxyId < m_nodeCapacity);\r
+ return m_nodes[proxyId].aabb;\r
+}\r
+\r
+template <typename T>\r
+inline void b2DynamicTree::Query(T* callback, const b2AABB& aabb) const\r
+{\r
+ const int32 k_stackSize = 128;\r
+ int32 stack[k_stackSize];\r
+\r
+ int32 count = 0;\r
+ stack[count++] = m_root;\r
+\r
+ while (count > 0)\r
+ {\r
+ int32 nodeId = stack[--count];\r
+ if (nodeId == b2_nullNode)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ const b2DynamicTreeNode* node = m_nodes + nodeId;\r
+\r
+ if (b2TestOverlap(node->aabb, aabb))\r
+ {\r
+ if (node->IsLeaf())\r
+ {\r
+ bool proceed = callback->QueryCallback(nodeId);\r
+ if (proceed == false)\r
+ {\r
+ return;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (count < k_stackSize)\r
+ {\r
+ stack[count++] = node->child1;\r
+ }\r
+\r
+ if (count < k_stackSize)\r
+ {\r
+ stack[count++] = node->child2;\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+template <typename T>\r
+inline void b2DynamicTree::RayCast(T* callback, const b2RayCastInput& input) const\r
+{\r
+ b2Vec2 p1 = input.p1;\r
+ b2Vec2 p2 = input.p2;\r
+ b2Vec2 r = p2 - p1;\r
+ b2Assert(r.LengthSquared() > 0.0f);\r
+ r.Normalize();\r
+\r
+ // v is perpendicular to the segment.\r
+ b2Vec2 v = b2Cross(1.0f, r);\r
+ b2Vec2 abs_v = b2Abs(v);\r
+\r
+ // Separating axis for segment (Gino, p80).\r
+ // |dot(v, p1 - c)| > dot(|v|, h)\r
+\r
+ float32 maxFraction = input.maxFraction;\r
+\r
+ // Build a bounding box for the segment.\r
+ b2AABB segmentAABB;\r
+ {\r
+ b2Vec2 t = p1 + maxFraction * (p2 - p1);\r
+ segmentAABB.lowerBound = b2Min(p1, t);\r
+ segmentAABB.upperBound = b2Max(p1, t);\r
+ }\r
+\r
+ const int32 k_stackSize = 128;\r
+ int32 stack[k_stackSize];\r
+\r
+ int32 count = 0;\r
+ stack[count++] = m_root;\r
+\r
+ while (count > 0)\r
+ {\r
+ int32 nodeId = stack[--count];\r
+ if (nodeId == b2_nullNode)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ const b2DynamicTreeNode* node = m_nodes + nodeId;\r
+\r
+ if (b2TestOverlap(node->aabb, segmentAABB) == false)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ // Separating axis for segment (Gino, p80).\r
+ // |dot(v, p1 - c)| > dot(|v|, h)\r
+ b2Vec2 c = node->aabb.GetCenter();\r
+ b2Vec2 h = node->aabb.GetExtents();\r
+ float32 separation = b2Abs(b2Dot(v, p1 - c)) - b2Dot(abs_v, h);\r
+ if (separation > 0.0f)\r
+ {\r
+ continue;\r
+ }\r
+\r
+ if (node->IsLeaf())\r
+ {\r
+ b2RayCastInput subInput;\r
+ subInput.p1 = input.p1;\r
+ subInput.p2 = input.p2;\r
+ subInput.maxFraction = maxFraction;\r
+\r
+ float32 value = callback->RayCastCallback(subInput, nodeId);\r
+\r
+ if (value == 0.0f)\r
+ {\r
+ // The client has terminated the ray cast.\r
+ return;\r
+ }\r
+\r
+ if (value > 0.0f)\r
+ {\r
+ // Update segment bounding box.\r
+ maxFraction = value;\r
+ b2Vec2 t = p1 + maxFraction * (p2 - p1);\r
+ segmentAABB.lowerBound = b2Min(p1, t);\r
+ segmentAABB.upperBound = b2Max(p1, t);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (count < k_stackSize)\r
+ {\r
+ stack[count++] = node->child1;\r
+ }\r
+\r
+ if (count < k_stackSize)\r
+ {\r
+ stack[count++] = node->child2;\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+#endif\r
--- /dev/null
+/*\r
+* Copyright (c) 2007-2009 Erin Catto http://www.gphysics.com\r
+*\r
+* This software is provided 'as-is', without any express or implied\r
+* warranty. In no event will the authors be held liable for any damages\r
+* arising from the use of this software.\r
+* Permission is granted to anyone to use this software for any purpose,\r
+* including commercial applications, and to alter it and redistribute it\r
+* freely, subject to the following restrictions:\r
+* 1. The origin of this software must not be misrepresented; you must not\r
+* claim that you wrote the original software. If you use this software\r
+* in a product, an acknowledgment in the product documentation would be\r
+* appreciated but is not required.\r
+* 2. Altered source versions must be plainly marked as such, and must not be\r
+* misrepresented as being the original software.\r
+* 3. This notice may not be removed or altered from any source distribution.\r
+*/\r
+\r
+#include <Box2D/Collision/b2Collision.h>\r
+#include <Box2D/Collision/b2Distance.h>\r
+#include <Box2D/Collision/b2TimeOfImpact.h>\r
+#include <Box2D/Collision/Shapes/b2CircleShape.h>\r
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>\r
+\r
+#include <cstdio>\r
+\r
+int32 b2_toiCalls, b2_toiIters, b2_toiMaxIters;\r
+int32 b2_toiRootIters, b2_toiMaxRootIters;\r
+\r
+int32 b2_toiMaxOptIters;\r
+\r
+struct b2SeparationFunction\r
+{\r
+ enum Type\r
+ {\r
+ e_points,\r
+ e_faceA,\r
+ e_faceB\r
+ };\r
+\r
+ // TODO_ERIN might not need to return the separation\r
+\r
+ float32 Initialize(const b2SimplexCache* cache,\r
+ const b2DistanceProxy* proxyA, const b2Sweep& sweepA,\r
+ const b2DistanceProxy* proxyB, const b2Sweep& sweepB)\r
+ {\r
+ m_proxyA = proxyA;\r
+ m_proxyB = proxyB;\r
+ int32 count = cache->count;\r
+ b2Assert(0 < count && count < 3);\r
+\r
+ m_sweepA = sweepA;\r
+ m_sweepB = sweepB;\r
+\r
+ b2Transform xfA, xfB;\r
+ m_sweepA.GetTransform(&xfA, 0.0f);\r
+ m_sweepB.GetTransform(&xfB, 0.0f);\r
+\r
+ if (count == 1)\r
+ {\r
+ m_type = e_points;\r
+ b2Vec2 localPointA = m_proxyA->GetVertex(cache->indexA[0]);\r
+ b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);\r
+ b2Vec2 pointA = b2Mul(xfA, localPointA);\r
+ b2Vec2 pointB = b2Mul(xfB, localPointB);\r
+ m_axis = pointB - pointA;\r
+ float32 s = m_axis.Normalize();\r
+ return s;\r
+ }\r
+ else if (cache->indexA[0] == cache->indexA[1])\r
+ {\r
+ // Two points on B and one on A.\r
+ m_type = e_faceB;\r
+ b2Vec2 localPointB1 = proxyB->GetVertex(cache->indexB[0]);\r
+ b2Vec2 localPointB2 = proxyB->GetVertex(cache->indexB[1]);\r
+\r
+ m_axis = b2Cross(localPointB2 - localPointB1, 1.0f);\r
+ m_axis.Normalize();\r
+ b2Vec2 normal = b2Mul(xfB.R, m_axis);\r
+\r
+ m_localPoint = 0.5f * (localPointB1 + localPointB2);\r
+ b2Vec2 pointB = b2Mul(xfB, m_localPoint);\r
+\r
+ b2Vec2 localPointA = proxyA->GetVertex(cache->indexA[0]);\r
+ b2Vec2 pointA = b2Mul(xfA, localPointA);\r
+\r
+ float32 s = b2Dot(pointA - pointB, normal);\r
+ if (s < 0.0f)\r
+ {\r
+ m_axis = -m_axis;\r
+ s = -s;\r
+ }\r
+ return s;\r
+ }\r
+ else\r
+ {\r
+ // Two points on A and one or two points on B.\r
+ m_type = e_faceA;\r
+ b2Vec2 localPointA1 = m_proxyA->GetVertex(cache->indexA[0]);\r
+ b2Vec2 localPointA2 = m_proxyA->GetVertex(cache->indexA[1]);\r
+ \r
+ m_axis = b2Cross(localPointA2 - localPointA1, 1.0f);\r
+ m_axis.Normalize();\r
+ b2Vec2 normal = b2Mul(xfA.R, m_axis);\r
+\r
+ m_localPoint = 0.5f * (localPointA1 + localPointA2);\r
+ b2Vec2 pointA = b2Mul(xfA, m_localPoint);\r
+\r
+ b2Vec2 localPointB = m_proxyB->GetVertex(cache->indexB[0]);\r
+ b2Vec2 pointB = b2Mul(xfB, localPointB);\r
+\r
+ float32 s = b2Dot(pointB - pointA, normal);\r
+ if (s < 0.0f)\r
+ {\r
+ m_axis = -m_axis;\r
+ s = -s;\r
+ }\r
+ return s;\r
+ }\r
+ }\r
+\r
+ float32 FindMinSeparation(int32* indexA, int32* indexB, float32 t) const\r
+ {\r
+ b2Transform xfA, xfB;\r
+ m_sweepA.GetTransform(&xfA, t);\r
+ m_sweepB.GetTransform(&xfB, t);\r
+\r
+ switch (m_type)\r
+ {\r
+ case e_points:\r
+ {\r
+ b2Vec2 axisA = b2MulT(xfA.R, m_axis);\r
+ b2Vec2 axisB = b2MulT(xfB.R, -m_axis);\r
+\r
+ *indexA = m_proxyA->GetSupport(axisA);\r
+ *indexB = m_proxyB->GetSupport(axisB);\r
+\r
+ b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);\r
+ b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);\r
+ \r
+ b2Vec2 pointA = b2Mul(xfA, localPointA);\r
+ b2Vec2 pointB = b2Mul(xfB, localPointB);\r
+\r
+ float32 separation = b2Dot(pointB - pointA, m_axis);\r
+ return separation;\r
+ }\r
+\r
+ case e_faceA:\r
+ {\r
+ b2Vec2 normal = b2Mul(xfA.R, m_axis);\r
+ b2Vec2 pointA = b2Mul(xfA, m_localPoint);\r
+\r
+ b2Vec2 axisB = b2MulT(xfB.R, -normal);\r
+ \r
+ *indexA = -1;\r
+ *indexB = m_proxyB->GetSupport(axisB);\r
+\r
+ b2Vec2 localPointB = m_proxyB->GetVertex(*indexB);\r
+ b2Vec2 pointB = b2Mul(xfB, localPointB);\r
+\r
+ float32 separation = b2Dot(pointB - pointA, normal);\r
+ return separation;\r
+ }\r
+\r
+ case e_faceB:\r
+ {\r
+ b2Vec2 normal = b2Mul(xfB.R, m_axis);\r
+ b2Vec2 pointB = b2Mul(xfB, m_localPoint);\r
+\r
+ b2Vec2 axisA = b2MulT(xfA.R, -normal);\r
+\r
+ *indexB = -1;\r
+ *indexA = m_proxyA->GetSupport(axisA);\r
+\r
+ b2Vec2 localPointA = m_proxyA->GetVertex(*indexA);\r
+ b2Vec2 pointA = b2Mul(xfA, localPointA);\r
+\r
+ float32 separation = b2Dot(pointA - pointB, normal);\r
+ return separation;\r
+ }\r
+\r
+ default:\r
+ b2Assert(false);\r
+ *indexA = -1;\r
+ *indexB = -1;\r
+ return 0.0f;\r
+ }\r
+ }\r
+\r
+ float32 Evaluate(int32 indexA, int32 indexB, float32 t) const\r
+ {\r
+ b2Transform xfA, xfB;\r
+ m_sweepA.GetTransform(&xfA, t);\r
+ m_sweepB.GetTransform(&xfB, t);\r
+\r
+ switch (m_type)\r
+ {\r
+ case e_points:\r
+ {\r
+ b2Vec2 axisA = b2MulT(xfA.R, m_axis);\r
+ b2Vec2 axisB = b2MulT(xfB.R, -m_axis);\r
+\r
+ b2Vec2 localPointA = m_proxyA->GetVertex(indexA);\r
+ b2Vec2 localPointB = m_proxyB->GetVertex(indexB);\r
+\r
+ b2Vec2 pointA = b2Mul(xfA, localPointA);\r
+ b2Vec2 pointB = b2Mul(xfB, localPointB);\r
+ float32 separation = b2Dot(pointB - pointA, m_axis);\r
+\r
+ return separation;\r
+ }\r
+\r
+ case e_faceA:\r
+ {\r
+ b2Vec2 normal = b2Mul(xfA.R, m_axis);\r
+ b2Vec2 pointA = b2Mul(xfA, m_localPoint);\r
+\r
+ b2Vec2 axisB = b2MulT(xfB.R, -normal);\r
+\r
+ b2Vec2 localPointB = m_proxyB->GetVertex(indexB);\r
+ b2Vec2 pointB = b2Mul(xfB, localPointB);\r
+\r
+ float32 separation = b2Dot(pointB - pointA, normal);\r
+ return separation;\r
+ }\r
+\r
+ case e_faceB:\r
+ {\r
+ b2Vec2 normal = b2Mul(xfB.R, m_axis);\r
+ b2Vec2 pointB = b2Mul(xfB, m_localPoint);\r
+\r
+ b2Vec2 axisA = b2MulT(xfA.R, -normal);\r
+\r
+ b2Vec2 localPointA = m_proxyA->GetVertex(indexA);\r
+ b2Vec2 pointA = b2Mul(xfA, localPointA);\r
+\r
+ float32 separation = b2Dot(pointA - pointB, normal);\r
+ return separation;\r
+ }\r
+\r
+ default:\r
+ b2Assert(false);\r
+ return 0.0f;\r
+ }\r
+ }\r
+\r
+ const b2DistanceProxy* m_proxyA;\r
+ const b2DistanceProxy* m_proxyB;\r
+ b2Sweep m_sweepA, m_sweepB;\r
+ Type m_type;\r
+ b2Vec2 m_localPoint;\r
+ b2Vec2 m_axis;\r
+};\r
+\r
+// CCD via the local separating axis method. This seeks progression\r
+// by computing the largest time at which separation is maintained.\r
+void b2TimeOfImpact(b2TOIOutput* output, const b2TOIInput* input)\r
+{\r
+ ++b2_toiCalls;\r
+\r
+ output->state = b2TOIOutput::e_unknown;\r
+ output->t = input->tMax;\r
+\r
+ const b2DistanceProxy* proxyA = &input->proxyA;\r
+ const b2DistanceProxy* proxyB = &input->proxyB;\r
+\r
+ b2Sweep sweepA = input->sweepA;\r
+ b2Sweep sweepB = input->sweepB;\r
+\r
+ // Large rotations can make the root finder fail, so we normalize the\r
+ // sweep angles.\r
+ sweepA.Normalize();\r
+ sweepB.Normalize();\r
+\r
+ float32 tMax = input->tMax;\r
+\r
+ float32 totalRadius = proxyA->m_radius + proxyB->m_radius;\r
+ float32 target = b2Max(b2_linearSlop, totalRadius - 3.0f * b2_linearSlop);\r
+ float32 tolerance = 0.25f * b2_linearSlop;\r
+ b2Assert(target > tolerance);\r
+\r
+ float32 t1 = 0.0f;\r
+ const int32 k_maxIterations = 20; // TODO_ERIN b2Settings\r
+ int32 iter = 0;\r
+\r
+ // Prepare input for distance query.\r
+ b2SimplexCache cache;\r
+ cache.count = 0;\r
+ b2DistanceInput distanceInput;\r
+ distanceInput.proxyA = input->proxyA;\r
+ distanceInput.proxyB = input->proxyB;\r
+ distanceInput.useRadii = false;\r
+\r
+ // The outer loop progressively attempts to compute new separating axes.\r
+ // This loop terminates when an axis is repeated (no progress is made).\r
+ for(;;)\r
+ {\r
+ b2Transform xfA, xfB;\r
+ sweepA.GetTransform(&xfA, t1);\r
+ sweepB.GetTransform(&xfB, t1);\r
+\r
+ // Get the distance between shapes. We can also use the results\r
+ // to get a separating axis.\r
+ distanceInput.transformA = xfA;\r
+ distanceInput.transformB = xfB;\r
+ b2DistanceOutput distanceOutput;\r
+ b2Distance(&distanceOutput, &cache, &distanceInput);\r
+\r
+ // If the shapes are overlapped, we give up on continuous collision.\r
+ if (distanceOutput.distance <= 0.0f)\r
+ {\r
+ // Failure!\r
+ output->state = b2TOIOutput::e_overlapped;\r
+ output->t = 0.0f;\r
+ break;\r
+ }\r
+\r
+ if (distanceOutput.distance < target + tolerance)\r
+ {\r
+ // Victory!\r
+ output->state = b2TOIOutput::e_touching;\r
+ output->t = t1;\r
+ break;\r
+ }\r
+\r
+ // Initialize the separating axis.\r
+ b2SeparationFunction fcn;\r
+ fcn.Initialize(&cache, proxyA, sweepA, proxyB, sweepB);\r
+#if 0\r
+ // Dump the curve seen by the root finder\r
+ {\r
+ const int32 N = 100;\r
+ float32 dx = 1.0f / N;\r
+ float32 xs[N+1];\r
+ float32 fs[N+1];\r
+\r
+ float32 x = 0.0f;\r
+\r
+ for (int32 i = 0; i <= N; ++i)\r
+ {\r
+ sweepA.GetTransform(&xfA, x);\r
+ sweepB.GetTransform(&xfB, x);\r
+ float32 f = fcn.Evaluate(xfA, xfB) - target;\r
+\r
+ printf("%g %g\n", x, f);\r
+\r
+ xs[i] = x;\r
+ fs[i] = f;\r
+\r
+ x += dx;\r
+ }\r
+ }\r
+#endif\r
+\r
+ // Compute the TOI on the separating axis. We do this by successively\r
+ // resolving the deepest point. This loop is bounded by the number of vertices.\r
+ bool done = false;\r
+ float32 t2 = tMax;\r
+ int32 pushBackIter = 0;\r
+ for (;;)\r
+ {\r
+ // Find the deepest point at t2. Store the witness point indices.\r
+ int32 indexA, indexB;\r
+ float32 s2 = fcn.FindMinSeparation(&indexA, &indexB, t2);\r
+\r
+ // Is the final configuration separated?\r
+ if (s2 > target + tolerance)\r
+ {\r
+ // Victory!\r
+ output->state = b2TOIOutput::e_separated;\r
+ output->t = tMax;\r
+ done = true;\r
+ break;\r
+ }\r
+\r
+ // Has the separation reached tolerance?\r
+ if (s2 > target - tolerance)\r
+ {\r
+ // Advance the sweeps\r
+ t1 = t2;\r
+ break;\r
+ }\r
+\r
+ // Compute the initial separation of the witness points.\r
+ float32 s1 = fcn.Evaluate(indexA, indexB, t1);\r
+\r
+ // Check for initial overlap. This might happen if the root finder\r
+ // runs out of iterations.\r
+ if (s1 < target - tolerance)\r
+ {\r
+ output->state = b2TOIOutput::e_failed;\r
+ output->t = t1;\r
+ done = true;\r
+ break;\r
+ }\r
+\r
+ // Check for touching\r
+ if (s1 <= target + tolerance)\r
+ {\r
+ // Victory! t1 should hold the TOI (could be 0.0).\r
+ output->state = b2TOIOutput::e_touching;\r
+ output->t = t1;\r
+ done = true;\r
+ break;\r
+ }\r
+\r
+ // Compute 1D root of: f(x) - target = 0\r
+ int32 rootIterCount = 0;\r
+ float32 a1 = t1, a2 = t2;\r
+ for (;;)\r
+ {\r
+ // Use a mix of the secant rule and bisection.\r
+ float32 t;\r
+ &n