diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index a95672f8cf..879c12124e 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -15,22 +16,18 @@ namespace MWPhysics { Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler) - : mShapeInstance(shapeInstance) + : mShapeInstance(std::move(shapeInstance)) , mSolid(true) + , mScale(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale()) + , mPosition(ptr.getRefData().getPosition().asVec3()) + , mRotation(rotation) , mTaskScheduler(scheduler) { mPtr = ptr; - - mCollisionObject = std::make_unique(); - mCollisionObject->setCollisionShape(shapeInstance->getCollisionShape()); - + mCollisionObject = BulletHelpers::makeCollisionObject(mShapeInstance->getCollisionShape(), + Misc::Convert::toBullet(mPosition), Misc::Convert::toBullet(rotation)); mCollisionObject->setUserPointer(this); - - setScale(ptr.getCellRef().getScale()); - setRotation(rotation); - updatePosition(); - commitPositionChange(); - + mShapeInstance->setLocalScaling(mScale); mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index ed68a46059..bb0f7437bd 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -65,23 +65,12 @@ namespace * osg::Quat(zr, osg::Vec3(0, 0, -1)); } - osg::Quat makeObjectOsgQuat(const ESM::Position& position) - { - const float xr = position.rot[0]; - const float yr = position.rot[1]; - const float zr = position.rot[2]; - - return osg::Quat(zr, osg::Vec3(0, 0, -1)) - * osg::Quat(yr, osg::Vec3(0, -1, 0)) - * osg::Quat(xr, osg::Vec3(-1, 0, 0)); - } - osg::Quat makeNodeRotation(const MWWorld::Ptr& ptr, RotationOrder order) { const auto pos = ptr.getRefData().getPosition(); const auto rot = ptr.getClass().isActor() ? makeActorOsgQuat(pos) - : (order == RotationOrder::inverse ? makeInversedOrderObjectOsgQuat(pos) : makeObjectOsgQuat(pos)); + : (order == RotationOrder::inverse ? makeInversedOrderObjectOsgQuat(pos) : Misc::Convert::makeOsgQuat(pos)); return rot; } @@ -155,7 +144,7 @@ namespace const auto transform = object->getTransform(); const btTransform closedDoorTransform( - Misc::Convert::toBullet(makeObjectOsgQuat(ptr.getCellRef().getPosition())), + Misc::Convert::makeBulletQuaternion(ptr.getCellRef().getPosition()), transform.getOrigin() ); diff --git a/components/bullethelpers/collisionobject.hpp b/components/bullethelpers/collisionobject.hpp new file mode 100644 index 0000000000..0951c2af38 --- /dev/null +++ b/components/bullethelpers/collisionobject.hpp @@ -0,0 +1,24 @@ +#ifndef OPENMW_COMPONENTS_BULLETHELPERS_COLLISIONOBJECT_H +#define OPENMW_COMPONENTS_BULLETHELPERS_COLLISIONOBJECT_H + +#include + +#include +#include +#include + +#include + +namespace BulletHelpers +{ + inline std::unique_ptr makeCollisionObject(btCollisionShape* shape, + const btVector3& position, const btQuaternion& rotation) + { + std::unique_ptr result = std::make_unique(); + result->setCollisionShape(shape); + result->setWorldTransform(btTransform(rotation, position)); + return result; + } +} + +#endif diff --git a/components/misc/convert.hpp b/components/misc/convert.hpp index c5784d33ae..81270c0c0b 100644 --- a/components/misc/convert.hpp +++ b/components/misc/convert.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_COMPONENTS_MISC_CONVERT_H #define OPENMW_COMPONENTS_MISC_CONVERT_H +#include #include #include @@ -47,6 +48,30 @@ namespace Convert { return osg::Quat(quat.x(), quat.y(), quat.z(), quat.w()); } + + inline osg::Quat makeOsgQuat(const float (&rotation)[3]) + { + return osg::Quat(rotation[2], osg::Vec3f(0, 0, -1)) + * osg::Quat(rotation[1], osg::Vec3f(0, -1, 0)) + * osg::Quat(rotation[0], osg::Vec3f(-1, 0, 0)); + } + + inline osg::Quat makeOsgQuat(const ESM::Position& position) + { + return makeOsgQuat(position.rot); + } + + inline btQuaternion makeBulletQuaternion(const float (&rotation)[3]) + { + return btQuaternion(btVector3(0, 0, -1), rotation[2]) + * btQuaternion(btVector3(0, -1, 0), rotation[1]) + * btQuaternion(btVector3(-1, 0, 0), rotation[0]); + } + + inline btQuaternion makeBulletQuaternion(const ESM::Position& position) + { + return makeBulletQuaternion(position.rot); + } } }