diff --git a/CHANGELOG.md b/CHANGELOG.md index b707851de..a4e736467 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -149,6 +149,7 @@ Feature #1617: Editor: Enchantment effect record verifier Feature #1645: Casting effects from objects Feature #2606: Editor: Implemented (optional) case sensitive global search + Feature #2787: Use the autogenerated collision box, if the creature mesh has no predefined one Feature #2847: Content selector: allow to copy the path to a file by using the context menu Feature #3083: Play animation when NPC is casting spell via script Feature #3103: Provide option for disposition to get increased by successful trade diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 79c6dcabf..b55c20455 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "../mwworld/class.hpp" @@ -28,6 +29,31 @@ Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr mHalfExtents = shape->mCollisionBoxHalfExtents; mMeshTranslation = shape->mCollisionBoxTranslate; + // We can not create actor without collisions - he will fall through the ground. + // In this case we should autogenerate collision box based on mesh shape + // (NPCs have bodyparts and use a different approach) + if (!ptr.getClass().isNpc() && mHalfExtents.length2() == 0.f) + { + const Resource::BulletShape* collisionShape = shape.get(); + if (collisionShape && collisionShape->mCollisionShape) + { + btTransform transform; + transform.setIdentity(); + btVector3 min; + btVector3 max; + + collisionShape->mCollisionShape->getAabb(transform, min, max); + mHalfExtents.x() = (max[0] - min[0])/2.f; + mHalfExtents.y() = (max[1] - min[1])/2.f; + mHalfExtents.z() = (max[2] - min[2])/2.f; + + mMeshTranslation = osg::Vec3f(0.f, 0.f, mHalfExtents.z()); + } + + if (mHalfExtents.length2() == 0.f) + Log(Debug::Error) << "Error: Failed to calculate bounding box for actor \"" << ptr.getCellRef().getRefId() << "\"."; + } + // Use capsule shape only if base is square (nonuniform scaling apparently doesn't work on it) if (std::abs(mHalfExtents.x()-mHalfExtents.y())= mHalfExtents.x()) { diff --git a/components/resource/bulletshape.hpp b/components/resource/bulletshape.hpp index a418bb28c..b30b5045c 100644 --- a/components/resource/bulletshape.hpp +++ b/components/resource/bulletshape.hpp @@ -26,8 +26,7 @@ namespace Resource btCollisionShape* mCollisionShape; - // Used for actors. Note, ideally actors would use a separate loader - as it is - // we have to keep a redundant copy of the actor model around in mCollisionShape, which isn't used. + // Used for actors. mCollisionShape is used for actors only when we need to autogenerate collision box for creatures. // For now, use one file <-> one resource for simplicity. osg::Vec3f mCollisionBoxHalfExtents; osg::Vec3f mCollisionBoxTranslate;