In my game, there are two 'dimensions' or 'parallel worlds' (I've mentioned in a previous post). The player can switch from one dimension to another, and the world is slightly different in either dimension (there's a wall here, but it isn't there in the other one etc.). I get this to work using collision flags. That way, things only collide if they share a common dimension. The player switches dimension by having his rigidbody removed and then re-added with the new flags.
Now, the problem I face is what to do if the player tries to switch to the other dimension at a point where there's a wall in the other dimension (if he switches he'll intersect). What I'm thinking of doing is a spherecast (player is sphere-shaped) that checks for objects having the other flag at the player's position, and switching only if it's free. I'm not sure how to do a sphere-vs-world cast though, so I just tried with a convex. This cast works only if the convex actually intersects a trimesh face (level geometry is trimesh), and isn't 'inside' it. Is there anyway to instead detect when an object is 'inside' another?
This is what I'm doing, but as I said, it works only for face intersections.
Code: Select all
btVector3 pos1 = mBody->getWorldTransform().getOrigin();
btVector3 pos2 = mBody->getWorldTransform().getOrigin() + btVector3(0,0.1,0); //We need /some/ displacement it seems.
btQuaternion rot = mBody->getWorldTransform().getRotation();
btTransform trans1(rot, pos1);
btTransform trans2(rot, pos2);
btConvexShape *shape = BtOgre::StaticMeshToShapeConverter(mEntity).createConvex(); //Creates convex from graphic entity.
struct TempCallback : public btDynamicsWorld::ConvexResultCallback
{
std::vector<btCollisionObject*> mHits;
btScalar addSingleResult(btDynamicsWorld::LocalConvexResult& convexResult, bool normalInWorldSpace)
{
mHits.push_back(convexResult.m_hitCollisionObject);
NGF::GameObject *obj = NGF::Bullet::fromBulletObject(convexResult.m_hitCollisionObject);
LOG(obj->getFlags());
return convexResult.m_hitFraction;
}
} res;
GlbVar.phyWorld->convexSweepTest(shape, trans1, trans2, res);
for (std::vector<btCollisionObject*>::iterator iter = res.mHits.begin(); iter != res.mHits.end(); ++iter)
{
btCollisionObject *currHit = (*iter);
if (currHit == mBody)
continue;
if (!(currHit->getCollisionFlags() & mDimensions))
/* can't switch */
}
My main questions are: How do I do a sphere-vs-world cast? How to ensure that it doesn't check just for face intersection, but also whether the object is inside a trimesh?