--- /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