LJS wrote:A jetpack is very simple. As I tend to generalize everything - which is the core of OOP or c++ wouldn't have existed - I've taken the liberty to use a jetpack.
Since you claim to be a beginner, I'm being bold and self-declare myself the veteran here.
You're falling victim to over-approximation.
The core of OOP is not to generalize everything. It is to generalize
when it makes sense providing you the tools to do so. And there are a few reasons for which this should not happen, such as the fact you're thinking at a generic kinematic controller (low level abstraction), but tied to a very specific gameplay concept (high level abstraction). If you think this is OOP I'm afraid we give two different meanings to the word. Personally I was introduced to OOP when it meant "functions are written near the data they mangle".
A humanoid is just the same as a car, plane or whatever. A jetpack could be a bicycle. They move and boom they hit something, i.e. collision detected. Then they can't move or will destruct whatever they bumped into.
No. A car needs its own internal simulation for kinematics, many articles have been written about that. I've never seen a bicycle explode in reality. A humanoid is absolutely NOT the same as a car.
Again, you can go with overgeneralization as much as you want. Ring me when you get the job done.
There's no "for instance" in game design. There are the requirements, the functionalities you need to make your game work and the functionalities you need to get the job done without losing your mental sanity.
Anything else is not supposed to be there.
Anyway...
Code: Select all
class cPhysicsManager
{
void update( Ogre::Real deltaTime )
{
// atm: m_dynamicsWorld is an btDiscreteDynamicsWorld*
m_dynamicsWorld->stepSimulation( deltaTime );
int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();
// note you were doing it the other way around: you were looking for a matching wrapper class for each pointer
// returned by manifolds. It is probably easier to it the other way around as you have to keep those objects somewhere.
cWrappingClass *interesting = ...; // or loop on a collection.
interesting->wasTouching = interesting.currentlyTouching; // fully copy for readability
interesting->currentlyTouching.clear();
for( int i = 0; i < numManifolds; ++i )
{
btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
btCollisionObject* obA = (btCollisionObject*)contactManifold->getBody0();
btCollisionObject* obB = (btCollisionObject*)contactManifold->getBody1();
if(interesting != obA && interesting != obB) continue;
btCollisionObject *other = obA == interesting? obB : obA;
// also remember to reject based on bidirectional distance. It takes some care...
interesting->currentlyTouching.push_back(other); // or maybe push more data. or maybe use std::set.
}
}
interesting->NotifyCollisionEnd(); // for each pointer in wasTouching which is not in currentlyTouching send a message
interesting->NotifyCollisionBegin(); // for each pointer in currentlyTouching which is not in wasTouching, send a message.
}
My specific need is: for instance (generalize stuff) the humanoid starts flying up 2 metres then it bumps into a ceiling (can be the inside of a plane, doesn't matter). How to prevend moving.
When collision occurs, the manifold shows up in the manifold pool (eventually local to a btGhostObject). If a manifold involves touching or encroaching, send a "Touch" event to the kinematic controller. This is the only thing that in
general makes sense.
Code: Select all
class FlyingMan : public cWrappingClass {
bool canMove;
void OnCollisionBegin() { canMove = false; }
void updateAction(...) {
if(canMove) { ... }
}
};
Actually, nobody would likely do that, until you want the collided object to be sticky: you probably just need to check your sweeps (because you are sweeping them don't you?).
My specific need is: for instance (generalize stuff) the car (worn by cChar, see topmost snippet) starts riding and then it bumps into a plane which has landed. How to prevend moving, start crashing, catch fire.
Kinematic controller reaction to "touch" event is to hide current mesh and spawn a particle system "fire".
Code: Select all
class BoomBoomCar : public cWrappingClass {
...
void OnCollisionBegin() {
graphicsMesh.FadeOut(1.0f); // say this blends to alpha=0 in 1 second, in the meanwhile...
ParticleSystem *ps = particleManager.NewSystemFromResource("Fire.ps.settings"); // "particle system setting resource", texture to use, how to animate...
ps->SetOrigin(graphicsMesh.getNamedPoint("joint_explosion");
ps->Active(true);
this->MarkForRigidBodyRemoval(); // nobody really wants to call this->dtor on the go
this->ps = ps; // say we keep ownership of it...
}
};
Of course for a lot of objects it would be far better to use btGhostObject instead of using the global pool but for a start we go that way.
Is it starting to be make sense?