Adds box2d contrib controllers.
authordsc <david.schoonover@gmail.com>
Wed, 18 May 2011 01:59:39 +0000 (18:59 -0700)
committerdsc <david.schoonover@gmail.com>
Wed, 18 May 2011 01:59:39 +0000 (18:59 -0700)
12 files changed:
libs/box2d/src/Box2D/Controllers/b2BuoyancyController.cpp [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2BuoyancyController.h [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2ConstantAccelController.cpp [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2ConstantAccelController.h [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2ConstantForceController.cpp [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2ConstantForceController.h [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2Controller.cpp [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2Controller.h [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2GravityController.cpp [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2GravityController.h [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2TensorDampingController.cpp [new file with mode: 0644]
libs/box2d/src/Box2D/Controllers/b2TensorDampingController.h [new file with mode: 0644]

diff --git a/libs/box2d/src/Box2D/Controllers/b2BuoyancyController.cpp b/libs/box2d/src/Box2D/Controllers/b2BuoyancyController.cpp
new file mode 100644 (file)
index 0000000..e405407
--- /dev/null
@@ -0,0 +1,119 @@
+/*\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 "b2BuoyancyController.h"\r
+#include "../b2Fixture.h"\r
+\r
+b2BuoyancyController::b2BuoyancyController(const b2BuoyancyControllerDef* def) : b2Controller(def)\r
+{\r
+       normal = def->normal;\r
+       offset = def->offset;\r
+       density = def->density;\r
+       velocity = def->velocity;\r
+       linearDrag = def->linearDrag;\r
+       angularDrag = def->angularDrag;\r
+       useDensity = def->useDensity;\r
+       useWorldGravity = def->useWorldGravity;\r
+       gravity = def->gravity;\r
+}\r
+\r
+void b2BuoyancyController::Step(const b2TimeStep& step)\r
+{\r
+       B2_NOT_USED(step);\r
+       if(!m_bodyList)\r
+               return;\r
+       if(useWorldGravity)\r
+       {\r
+               gravity = m_world->GetGravity();\r
+       }\r
+       for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody)\r
+       {\r
+               b2Body* body = i->body;\r
+               if(body->IsSleeping())\r
+               {\r
+                       //Buoyancy force is just a function of position,\r
+                       //so unlike most forces, it is safe to ignore sleeping bodes\r
+                       continue;\r
+               }\r
+               b2Vec2 areac(0,0);\r
+               b2Vec2 massc(0,0);\r
+               float32 area = 0;\r
+               float32 mass = 0;\r
+               for(b2Fixture* shape=body->GetFixtureList();shape;shape=shape->GetNext())\r
+               {\r
+                       b2Vec2 sc(0,0);\r
+                       float32 sarea = shape->ComputeSubmergedArea(normal, offset, &sc);\r
+                       area += sarea;\r
+                       areac.x += sarea * sc.x;\r
+                       areac.y += sarea * sc.y;\r
+                       float shapeDensity = 0;\r
+                       if(useDensity)\r
+                       {\r
+                               //TODO: Expose density publicly\r
+                               shapeDensity=shape->GetDensity();\r
+                       }\r
+                       else\r
+                       {\r
+                               shapeDensity = 1;\r
+                       }\r
+                       mass += sarea*shapeDensity;\r
+                       massc.x += sarea * sc.x * shapeDensity;\r
+                       massc.y += sarea * sc.y * shapeDensity;\r
+               }\r
+               areac.x/=area;\r
+               areac.y/=area;\r
+               b2Vec2 localCentroid = b2MulT(body->GetXForm(),areac);\r
+               massc.x/=mass;\r
+               massc.y/=mass;\r
+               if(area<B2_FLT_EPSILON)\r
+                       continue;\r
+               //Buoyancy\r
+               b2Vec2 buoyancyForce = -density*area*gravity;\r
+               body->ApplyForce(buoyancyForce,massc);\r
+               //Linear drag\r
+               b2Vec2 dragForce = body->GetLinearVelocityFromWorldPoint(areac) - velocity;\r
+               dragForce *= -linearDrag*area;\r
+               body->ApplyForce(dragForce,areac);\r
+               //Angular drag\r
+               //TODO: Something that makes more physical sense?\r
+               body->ApplyTorque(-body->GetInertia()/body->GetMass()*area*body->GetAngularVelocity()*angularDrag);\r
+               \r
+       }\r
+}\r
+\r
+void b2BuoyancyController::Draw(b2DebugDraw *debugDraw)\r
+{\r
+       float32 r = 1000;\r
+       b2Vec2 p1 = offset * normal + b2Cross(normal, r);\r
+       b2Vec2 p2 = offset * normal - b2Cross(normal, r);\r
+\r
+       b2Color color(0,0,0.8f);\r
+\r
+       debugDraw->DrawSegment(p1, p2, color);\r
+}\r
+\r
+void b2BuoyancyController::Destroy(b2BlockAllocator* allocator)\r
+{\r
+       allocator->Free(this, sizeof(b2BuoyancyController));\r
+}\r
+\r
+b2BuoyancyController* b2BuoyancyControllerDef::Create(b2BlockAllocator* allocator) const\r
+{\r
+       void* mem = allocator->Allocate(sizeof(b2BuoyancyController));\r
+       return new (mem) b2BuoyancyController(this);\r
+}\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2BuoyancyController.h b/libs/box2d/src/Box2D/Controllers/b2BuoyancyController.h
new file mode 100644 (file)
index 0000000..0392e2d
--- /dev/null
@@ -0,0 +1,102 @@
+/*\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_BUOYANCYCONTROLLER_H\r
+#define B2_BUOYANCYCONTROLLER_H\r
+\r
+#include "b2Controller.h"\r
+\r
+class b2BuoyancyControllerDef;\r
+\r
+/// Calculates buoyancy forces for fluids in the form of a half plane.\r
+class b2BuoyancyController : public b2Controller{\r
+public:\r
+       /// The outer surface normal\r
+       b2Vec2 normal;\r
+       /// The height of the fluid surface along the normal\r
+       float32 offset;\r
+       /// The fluid density\r
+       float32 density;\r
+       /// Fluid velocity, for drag calculations\r
+       b2Vec2 velocity;\r
+       /// Linear drag co-efficient\r
+       float32 linearDrag;\r
+       /// Linear drag co-efficient\r
+       float32 angularDrag;\r
+       /// If false, bodies are assumed to be uniformly dense, otherwise use the shapes densities\r
+       bool useDensity; //False by default to prevent a gotcha\r
+       /// If true, gravity is taken from the world instead of the gravity parameter.\r
+       bool useWorldGravity;\r
+       /// Gravity vector, if the world's gravity is not used\r
+       b2Vec2 gravity;\r
+\r
+       /// @see b2Controller::Step\r
+       void Step(const b2TimeStep& step);\r
+\r
+       /// @see b2Controller::Draw\r
+       void Draw(b2DebugDraw *debugDraw);\r
+\r
+protected:\r
+       void Destroy(b2BlockAllocator* allocator);\r
+\r
+private:\r
+       friend class b2BuoyancyControllerDef;\r
+       b2BuoyancyController(const b2BuoyancyControllerDef* def);\r
+};\r
+\r
+/// This class is used to build buoyancy controllers\r
+class b2BuoyancyControllerDef : public b2ControllerDef\r
+{\r
+public:\r
+       /// The outer surface normal\r
+       b2Vec2 normal;\r
+       /// The height of the fluid surface along the normal\r
+       float32 offset;\r
+       /// The fluid density\r
+       float32 density;\r
+       /// Fluid velocity, for drag calculations\r
+       b2Vec2 velocity;\r
+       /// Linear drag co-efficient\r
+       float32 linearDrag;\r
+       /// Linear drag co-efficient\r
+       float32 angularDrag;\r
+       /// If false, bodies are assumed to be uniformly dense, otherwise use the shapes densities\r
+       bool useDensity; //False by default to prevent a gotcha\r
+       /// If true, gravity is taken from the world instead of the gravity parameter.\r
+       bool useWorldGravity;\r
+       /// Gravity vector, if the world's gravity is not used\r
+       b2Vec2 gravity;\r
+\r
+       b2BuoyancyControllerDef():\r
+               normal(0,1),\r
+               offset(0),\r
+               density(0),\r
+               velocity(0,0),\r
+               linearDrag(0),\r
+               angularDrag(0),\r
+               useDensity(false),\r
+               useWorldGravity(true),\r
+               gravity(0,0)\r
+       {\r
+       }\r
+\r
+private:\r
+       b2BuoyancyController* Create(b2BlockAllocator* allocator) const;\r
+};\r
+\r
+#endif\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2ConstantAccelController.cpp b/libs/box2d/src/Box2D/Controllers/b2ConstantAccelController.cpp
new file mode 100644 (file)
index 0000000..fab7204
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+* Copyright (c) 2006-2007 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 "b2ConstantAccelController.h"\r
+\r
+b2ConstantAccelController::b2ConstantAccelController(const b2ConstantAccelControllerDef* def) : b2Controller(def)\r
+{\r
+       A = def->A;\r
+}\r
+\r
+void b2ConstantAccelController::Step(const b2TimeStep& step)\r
+{\r
+       for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody){\r
+               b2Body* body = i->body;\r
+               if(body->IsSleeping())\r
+                       continue; \r
+               body->SetLinearVelocity(body->GetLinearVelocity()+step.dt*A);\r
+       }\r
+}\r
+\r
+void b2ConstantAccelController::Destroy(b2BlockAllocator* allocator)\r
+{\r
+       allocator->Free(this, sizeof(b2ConstantAccelController));\r
+}\r
+\r
+\r
+b2ConstantAccelController* b2ConstantAccelControllerDef::Create(b2BlockAllocator* allocator) const\r
+{\r
+       void* mem = allocator->Allocate(sizeof(b2ConstantAccelController));\r
+       return new (mem) b2ConstantAccelController(this);\r
+}\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2ConstantAccelController.h b/libs/box2d/src/Box2D/Controllers/b2ConstantAccelController.h
new file mode 100644 (file)
index 0000000..2318eff
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+* Copyright (c) 2006-2007 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_CONSTANTACCELCONTROLLER_H\r
+#define B2_CONSTANTACCELCONTROLLER_H\r
+\r
+#include "b2Controller.h"\r
+\r
+class b2ConstantAccelControllerDef;\r
+\r
+/// Applies a force every frame\r
+class b2ConstantAccelController : public b2Controller{\r
+public:\r
+       /// The force to apply\r
+       b2Vec2 A;\r
+\r
+       /// @see b2Controller::Step\r
+       void Step(const b2TimeStep& step);\r
+\r
+protected:\r
+       void Destroy(b2BlockAllocator* allocator);\r
+\r
+private:\r
+       friend class b2ConstantAccelControllerDef;\r
+       b2ConstantAccelController(const b2ConstantAccelControllerDef* def);\r
+\r
+};\r
+\r
+/// This class is used to build constant acceleration controllers\r
+class b2ConstantAccelControllerDef : public b2ControllerDef\r
+{\r
+public:\r
+       /// The force to apply\r
+       b2Vec2 A;\r
+private:\r
+       b2ConstantAccelController* Create(b2BlockAllocator* allocator) const;\r
+};\r
+\r
+#endif\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2ConstantForceController.cpp b/libs/box2d/src/Box2D/Controllers/b2ConstantForceController.cpp
new file mode 100644 (file)
index 0000000..1abde30
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+* Copyright (c) 2006-2007 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 "b2ConstantForceController.h"\r
+\r
+b2ConstantForceController::b2ConstantForceController(const b2ConstantForceControllerDef* def) : b2Controller(def)\r
+{\r
+       F = def->F;\r
+}\r
+\r
+void b2ConstantForceController::Step(const b2TimeStep& step)\r
+{\r
+       B2_NOT_USED(step);\r
+       for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody){\r
+               b2Body* body = i->body;\r
+               if(body->IsSleeping())\r
+                       continue;\r
+               body->ApplyForce(F,body->GetWorldCenter());\r
+       }\r
+}\r
+\r
+void b2ConstantForceController::Destroy(b2BlockAllocator* allocator)\r
+{\r
+       allocator->Free(this, sizeof(b2ConstantForceController));\r
+}\r
+\r
+\r
+b2ConstantForceController* b2ConstantForceControllerDef::Create(b2BlockAllocator* allocator) const\r
+{\r
+       void* mem = allocator->Allocate(sizeof(b2ConstantForceController));\r
+       return new (mem) b2ConstantForceController(this);\r
+}\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2ConstantForceController.h b/libs/box2d/src/Box2D/Controllers/b2ConstantForceController.h
new file mode 100644 (file)
index 0000000..b21e498
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+* Copyright (c) 2006-2007 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_CONSTANTFORCECONTROLLER_H\r
+#define B2_CONSTANTFORCECONTROLLER_H\r
+\r
+#include "b2Controller.h"\r
+\r
+class b2ConstantForceControllerDef;\r
+\r
+/// Applies a force every frame\r
+class b2ConstantForceController : public b2Controller\r
+{\r
+public:\r
+       /// The force to apply\r
+       b2Vec2 F;\r
+\r
+       /// @see b2Controller::Step\r
+       void Step(const b2TimeStep& step);\r
+\r
+protected:\r
+       void Destroy(b2BlockAllocator* allocator);\r
+\r
+private:\r
+       friend class b2ConstantForceControllerDef;\r
+       b2ConstantForceController(const b2ConstantForceControllerDef* def);\r
+};\r
+\r
+/// This class is used to build constant force controllers\r
+class b2ConstantForceControllerDef : public b2ControllerDef\r
+{\r
+public:\r
+       /// The force to apply\r
+       b2Vec2 F;\r
+private:\r
+       b2ConstantForceController* Create(b2BlockAllocator* allocator) const;\r
+};\r
+\r
+#endif\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2Controller.cpp b/libs/box2d/src/Box2D/Controllers/b2Controller.cpp
new file mode 100644 (file)
index 0000000..87169bd
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+* Copyright (c) 2006-2007 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 "b2Controller.h"\r
+#include "../../Common/b2BlockAllocator.h"\r
+\r
+\r
+b2Controller::~b2Controller()\r
+{\r
+       //Remove attached bodies\r
+       Clear();\r
+}\r
+\r
+void b2Controller::AddBody(b2Body* body)\r
+{\r
+       void* mem = m_world->m_blockAllocator.Allocate(sizeof(b2ControllerEdge));\r
+       b2ControllerEdge* edge = new (mem) b2ControllerEdge;\r
+       \r
+       edge->body = body;\r
+       edge->controller = this;\r
+       \r
+       //Add edge to controller list\r
+       edge->nextBody = m_bodyList;\r
+       edge->prevBody = NULL;\r
+       if(m_bodyList)\r
+               m_bodyList->prevBody = edge;\r
+       m_bodyList = edge;\r
+       ++m_bodyCount;\r
+\r
+       //Add edge to body list\r
+       edge->nextController = body->m_controllerList;\r
+       edge->prevController = NULL;\r
+       if(body->m_controllerList)\r
+               body->m_controllerList->prevController = edge;\r
+       body->m_controllerList = edge;\r
+}\r
+\r
+void b2Controller::RemoveBody(b2Body* body)\r
+{\r
+       //Assert that the controller is not empty\r
+       b2Assert(m_bodyCount>0);\r
+\r
+       //Find the corresponding edge\r
+       b2ControllerEdge* edge = m_bodyList;\r
+       while(edge && edge->body!=body)\r
+               edge = edge->nextBody;\r
+\r
+       //Assert that we are removing a body that is currently attached to the controller\r
+       b2Assert(edge!=NULL);\r
+\r
+       //Remove edge from controller list\r
+       if(edge->prevBody)\r
+               edge->prevBody->nextBody = edge->nextBody;\r
+       if(edge->nextBody)\r
+               edge->nextBody->prevBody = edge->prevBody;\r
+       if(edge == m_bodyList)\r
+               m_bodyList = edge->nextBody;\r
+       --m_bodyCount;\r
+\r
+       //Remove edge from body list\r
+       if(edge->prevController)\r
+               edge->prevController->nextController = edge->nextController;\r
+       if(edge->nextController)\r
+               edge->nextController->prevController = edge->prevController;\r
+       if(edge == body->m_controllerList)\r
+               body->m_controllerList = edge->nextController;\r
+\r
+       //Free the edge\r
+       m_world->m_blockAllocator.Free(edge, sizeof(b2ControllerEdge));\r
+}\r
+\r
+void b2Controller::Clear(){\r
+\r
+       while(m_bodyList)\r
+       {\r
+               b2ControllerEdge* edge = m_bodyList;\r
+\r
+               //Remove edge from controller list\r
+               m_bodyList = edge->nextBody;\r
+\r
+               //Remove edge from body list\r
+               if(edge->prevController)\r
+                       edge->prevController->nextController = edge->nextController;\r
+               if(edge->nextController)\r
+                       edge->nextController->prevController = edge->prevController;\r
+               if(edge == edge->body->m_controllerList)\r
+                       edge->body->m_controllerList = edge->nextController;\r
+\r
+               //Free the edge\r
+               m_world->m_blockAllocator.Free(edge, sizeof(b2ControllerEdge));\r
+       }\r
+\r
+       m_bodyCount = 0;\r
+}\r
+\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2Controller.h b/libs/box2d/src/Box2D/Controllers/b2Controller.h
new file mode 100644 (file)
index 0000000..91b36a0
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would be
+* appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+* misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef B2_CONTROLLER_H
+#define B2_CONTROLLER_H
+
+#include "../../Dynamics/b2World.h"
+#include "../../Dynamics/b2Body.h"
+
+class b2Body;
+class b2World;
+
+class b2Controller;
+
+/// A controller edge is used to connect bodies and controllers together
+/// in a bipartite graph.
+struct b2ControllerEdge
+{
+       b2Controller* controller;               ///< provides quick access to other end of this edge.
+       b2Body* body;                                   ///< the body
+       b2ControllerEdge* prevBody;             ///< the previous controller edge in the controllers's joint list
+       b2ControllerEdge* nextBody;             ///< the next controller edge in the controllers's joint list
+       b2ControllerEdge* prevController;               ///< the previous controller edge in the body's joint list
+       b2ControllerEdge* nextController;               ///< the next controller edge in the body's joint list
+};
+
+class b2ControllerDef;
+
+/// Base class for controllers. Controllers are a convience for encapsulating common
+/// per-step functionality.
+class b2Controller
+{
+public:
+       virtual ~b2Controller();
+
+       /// Controllers override this to implement per-step functionality.
+       virtual void Step(const b2TimeStep& step) = 0;
+
+       /// Controllers override this to provide debug drawing.
+       virtual void Draw(b2DebugDraw *debugDraw) {B2_NOT_USED(debugDraw);};
+
+       /// Adds a body to the controller list.
+       void AddBody(b2Body* body);
+
+       /// Removes a body from the controller list.
+       void RemoveBody(b2Body* body);
+
+       /// Removes all bodies from the controller list.
+       void Clear();
+
+       /// Get the next controller in the world's body list.
+       b2Controller* GetNext();
+       const b2Controller* GetNext() const;
+
+       /// Get the parent world of this body.
+       b2World* GetWorld();
+       const b2World* GetWorld() const;
+
+       /// Get the attached body list
+       b2ControllerEdge* GetBodyList();
+       const b2ControllerEdge* GetBodyList() const;
+
+
+protected:
+       friend class b2World;
+
+       b2World* m_world;
+
+       b2ControllerEdge* m_bodyList;
+       int32 m_bodyCount;
+
+       b2Controller(const b2ControllerDef* def):
+               m_world(NULL),
+               m_bodyList(NULL),
+               m_bodyCount(0),
+               m_prev(NULL),
+               m_next(NULL)
+               
+               {
+                       B2_NOT_USED(def);
+               }
+       virtual void Destroy(b2BlockAllocator* allocator) = 0;
+
+private:
+       b2Controller* m_prev;
+       b2Controller* m_next;
+
+       static void Destroy(b2Controller* controller, b2BlockAllocator* allocator);
+};
+
+class b2ControllerDef
+{
+public:
+       virtual ~b2ControllerDef() {};
+       
+private:
+       friend class b2World;
+       virtual b2Controller* Create(b2BlockAllocator* allocator) const = 0;
+};
+
+inline b2Controller* b2Controller::GetNext()
+{
+       return m_next;
+}
+
+inline const b2Controller* b2Controller::GetNext() const
+{
+       return m_next;
+}
+
+inline b2World* b2Controller::GetWorld()
+{
+       return m_world;
+}
+
+inline const b2World* b2Controller::GetWorld() const
+{
+       return m_world;
+}
+
+inline b2ControllerEdge* b2Controller::GetBodyList()
+{
+       return m_bodyList;
+}
+
+inline const b2ControllerEdge* b2Controller::GetBodyList() const
+{
+       return m_bodyList;
+}
+
+inline void b2Controller::Destroy(b2Controller* controller, b2BlockAllocator* allocator)
+{
+       controller->Destroy(allocator);
+}
+
+#endif
diff --git a/libs/box2d/src/Box2D/Controllers/b2GravityController.cpp b/libs/box2d/src/Box2D/Controllers/b2GravityController.cpp
new file mode 100644 (file)
index 0000000..98ba40b
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+* Copyright (c) 2006-2007 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 "b2GravityController.h"\r
+\r
+b2GravityController::b2GravityController(const b2GravityControllerDef* def) : b2Controller(def)\r
+{\r
+       G = def->G;\r
+       invSqr = def->invSqr;\r
+}\r
+\r
+void b2GravityController::Step(const b2TimeStep& step)\r
+{\r
+       B2_NOT_USED(step);\r
+       if(invSqr){\r
+               for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody){\r
+                       b2Body* body1 = i->body;\r
+                       for(b2ControllerEdge *j=m_bodyList;j!=i;j=j->nextBody){\r
+                               b2Body* body2 = j->body;\r
+                               b2Vec2 d = body2->GetWorldCenter() - body1->GetWorldCenter();\r
+                               float32 r2 = d.LengthSquared();\r
+                               if(r2 < B2_FLT_EPSILON)\r
+                                       continue;\r
+                               b2Vec2 f = G / r2 / sqrt(r2) * body1->GetMass() * body2->GetMass() * d;\r
+                               body1->ApplyForce(f      , body1->GetWorldCenter());\r
+                               body2->ApplyForce(-1.0f*f, body2->GetWorldCenter());\r
+                       }\r
+               }\r
+       }else{\r
+               for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody){\r
+                       b2Body* body1 = i->body;\r
+                       for(b2ControllerEdge *j=m_bodyList;j!=i;j=j->nextBody){\r
+                               b2Body* body2 = j->body;\r
+                               b2Vec2 d = body2->GetWorldCenter() - body1->GetWorldCenter();\r
+                               float32 r2 = d.LengthSquared();\r
+                               if(r2 < B2_FLT_EPSILON)\r
+                                       continue;\r
+                               b2Vec2 f = G / r2 * body1->GetMass() * body2->GetMass() * d;\r
+                               body1->ApplyForce(f      , body1->GetWorldCenter());\r
+                               body2->ApplyForce(-1.0f*f, body2->GetWorldCenter());\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+void b2GravityController::Destroy(b2BlockAllocator* allocator)\r
+{\r
+       allocator->Free(this, sizeof(b2GravityController));\r
+}\r
+\r
+b2GravityController* b2GravityControllerDef::Create(b2BlockAllocator* allocator) const\r
+{\r
+       void* mem = allocator->Allocate(sizeof(b2GravityController));\r
+       return new (mem) b2GravityController(this);\r
+}\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2GravityController.h b/libs/box2d/src/Box2D/Controllers/b2GravityController.h
new file mode 100644 (file)
index 0000000..2b59f98
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+* Copyright (c) 2006-2007 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_GRAVITYCONTROLLER_H\r
+#define B2_GRAVITYCONTROLLER_H\r
+\r
+#include "b2Controller.h"\r
+\r
+class b2GravityControllerDef;\r
+\r
+/// Applies simplified gravity between every pair of bodies\r
+class b2GravityController : public b2Controller{\r
+public:\r
+       /// Specifies the strength of the gravitiation force\r
+       float32 G;\r
+       /// If true, gravity is proportional to r^-2, otherwise r^-1\r
+       bool invSqr;\r
+\r
+       /// @see b2Controller::Step\r
+       void Step(const b2TimeStep& step);\r
+\r
+protected:\r
+       void Destroy(b2BlockAllocator* allocator);\r
+\r
+private:\r
+       friend class b2GravityControllerDef;\r
+       b2GravityController(const b2GravityControllerDef* def);\r
+\r
+\r
+};\r
+\r
+/// This class is used to build gravity controllers\r
+class b2GravityControllerDef : public b2ControllerDef\r
+{\r
+public:\r
+       /// Specifies the strength of the gravitiation force\r
+       float32 G;\r
+       /// If true, gravity is proportional to r^-2, otherwise r^-1\r
+       bool invSqr;\r
+private:\r
+       b2GravityController* Create(b2BlockAllocator* allocator) const;\r
+};\r
+\r
+#endif\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2TensorDampingController.cpp b/libs/box2d/src/Box2D/Controllers/b2TensorDampingController.cpp
new file mode 100644 (file)
index 0000000..25a16b9
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+* Copyright (c) 2006-2007 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 "b2TensorDampingController.h"\r
+\r
+b2TensorDampingController::b2TensorDampingController(const b2TensorDampingControllerDef* def) : b2Controller(def)\r
+{\r
+       T = def->T;\r
+       maxTimestep = def->maxTimestep;\r
+}\r
+\r
+void b2TensorDampingController::Step(const b2TimeStep& step)\r
+{\r
+       float32 timestep = step.dt;\r
+       if(timestep<=B2_FLT_EPSILON)\r
+               return;\r
+       if(timestep>maxTimestep && maxTimestep>0)\r
+               timestep = maxTimestep;\r
+       for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody){\r
+               b2Body* body = i->body;\r
+               if(body->IsSleeping())\r
+                       continue;\r
+               b2Vec2 damping = body->GetWorldVector(\r
+                                                       b2Mul(T,\r
+                                                               body->GetLocalVector(\r
+                                                                       body->GetLinearVelocity()\r
+                                                               )\r
+                                                       )\r
+                                               );\r
+               body->SetLinearVelocity(body->GetLinearVelocity() + timestep * damping);\r
+       }\r
+}\r
+\r
+void b2TensorDampingControllerDef::SetAxisAligned(float32 xDamping, float32 yDamping)\r
+{\r
+       T.col1.x = -xDamping;\r
+       T.col1.y = 0;\r
+       T.col2.x = 0;\r
+       T.col2.y = -yDamping;\r
+       if(xDamping>0 || yDamping>0){\r
+               maxTimestep = 1/b2Max(xDamping,yDamping);\r
+       }else{\r
+               maxTimestep = 0;\r
+       }\r
+}\r
+\r
+void b2TensorDampingController::Destroy(b2BlockAllocator* allocator)\r
+{\r
+       allocator->Free(this, sizeof(b2TensorDampingController));\r
+}\r
+\r
+\r
+b2TensorDampingController* b2TensorDampingControllerDef::Create(b2BlockAllocator* allocator) const\r
+{\r
+       void* mem = allocator->Allocate(sizeof(b2TensorDampingController));\r
+       return new (mem) b2TensorDampingController(this);\r
+}\r
diff --git a/libs/box2d/src/Box2D/Controllers/b2TensorDampingController.h b/libs/box2d/src/Box2D/Controllers/b2TensorDampingController.h
new file mode 100644 (file)
index 0000000..8ed0c99
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+* Copyright (c) 2006-2007 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_TENSORDAMPINGCONTROLLER_H\r
+#define B2_TENSORDAMPINGCONTROLLER_H\r
+\r
+#include "b2Controller.h"\r
+\r
+class b2TensorDampingControllerDef;\r
+\r
+/// Applies top down linear damping to the controlled bodies\r
+/// The damping is calculated by multiplying velocity by a matrix in local co-ordinates.\r
+class b2TensorDampingController : public b2Controller{\r
+public:\r
+       /// Tensor to use in damping model\r
+       b2Mat22 T;\r
+       /*Some examples (matrixes in format (row1; row2) )\r
+       (-a 0;0 -a)             Standard isotropic damping with strength a\r
+       (0 a;-a 0)              Electron in fixed field - a force at right angles to velocity with proportional magnitude\r
+       (-a 0;0 -b)             Differing x and y damping. Useful e.g. for top-down wheels.\r
+       */\r
+       //By the way, tensor in this case just means matrix, don't let the terminology get you down.\r
+\r
+       /// Set this to a positive number to clamp the maximum amount of damping done.\r
+       float32 maxTimestep;\r
+       // Typically one wants maxTimestep to be 1/(max eigenvalue of T), so that damping will never cause something to reverse direction\r
+\r
+       /// @see b2Controller::Step\r
+       void Step(const b2TimeStep& step);\r
+\r
+protected:\r
+       void Destroy(b2BlockAllocator* allocator);\r
+\r
+private:\r
+       friend class b2TensorDampingControllerDef;\r
+       b2TensorDampingController(const b2TensorDampingControllerDef* def);\r
+\r
+};\r
+\r
+/// This class is used to build tensor damping controllers\r
+class b2TensorDampingControllerDef : public b2ControllerDef\r
+{\r
+public:\r
+       /// Tensor to use in damping model\r
+       b2Mat22 T;\r
+       /// Set this to a positive number to clamp the maximum amount of damping done.\r
+       float32 maxTimestep;\r
+       /// Sets damping independantly along the x and y axes\r
+       void SetAxisAligned(float32 xDamping,float32 yDamping);\r
+private:\r
+       b2TensorDampingController* Create(b2BlockAllocator* allocator) const;\r
+};\r
+\r
+#endif\r