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