Use a separate collision type for doors (Fixes #1962)

openmw-38
scrawl 9 years ago
parent 604b5d24e9
commit 2c51e7345f

@ -58,7 +58,7 @@ namespace MWClass
void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const void Door::insertObject(const MWWorld::Ptr& ptr, const std::string& model, MWPhysics::PhysicsSystem& physics) const
{ {
if(!model.empty()) if(!model.empty())
physics.addObject(ptr, model); physics.addObject(ptr, model, MWPhysics::CollisionType_Door);
// Resume the door's opening/closing animation if it wasn't finished // Resume the door's opening/closing animation if it wasn't finished
if (ptr.getRefData().getCustomData()) if (ptr.getRefData().getCustomData())

@ -76,7 +76,7 @@ void Actor::updateCollisionMask()
mCollisionWorld->removeCollisionObject(mCollisionObject.get()); mCollisionWorld->removeCollisionObject(mCollisionObject.get());
int collisionMask = CollisionType_World | CollisionType_HeightMap; int collisionMask = CollisionType_World | CollisionType_HeightMap;
if (mExternalCollisionMode) if (mExternalCollisionMode)
collisionMask |= CollisionType_Actor | CollisionType_Projectile; collisionMask |= CollisionType_Actor | CollisionType_Projectile | CollisionType_Door;
if (mCanWaterWalk) if (mCanWaterWalk)
collisionMask |= CollisionType_Water; collisionMask |= CollisionType_Water;
mCollisionWorld->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask); mCollisionWorld->addCollisionObject(mCollisionObject.get(), CollisionType_Actor, collisionMask);

@ -6,8 +6,9 @@ namespace MWPhysics
enum CollisionType { enum CollisionType {
CollisionType_World = 1<<0, CollisionType_World = 1<<0,
CollisionType_Actor = 1<<1, CollisionType_Door = 1<<1,
CollisionType_HeightMap = 1<<2, CollisionType_Actor = 1<<2,
CollisionType_HeightMap = 1<<3,
CollisionType_Projectile = 1<<4, CollisionType_Projectile = 1<<4,
CollisionType_Water = 1<<5 CollisionType_Water = 1<<5
}; };

@ -857,7 +857,7 @@ namespace MWPhysics
const btCollisionObject* mMe; const btCollisionObject* mMe;
}; };
PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore, int mask, int group) const PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::ConstPtr ignore, int mask, int group) const
{ {
btVector3 btFrom = toBullet(from); btVector3 btFrom = toBullet(from);
btVector3 btTo = toBullet(to); btVector3 btTo = toBullet(to);
@ -923,7 +923,7 @@ namespace MWPhysics
osg::Vec3f pos1 (physactor1->getPosition() + osg::Vec3f(0,0,physactor1->getHalfExtents().z() * 0.8)); // eye level osg::Vec3f pos1 (physactor1->getPosition() + osg::Vec3f(0,0,physactor1->getHalfExtents().z() * 0.8)); // eye level
osg::Vec3f pos2 (physactor2->getPosition() + osg::Vec3f(0,0,physactor2->getHalfExtents().z() * 0.8)); osg::Vec3f pos2 (physactor2->getPosition() + osg::Vec3f(0,0,physactor2->getHalfExtents().z() * 0.8));
RayResult result = castRay(pos1, pos2, MWWorld::Ptr(), CollisionType_World|CollisionType_HeightMap); RayResult result = castRay(pos1, pos2, MWWorld::Ptr(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door);
return !result.mHit; return !result.mHit;
} }
@ -1073,7 +1073,7 @@ namespace MWPhysics
} }
} }
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh) void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType)
{ {
osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->createInstance(mesh); osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance = mShapeManager->createInstance(mesh);
if (!shapeInstance || !shapeInstance->getCollisionShape()) if (!shapeInstance || !shapeInstance->getCollisionShape())
@ -1085,7 +1085,7 @@ namespace MWPhysics
if (obj->isAnimated()) if (obj->isAnimated())
mAnimatedObjects.insert(obj); mAnimatedObjects.insert(obj);
mCollisionWorld->addCollisionObject(obj->getCollisionObject(), CollisionType_World, mCollisionWorld->addCollisionObject(obj->getCollisionObject(), collisionType,
CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile);
} }

@ -57,7 +57,7 @@ namespace MWPhysics
void setWaterHeight(float height); void setWaterHeight(float height);
void disableWater(); void disableWater();
void addObject (const MWWorld::Ptr& ptr, const std::string& mesh); void addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType = CollisionType_World);
void addActor (const MWWorld::Ptr& ptr, const std::string& mesh); void addActor (const MWWorld::Ptr& ptr, const std::string& mesh);
void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated); void updatePtr (const MWWorld::Ptr& old, const MWWorld::Ptr& updated);
@ -106,8 +106,8 @@ namespace MWPhysics
}; };
/// @param me Optional, a Ptr to ignore in the list of results /// @param me Optional, a Ptr to ignore in the list of results
RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore = MWWorld::Ptr(), int mask = RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::ConstPtr ignore = MWWorld::ConstPtr(), int mask =
CollisionType_World|CollisionType_HeightMap|CollisionType_Actor, int group=0xff) const; CollisionType_World|CollisionType_HeightMap|CollisionType_Actor|CollisionType_Door, int group=0xff) const;
RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius); RayResult castSphere(const osg::Vec3f& from, const osg::Vec3f& to, float radius);

@ -1380,7 +1380,7 @@ namespace MWWorld
{ {
osg::Vec3f a(x1,y1,z1); osg::Vec3f a(x1,y1,z1);
osg::Vec3f b(x2,y2,z2); osg::Vec3f b(x2,y2,z2);
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), MWPhysics::CollisionType_World); MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), MWPhysics::CollisionType_World|MWPhysics::CollisionType_Door);
return result.mHit; return result.mHit;
} }
@ -1413,7 +1413,7 @@ namespace MWWorld
bool reached = (targetRot == maxRot && it->second) || targetRot == minRot; bool reached = (targetRot == maxRot && it->second) || targetRot == minRot;
/// \todo should use convexSweepTest here /// \todo should use convexSweepTest here
std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(it->first, MWPhysics::CollisionType_Actor, MWPhysics::CollisionType_Actor); std::vector<MWWorld::Ptr> collisions = mPhysics->getCollisions(it->first, MWPhysics::CollisionType_Door, MWPhysics::CollisionType_Actor);
for (std::vector<MWWorld::Ptr>::iterator cit = collisions.begin(); cit != collisions.end(); ++cit) for (std::vector<MWWorld::Ptr>::iterator cit = collisions.begin(); cit != collisions.end(); ++cit)
{ {
MWWorld::Ptr ptr = *cit; MWWorld::Ptr ptr = *cit;
@ -2334,7 +2334,7 @@ namespace MWWorld
to = from + (to * maxDist); to = from + (to * maxDist);
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from, to, MWWorld::Ptr(), MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from, to, MWWorld::Ptr(),
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap); MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap|MWPhysics::CollisionType_Door);
if (!result.mHit) if (!result.mHit)
return maxDist; return maxDist;

Loading…
Cancel
Save