--- /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 "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
--- /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_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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*
+* 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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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