OvermindDL1
18-04-2006 17:12:55
The code I posted is a bit old actually, but the new one is identical except the hoverHeight, instead of it always being a specific point, a ray is traced down from the craft, where it intersects it gets that height and the hoverHeight is added to it so it always hovers above that point. The only issues I have is when the thing starts getting too fast (this is a problem in near any physics engine, and I could up the quality on the newton engine, continuous collision, to prevent it, but it is too costly to be worth it), it can clip through the ground... a bad thing obviously. As a workaround, I just have it see the raytrace, if the object is below the trace if it hit world geometry(below ground in other words), it is setPosition'ed just barely above the ground with a nice force applied (if they managed to clip below ground, they were going quite fast, so it is like they bounced hard off the ground).
Robomaniac
20-04-2006 19:38:25
I tried to implement this yesterday, and I'm having some trouble getting it to work... I'm going to start by working with a simple flat plane to test the behavior then enhance it. As of now, the ship doesn't respond to the bouyancy at all, even though it calls the bouyancy callback, nothing happens. Do i have to set up any bouyancy planes or anything in advance?
Here's my code
void Hovership::forceAndTorqueCallback(OgreNewt::Body* me)
{
//apply a simple gravity force.
float mass;
Ogre::Vector3 inertia;
me->getMassMatrix(mass, inertia);
Ogre::Vector3 force(0,-9.8,0);
force *= mass;
me->addForce( force );
me->addBouyancyForce(1.0, 0.9, 0.9, Ogre::Vector3(0, -9.8, 0),
fastdelegate::MakeDelegate(this, &Hovership::bouyancyCallback));
}
bool Hovership::bouyancyCallback(int colID, OgreNewt::Body* me, const Ogre::Quaternion& o, const Ogre::Vector3& pos, Ogre::Plane& plane)
{
plane = Ogre::Plane(Ogre::Vector3(0, 1, 0), Ogre::Vector3(0, 0, 0));
return true;
}
OvermindDL1
21-04-2006 01:49:50
I had the same problem, never did figure it out, but I just started playing with all the values, density, mass, everything, and it finally started working, then I just fine-tuned to get it to how I have it now. The svn might be up right now, you can take a look at it, you can change the values in the console in real-time and all (generally have to create a new object to see most changes).
In the odf in the root directory, change the model name to your model and set the mass and such accordingly, then you can play with it till you get good numbers, then plug them into yours.
For note as well, you may want to get an svn copy from like two revisions ago as it now has networking in it, and if it doesn't find a server (if it is the client build, think it is), it closes in thirty seconds after start. Read the svn comments to find out exactly when I added the networking, and get the one right before that.
OvermindDL1
26-04-2006 00:41:14
Here are the pieces of source that would be useful, the rest is tied into other things so you wouldn't be able to compile it anyway. This is a direct copy/paste of the test code, and note the "test" when I said that. I have since deleted this a while ago, and all other test code, so I can finish working on the Engine without worry of test junk everywhere (Yes the engine is *much* nicer looking then this test code). Class WhiteSphere is the hovercraft, as you can guess it started out as a white physics ball...
PhysTestWS.odf
gravity=0 -98 0
fluidDensity=0.5
fluidLinearViscosity=0.0001
fluidAngularViscosity=0.000
angularDamping=10 10 100
linearDamping=5.0
mass=75.0
size=5 3 5
inertia=4.0 4.0 5.0
centerOfMass=0.0 -0.1 0.0
hoverHeight=-190.0
moveAmtPerTick=10000.0
moveFastMultiplier=10.0
moveVeryFastMultiplier=20.0
moveSlowMultiplier=0.25
rotateMultiplier=600.0
turnPos=0.0 0.0 2.0
modelName=fvtank.mesh
moveSpeedMultiplier=0.75 0.1 1.0
Spawnable.h
#pragma once
//#include <Ogre.h>
//#include <OgreNewt.h>
#include "ODL1_PCH.h"
class Player;
class Spawnable : public ODL1::Object
{
protected:
Ogre::SceneManager *m_SceneMgr;
Ogre::SceneNode *m_ParentNode;
Ogre::Vector3 m_Position; // are these necessary? not putting them in Object for right now...
Ogre::Vector3 m_Direction; // are these necessary? not putting them in Object for right now...
Ogre::Node::TransformSpace m_RelativeTo; // are these necessary? not putting them in Object for right now...
Ogre::Vector3 m_LocalDirectionVector; // are these necessary? not putting them in Object for right now...
OgreNewt::World *m_PhysWorld;
OgreNewt::Body *m_PhysBody;
Ogre::Entity *m_Entity;
Ogre::SceneNode *m_SceneNode;
// Camera vars
Ogre::Vector3 m_CamRelativePosition;
Ogre::Quaternion m_CamOrientation;
public:
Spawnable(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *parentNode, OgreNewt::World *physWorld, const Ogre::Vector3 &position = Ogre::Vector3::ZERO, const Ogre::Vector3 &direction = Ogre::Vector3::ZERO, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TransformSpace::TS_LOCAL, const Ogre::Vector3 &localDirectionVector = Ogre::Vector3::NEGATIVE_UNIT_Z);
virtual ~Spawnable(void);
virtual void Initialize(void);
virtual Ogre::String getUniqueName(Ogre::String &name);
virtual Ogre::Entity *createVisibleEntity(void) = 0;
virtual OgreNewt::Body *createPhysBody(void) = 0;
virtual void _placementCallback(OgreNewt::Body* me, const Ogre::Quaternion& orient, const Ogre::Vector3& pos);
virtual void forceCallback(OgreNewt::Body* me);
inline OgreNewt::Body *getPhysicsBody(void) { return m_PhysBody; }
inline Ogre::Entity *getVisibleEntity(void) { return m_Entity; }
inline Ogre::SceneNode *getSceneNode(void) { return m_SceneNode; }
inline const Ogre::Vector3 getCamRelativePosition(void) { return m_CamRelativePosition; }
inline const Ogre::Quaternion getCamOrientation(void) { return m_CamOrientation; }
// PlaceHolder: To replace with my class system
virtual const long getType()
{
return 0;
}
// Events
virtual void POVAttaching(Player *pc) {}
virtual void POVRemoving(Player *pc) {}
virtual void PossessedBy(Player *pc) {}
virtual void UnPossessed(Player *pc) {}
virtual void ExitedPhysicsWorld(void);
virtual void Destroyed(void);
// Will return true if it is or will be destroyed, false if it is indestructible
virtual bool Destroy(void);
};
Spawnable.cpp
#include ".\spawnable.h"
using namespace Ogre;
Spawnable::Spawnable(SceneManager *sceneMgr, SceneNode *parentNode, OgreNewt::World *physWorld, const Vector3 &position/* = Vector3::ZERO*/, const Vector3 &direction/* = Vector3::ZERO*/, Node::TransformSpace relativeTo/* = TS_LOCAL*/, const Vector3 &localDirectionVector/* = Vector3::NEGATIVE_UNIT_Z*/) :
m_SceneMgr(sceneMgr),
m_ParentNode(parentNode),
m_PhysWorld(physWorld),
m_Position(position),
m_Direction(direction),
m_RelativeTo(relativeTo),
m_LocalDirectionVector(localDirectionVector),
m_PhysBody(0),
m_Entity(0),
m_SceneNode(0),
m_CamRelativePosition(0.0f, 0.0f, 0.0f),
m_CamOrientation(0.0f, 0.0f, 1.0f, 0.0f)
{
}
Spawnable::~Spawnable(void)
{
if(m_Entity)
{
m_SceneMgr->destroyEntity(m_Entity);
m_Entity=0;
}
if(m_SceneNode)
{
m_SceneMgr->destroySceneNode(m_SceneNode->getName());
m_SceneNode=0;
}
if(m_PhysBody)
{
delete m_PhysBody;
m_PhysBody=0;
}
}
String Spawnable::getUniqueName(Ogre::String &name)
{
static unsigned long id = 0;
return name+StringConverter::toString(id++);
}
void Spawnable::Initialize(void)
{
if(m_Entity) m_SceneMgr->destroyEntity(m_Entity);
if(!m_SceneNode)
{
if(m_ParentNode)
{
m_SceneNode = m_ParentNode->createChildSceneNode(getUniqueName(String("Spawnable")));
}
else
{
m_SceneNode = m_SceneMgr->getRootSceneNode()->createChildSceneNode(getUniqueName(String("Spawnable")));
}
}
m_Entity = createVisibleEntity();
m_SceneNode->attachObject(m_Entity);
if(m_PhysBody) delete m_PhysBody;
m_PhysBody = createPhysBody();
m_PhysBody->attachToNode(m_SceneNode);
m_PhysBody->setUserData(this);
// m_PhysBody->setCustomTransformCallback(fastdelegate::MakeDelegate(this, &Spawnable::_placementCallback));
m_PhysBody->setPositionOrientation(m_Position, Quaternion(Radian(0.0f),m_Direction));
m_PhysBody->setCustomForceAndTorqueCallback(fastdelegate::MakeDelegate(this, &Spawnable::forceCallback));
m_PhysBody->unFreeze();
}
void Spawnable::forceCallback( OgreNewt::Body* me )
{
//apply a simple gravity force.
Ogre::Real mass;
Ogre::Vector3 inertia;
me->getMassMatrix(mass, inertia);
Ogre::Vector3 force(0,-50.0,0);
force *= mass;
me->addForce( force );
}
void Spawnable::_placementCallback(OgreNewt::Body* me, const Quaternion& orient, const Vector3& pos)
{
// useful if I have multiple world sections, useless right now though...
}
void Spawnable::ExitedPhysicsWorld(void)
{
}
void Spawnable::Destroyed(void)
{
}
bool Spawnable::Destroy(void)
{
return false;
}
WhiteSphere.h
#pragma once
#include "spawnable.h"
#include "IInteraction.h"
class WhiteSphere :
public Spawnable,
public IInteraction
{
protected:
bool m_MoveForward;
bool m_MoveBackward;
bool m_MoveLeft;
bool m_MoveRight;
bool m_MoveUp;
bool m_MoveDown;
bool m_MoveFast;
bool m_MoveVeryFast;
bool m_MoveSlow;
Ogre::Real m_RotateLeftRight;
Ogre::Real m_RotateUpDown;
Ogre::Real m_RotateClockwiseAndCounter;
public:
// test stuff begin
static bool g_GlobalsSet;
static Ogre::Vector3 gravity;
static Ogre::Real fluidDensity;
static Ogre::Real fluidLinearViscosity;
static Ogre::Real fluidAngularViscosity;
static Ogre::Vector3 angularDamping;
static Ogre::Real linearDamping;
static Ogre::Real mass;
static Ogre::Vector3 size;
static Ogre::Vector3 inertia;
static bool inertiaSet;
static Ogre::Vector3 centerOfMass;
static bool centerOfMassSet;
static Ogre::Real hoverHeight;
static Ogre::Real moveAmtPerTick;
static Ogre::Real moveFastMultiplier;
static Ogre::Real moveVeryFastMultiplier;
static Ogre::Real moveSlowMultiplier;
static Ogre::Real rotateMultiplier;
static Ogre::Vector3 turnPos;
static Ogre::Vector3 moveSpeedMultiplier;
static Ogre::String modelName;
inline static void recalcInertia()
{
inertia = OgreNewt::MomentOfInertia::CalcEllipsoidSolid( mass, size );
}
// test stuff end
virtual const long getType()
{
return 1;
}
public:
WhiteSphere(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *parentNode, OgreNewt::World *physWorld, const Ogre::Vector3 &position = Ogre::Vector3::ZERO, const Ogre::Vector3 &direction = Ogre::Vector3::ZERO, Ogre::Node::TransformSpace relativeTo = Ogre::Node::TransformSpace::TS_LOCAL, const Ogre::Vector3 &localDirectionVector = Ogre::Vector3::NEGATIVE_UNIT_Z);
~WhiteSphere(void);
virtual Ogre::Entity *createVisibleEntity(void);
virtual OgreNewt::Collision *createPhysCollision(void);
virtual OgreNewt::Body *createPhysBody(void);
virtual void PossessedBy(Player *pc);
virtual void UnPossessed(Player *pc);
virtual void preRender(const Ogre::FrameEvent& evt);
virtual bool mouseMoved(Ogre::MouseEvent *e);
virtual bool keyClicked(Ogre::KeyEvent* e);
virtual bool keyPressed(Ogre::KeyEvent* e);
virtual bool keyReleased(Ogre::KeyEvent* e);
virtual void forceCallback(OgreNewt::Body* me);
virtual bool buoyancyCallback(int colID, OgreNewt::Body* me, const Ogre::Quaternion& orient, const Ogre::Vector3& pos, Ogre::Plane& plane);
};
WhiteSphere.cpp
#include "whitesphere.h"
#include "Hoverer.h"
#include "ConVar.h"
using namespace Ogre;
// test stuff begin
bool WhiteSphere::g_GlobalsSet(false);
Ogre::Vector3 WhiteSphere::gravity(0,-245.0,0);
Ogre::Real WhiteSphere::fluidDensity(0.7f);
Ogre::Real WhiteSphere::fluidLinearViscosity(0.9f);
Ogre::Real WhiteSphere::fluidAngularViscosity(0.3f);
Ogre::Vector3 WhiteSphere::angularDamping(50.0f, 50.0f, 500.0f);
Ogre::Real WhiteSphere::linearDamping(0.9f);
Ogre::Real WhiteSphere::mass(12475.0f);
Ogre::Vector3 WhiteSphere::size(75.0f, 35.0f, 75.0f);
Ogre::Vector3 WhiteSphere::inertia(1708075.0, 28068750.0f, 17090750.0f);
bool WhiteSphere::inertiaSet = false;
Ogre::Vector3 WhiteSphere::centerOfMass(0.0f, 0.0f, 0.0f);
bool WhiteSphere::centerOfMassSet = false;
Ogre::Real WhiteSphere::hoverHeight(25.0f);
Ogre::Real WhiteSphere::moveAmtPerTick = 1000000.0f;
Ogre::Real WhiteSphere::moveFastMultiplier = 10.0f;
Ogre::Real WhiteSphere::moveVeryFastMultiplier = 100.0f;
Ogre::Real WhiteSphere::moveSlowMultiplier = 0.25f;
Ogre::Real WhiteSphere::rotateMultiplier = 2500000.0f;
Ogre::Vector3 WhiteSphere::turnPos(0.0f, 0.0f, 10.0f);
Ogre::Vector3 WhiteSphere::moveSpeedMultiplier(1.0f, 1.0f, 1.0f);
Ogre::String WhiteSphere::modelName("razor.mesh");
// test stuff end
static ConVar conVar_gravity("gravity", WhiteSphere::gravity, "This is the gravity");
static ConVar conVar_fluidDensity("fluidDensity", WhiteSphere::fluidDensity, "This is how quickly it is pushed up to the hoverheight");
static ConVar conVar_fluidLinearViscosity("fluidLinearViscosity", WhiteSphere::fluidLinearViscosity, "This is how much damping there is for moving around under the hoverheight");
static ConVar conVar_fluidAngularViscosity("fluidAngularViscosity", WhiteSphere::fluidAngularViscosity, "This is how much damping on rotating there is under the hoverheight");
static ConVar conVar_angularDamping("angularDamping", WhiteSphere::angularDamping, "This is the normal damping for rotatings");
static ConVar conVar_linearDamping("linearDamping", WhiteSphere::linearDamping);
static ConVar conVar_mass("mass", WhiteSphere::mass);
static ConVar conVar_size("size", WhiteSphere::size);
static ConVar conVar_inertia("inertia", WhiteSphere::inertia);
static ConVar conVar_centerOfMass("centerOfMass", WhiteSphere::centerOfMass);
static ConVar conVar_hoverHeight("hoverHeight", WhiteSphere::hoverHeight);
static ConVar conVar_moveAmtPerTick("moveAmtPerTick", WhiteSphere::moveAmtPerTick);
static ConVar conVar_moveFastMultiplier("moveFastMultiplier", WhiteSphere::moveFastMultiplier);
static ConVar conVar_moveVeryFastMultiplier("moveVeryFastMultiplier", WhiteSphere::moveVeryFastMultiplier);
static ConVar conVar_moveSlowMultiplier("moveSlowMultiplier", WhiteSphere::moveSlowMultiplier);
static ConVar conVar_rotateMultiplier("rotateMultiplier", WhiteSphere::rotateMultiplier);
static ConVar conVar_turnPos("turnPos", WhiteSphere::turnPos);
static ConVar conVar_moveSpeedMultiplier("moveSpeedMultiplier", WhiteSphere::moveSpeedMultiplier);
static ConVar conVar_modelName("modelName", WhiteSphere::modelName);
WhiteSphere::WhiteSphere(SceneManager *sceneMgr, SceneNode *parentNode, OgreNewt::World *physWorld, const Vector3 &position/* = Vector3::ZERO*/, const Vector3 &direction/* = Vector3::ZERO*/, Node::TransformSpace relativeTo/* = TS_LOCAL*/, const Vector3 &localDirectionVector/* = Vector3::NEGATIVE_UNIT_Z*/) :
Spawnable(sceneMgr, parentNode, physWorld, position, direction, relativeTo, localDirectionVector),
m_MoveForward(false),
m_MoveBackward(false),
m_MoveLeft(false),
m_MoveRight(false),
m_MoveUp(false),
m_MoveDown(false),
m_MoveFast(false),
m_MoveVeryFast(false),
m_MoveSlow(false),
m_RotateLeftRight(0.0f),
m_RotateUpDown(0.0f),
m_RotateClockwiseAndCounter(0.0f)
{
// test pre-loading hoverer
//*ODL1::objectPtr p =*/ Hoverer::getClassStatic()/*.Spawn()*/;
// done test
bActive = true;
bMouseKeyEvents = true;
bRequiresTicks = true;
if(!g_GlobalsSet)
{
ConfigFile cf;
cf.loadDirect(String("PhysTestWS.odf"));
// Go through all sections & settings in the file
ConfigFile::SectionIterator seci = cf.getSectionIterator();
String secName, typeName, archName;
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();
ConfigFile::SettingsMultiMap *settings = seci.getNext();
ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
archName = i->second;
if(!typeName.compare("gravity"))
{
gravity = StringConverter::parseVector3(archName);
}
else if(!typeName.compare("fluidDensity"))
{
fluidDensity = StringConverter::parseReal(archName);
}
else if(!typeName.compare("fluidLinearViscosity"))
{
fluidLinearViscosity = StringConverter::parseReal(archName);
}
else if(!typeName.compare("fluidAngularViscosity"))
{
fluidAngularViscosity = StringConverter::parseReal(archName);
}
else if(!typeName.compare("angularDamping"))
{
angularDamping = StringConverter::parseVector3(archName);
}
else if(!typeName.compare("linearDamping"))
{
linearDamping = StringConverter::parseReal(archName);
}
else if(!typeName.compare("mass"))
{
mass = StringConverter::parseReal(archName);
}
else if(!typeName.compare("size"))
{
size = StringConverter::parseVector3(archName);
}
else if(!typeName.compare("inertia"))
{
inertia = StringConverter::parseVector3(archName);
inertiaSet = true;
}
else if(!typeName.compare("centerOfMass"))
{
centerOfMass = StringConverter::parseVector3(archName);
centerOfMassSet = true;
}
else if(!typeName.compare("hoverHeight"))
{
hoverHeight = StringConverter::parseReal(archName);
}
else if(!typeName.compare("moveAmtPerTick"))
{
moveAmtPerTick = StringConverter::parseReal(archName);
}
else if(!typeName.compare("moveFastMultiplier"))
{
moveFastMultiplier = StringConverter::parseReal(archName);
}
else if(!typeName.compare("moveVeryFastMultiplier"))
{
moveVeryFastMultiplier = StringConverter::parseReal(archName);
}
else if(!typeName.compare("moveSlowMultiplier"))
{
moveSlowMultiplier = StringConverter::parseReal(archName);
}
else if(!typeName.compare("rotateMultiplier"))
{
rotateMultiplier = StringConverter::parseReal(archName);
}
else if(!typeName.compare("turnPos"))
{
turnPos = StringConverter::parseVector3(archName);
}
else if(!typeName.compare("modelName"))
{
modelName = archName;
}
else if(!typeName.compare("moveSpeedMultiplier"))
{
moveSpeedMultiplier = StringConverter::parseVector3(archName);
}
}
}
g_GlobalsSet = true;
if(inertiaSet==false)
{
inertia = OgreNewt::MomentOfInertia::CalcEllipsoidSolid( mass, size );
inertiaSet = true;
}
if(centerOfMassSet==false)
{
centerOfMass = Vector3(0.0f, -5.0f, 0.0f);
centerOfMassSet = true;
}
}
}
WhiteSphere::~WhiteSphere(void)
{
}
Ogre::Entity *WhiteSphere::createVisibleEntity(void)
{
Ogre::Entity *toReturn = m_SceneMgr->createEntity(getUniqueName(String("WhiteSphere")), modelName);
return toReturn;
}
OgreNewt::Collision *WhiteSphere::createPhysCollision(void)
{
return 0;
}
OgreNewt::Body *WhiteSphere::createPhysBody(void)
{
OgreNewt::CollisionPrimitives::Ellipsoid col(m_PhysWorld, size);
OgreNewt::Body *body = new OgreNewt::Body( m_PhysWorld, &col );
// Vector3 inertia = OgreNewt::MomentOfInertia::CalcEllipsoidSolid( size.length(), size );
body->setMassMatrix( mass, inertia );
// body->setMassMatrix( size.length(), inertia );
body->setCenterOfMass(centerOfMass);
// body->setCenterOfMass(Vector3(0.0f, -5.0f, 0.0f));
// body->setCustomForceAndTorqueCallback(fastdelegate::MakeDelegate(this, &WhiteSphere::forceCallback));
body->setAngularDamping(angularDamping);
body->setLinearDamping(linearDamping);
// body->setAngularDamping(Vector3(50.0f, 50.0f, 500.0f));
// body->setLinearDamping(0.9f);
return body;
}
void WhiteSphere::PossessedBy(Player *pc)
{
InteractionMaster::getSingletonPtr()->AddInteraction(this, pc);
}
void WhiteSphere::UnPossessed(Player *pc)
{
InteractionMaster::getSingletonPtr()->RemoveInteraction(this);
}
void WhiteSphere::preRender(const Ogre::FrameEvent& evt)
{
}
bool WhiteSphere::mouseMoved(Ogre::MouseEvent *e)
{
m_PhysBody->unFreeze();
m_RotateLeftRight += e->getRelX();
m_RotateUpDown += e->getRelY();
e->consume();
return true;
}
bool WhiteSphere::keyClicked(Ogre::KeyEvent* e)
{
return false;
}
bool WhiteSphere::keyPressed(Ogre::KeyEvent* e)
{
m_PhysBody->unFreeze();
switch(e->getKey())
{
case KC_W:
m_MoveForward = true;
e->consume();
return true;
case KC_S:
m_MoveBackward = true;
e->consume();
return true;
case KC_A:
m_MoveLeft = true;
e->consume();
return true;
case KC_D:
m_MoveRight = true;
e->consume();
return true;
case KC_F:
m_MoveUp = true;
e->consume();
return true;
case KC_C:
m_MoveDown = true;
e->consume();
return true;
case KC_LSHIFT:
m_MoveFast = true;
e->consume();
return true;
case KC_SPACE:
m_MoveVeryFast = true;
e->consume();
return true;
case KC_LCONTROL:
m_MoveSlow = true;
e->consume();
return true;
}
return false;
}
bool WhiteSphere::keyReleased(Ogre::KeyEvent* e)
{
switch(e->getKey())
{
case KC_W:
m_MoveForward = false;
e->consume();
return true;
case KC_S:
m_MoveBackward = false;
e->consume();
return true;
case KC_A:
m_MoveLeft = false;
e->consume();
return true;
case KC_D:
m_MoveRight = false;
e->consume();
return true;
case KC_F:
m_MoveUp = false;
e->consume();
return true;
case KC_C:
m_MoveDown = false;
e->consume();
return true;
case KC_LSHIFT:
m_MoveFast = false;
e->consume();
return true;
case KC_SPACE:
m_MoveVeryFast = false;
e->consume();
return true;
case KC_LCONTROL:
m_MoveSlow = false;
e->consume();
return true;
// default:
// CEGUI::System::getSingleton().injectKeyUp(e->getKey());
// e->consume();
// return false;
}
return false;
}
void WhiteSphere::forceCallback( OgreNewt::Body* me )
{
//apply a simple gravity force.
Real mass;
Vector3 inertia;
me->getMassMatrix(mass, inertia);
// Vector3 gravity(0,-245.0,0);
// Vector3 pos;
// Quaternion rot;
// me->getPositionOrientation(pos, rot);
// if(pos.y > hoverHeight)
// {
me->addForce(gravity*mass);
// }
// else if(pos.y < hoverHeight)
// {
// static Real pushUpMultiplier(100.0f);
// me->addForce((hoverHeight-pos.y)*pushUpMultiplier);
// }
// static Real moveAmtPerTick = 1000000.0f;
// static Real moveFastMultiplier = 10.0f;
// static Real moveVeryFastMultiplier = 100.0f;
// static Real moveSlowMultiplier = 0.25f;
// static Real rotateMultiplier = 2500000.0f;
// static Vector3 turnPos(0.0f, 0.0f, 10.0f);
Real moveScaled = moveAmtPerTick;
if(m_MoveFast) moveScaled *= moveFastMultiplier;
if(m_MoveVeryFast) moveScaled *= moveVeryFastMultiplier;
if(m_MoveSlow) moveScaled *= moveSlowMultiplier;
Vector3 moveAmt(0.0f, 0.0f, 0.0f);
if(m_MoveForward) moveAmt[2] += moveScaled;
if(m_MoveBackward) moveAmt[2] -= moveScaled;
if(m_MoveLeft) moveAmt[0] += moveScaled;
if(m_MoveRight) moveAmt[0] -= moveScaled;
if(m_MoveUp) moveAmt[1] += moveScaled;
if(m_MoveDown) moveAmt[1] -= moveScaled;
me->addLocalForce(moveAmt*moveSpeedMultiplier, Vector3(0.0f, 0.0f, 0.0f));
Vector3 turnAmt(0.0f, 0.0f, 0.0f);
bool doTurnForce = false;
if(m_RotateLeftRight)
{
doTurnForce = true;
turnAmt[0] = -(m_RotateLeftRight)*rotateMultiplier;
m_RotateLeftRight = 0.0f;
}
if(m_RotateUpDown)
{
doTurnForce = true;
turnAmt[1] = -(m_RotateUpDown)*rotateMultiplier;
m_RotateUpDown = 0.0f;
}
if(m_RotateClockwiseAndCounter) // TODO: Implement rotation if desired
{
m_RotateClockwiseAndCounter = 0.0f;
}
if(doTurnForce)
{
me->addLocalForce(turnAmt, turnPos);
}
me->addBouyancyForce(fluidDensity, fluidLinearViscosity, fluidAngularViscosity, gravity*mass, fastdelegate::MakeDelegate(this, &WhiteSphere::buoyancyCallback));
// me->addBouyancyForce(0.7, 0.9, 0.3, gravity*mass, fastdelegate::MakeDelegate(this, &WhiteSphere::buoyancyCallback));
}
bool WhiteSphere::buoyancyCallback(int colID, OgreNewt::Body* me, const Ogre::Quaternion& orient, const Ogre::Vector3& pos, Ogre::Plane& plane)
{
// Plane(pos, Ogre::Vector3(0,500,0));
plane = Plane(Ogre::Vector3(0,1,0), Ogre::Vector3(0,hoverHeight,0));
return true;
}
And using the svn link (when it is up), get revision 16, that is the last one to include this hovercraft binary in full, later ones are where I started removing all of it.