mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-17 10:21:11 +00:00
Merge pull request #2620 from elsid/fix_cage_door_rotation
Rotate door object using direct rotation order once
This commit is contained in:
commit
058bbf4b0f
16
apps/openmw/mwbase/rotationflags.hpp
Normal file
16
apps/openmw/mwbase/rotationflags.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef GAME_MWBASE_ROTATIONFLAGS_H
|
||||||
|
#define GAME_MWBASE_ROTATIONFLAGS_H
|
||||||
|
|
||||||
|
namespace MWBase
|
||||||
|
{
|
||||||
|
using RotationFlags = unsigned short;
|
||||||
|
|
||||||
|
enum RotationFlag : RotationFlags
|
||||||
|
{
|
||||||
|
RotationFlag_none = 0,
|
||||||
|
RotationFlag_adjust = 1,
|
||||||
|
RotationFlag_inverseOrder = 1 << 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef GAME_MWBASE_WORLD_H
|
#ifndef GAME_MWBASE_WORLD_H
|
||||||
#define GAME_MWBASE_WORLD_H
|
#define GAME_MWBASE_WORLD_H
|
||||||
|
|
||||||
|
#include "rotationflags.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -280,7 +282,8 @@ namespace MWBase
|
|||||||
|
|
||||||
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
||||||
|
|
||||||
virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z, bool adjust = false) = 0;
|
virtual void rotateObject(const MWWorld::Ptr& ptr, float x, float y, float z,
|
||||||
|
RotationFlags flags = RotationFlag_inverseOrder) = 0;
|
||||||
|
|
||||||
virtual MWWorld::Ptr placeObject(const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, ESM::Position pos) = 0;
|
virtual MWWorld::Ptr placeObject(const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, ESM::Position pos) = 0;
|
||||||
///< Place an object. Makes a copy of the Ptr.
|
///< Place an object. Makes a copy of the Ptr.
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
using MWWorld::RotationOrder;
|
||||||
|
|
||||||
osg::Quat makeActorOsgQuat(const ESM::Position& position)
|
osg::Quat makeActorOsgQuat(const ESM::Position& position)
|
||||||
{
|
{
|
||||||
return osg::Quat(position.rot[2], osg::Vec3(0, 0, -1));
|
return osg::Quat(position.rot[2], osg::Vec3(0, 0, -1));
|
||||||
@ -67,7 +69,7 @@ namespace
|
|||||||
* osg::Quat(xr, osg::Vec3(-1, 0, 0));
|
* osg::Quat(xr, osg::Vec3(-1, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNodeRotation(const MWWorld::Ptr& ptr, MWRender::RenderingManager& rendering, const bool inverseRotationOrder)
|
void setNodeRotation(const MWWorld::Ptr& ptr, MWRender::RenderingManager& rendering, RotationOrder order)
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getBaseNode())
|
if (!ptr.getRefData().getBaseNode())
|
||||||
return;
|
return;
|
||||||
@ -75,7 +77,7 @@ namespace
|
|||||||
rendering.rotateObject(ptr,
|
rendering.rotateObject(ptr,
|
||||||
ptr.getClass().isActor()
|
ptr.getClass().isActor()
|
||||||
? makeActorOsgQuat(ptr.getRefData().getPosition())
|
? makeActorOsgQuat(ptr.getRefData().getPosition())
|
||||||
: (inverseRotationOrder
|
: (order == RotationOrder::inverse
|
||||||
? makeInversedOrderObjectOsgQuat(ptr.getRefData().getPosition())
|
? makeInversedOrderObjectOsgQuat(ptr.getRefData().getPosition())
|
||||||
: makeObjectOsgQuat(ptr.getRefData().getPosition()))
|
: makeObjectOsgQuat(ptr.getRefData().getPosition()))
|
||||||
);
|
);
|
||||||
@ -100,7 +102,7 @@ namespace
|
|||||||
model = ""; // marker objects that have a hardcoded function in the game logic, should be hidden from the player
|
model = ""; // marker objects that have a hardcoded function in the game logic, should be hidden from the player
|
||||||
|
|
||||||
ptr.getClass().insertObjectRendering(ptr, model, rendering);
|
ptr.getClass().insertObjectRendering(ptr, model, rendering);
|
||||||
setNodeRotation(ptr, rendering, false);
|
setNodeRotation(ptr, rendering, RotationOrder::direct);
|
||||||
|
|
||||||
ptr.getClass().insertObject (ptr, model, physics);
|
ptr.getClass().insertObject (ptr, model, physics);
|
||||||
|
|
||||||
@ -179,9 +181,9 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateObjectRotation (const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics,
|
void updateObjectRotation (const MWWorld::Ptr& ptr, MWPhysics::PhysicsSystem& physics,
|
||||||
MWRender::RenderingManager& rendering, bool inverseRotationOrder)
|
MWRender::RenderingManager& rendering, RotationOrder order)
|
||||||
{
|
{
|
||||||
setNodeRotation(ptr, rendering, inverseRotationOrder);
|
setNodeRotation(ptr, rendering, order);
|
||||||
physics.updateRotation(ptr);
|
physics.updateRotation(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,9 +280,9 @@ namespace
|
|||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
|
|
||||||
void Scene::updateObjectRotation (const Ptr& ptr, bool inverseRotationOrder)
|
void Scene::updateObjectRotation(const Ptr& ptr, RotationOrder order)
|
||||||
{
|
{
|
||||||
::updateObjectRotation(ptr, *mPhysics, mRendering, inverseRotationOrder);
|
::updateObjectRotation(ptr, *mPhysics, mRendering, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::updateObjectScale(const Ptr &ptr)
|
void Scene::updateObjectScale(const Ptr &ptr)
|
||||||
|
@ -51,6 +51,12 @@ namespace MWWorld
|
|||||||
class CellStore;
|
class CellStore;
|
||||||
class CellPreloader;
|
class CellPreloader;
|
||||||
|
|
||||||
|
enum class RotationOrder
|
||||||
|
{
|
||||||
|
direct,
|
||||||
|
inverse
|
||||||
|
};
|
||||||
|
|
||||||
class Scene
|
class Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -137,7 +143,7 @@ namespace MWWorld
|
|||||||
void removeObjectFromScene (const Ptr& ptr);
|
void removeObjectFromScene (const Ptr& ptr);
|
||||||
///< Remove an object from the scene, but not from the world model.
|
///< Remove an object from the scene, but not from the world model.
|
||||||
|
|
||||||
void updateObjectRotation (const Ptr& ptr, bool inverseRotationOrder);
|
void updateObjectRotation(const Ptr& ptr, RotationOrder order);
|
||||||
void updateObjectScale(const Ptr& ptr);
|
void updateObjectScale(const Ptr& ptr);
|
||||||
|
|
||||||
bool isCellActive(const CellStore &cell);
|
bool isCellActive(const CellStore &cell);
|
||||||
|
@ -1348,13 +1348,13 @@ namespace MWWorld
|
|||||||
mShouldUpdateNavigator = updateNavigatorObject(object) || mShouldUpdateNavigator;
|
mShouldUpdateNavigator = updateNavigatorObject(object) || mShouldUpdateNavigator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::rotateObjectImp (const Ptr& ptr, const osg::Vec3f& rot, bool adjust)
|
void World::rotateObjectImp(const Ptr& ptr, const osg::Vec3f& rot, MWBase::RotationFlags flags)
|
||||||
{
|
{
|
||||||
const float pi = static_cast<float>(osg::PI);
|
const float pi = static_cast<float>(osg::PI);
|
||||||
|
|
||||||
ESM::Position pos = ptr.getRefData().getPosition();
|
ESM::Position pos = ptr.getRefData().getPosition();
|
||||||
float *objRot = pos.rot;
|
float *objRot = pos.rot;
|
||||||
if(adjust)
|
if (flags & MWBase::RotationFlag_adjust)
|
||||||
{
|
{
|
||||||
objRot[0] += rot.x();
|
objRot[0] += rot.x();
|
||||||
objRot[1] += rot.y();
|
objRot[1] += rot.y();
|
||||||
@ -1386,7 +1386,9 @@ namespace MWWorld
|
|||||||
|
|
||||||
if(ptr.getRefData().getBaseNode() != 0)
|
if(ptr.getRefData().getBaseNode() != 0)
|
||||||
{
|
{
|
||||||
mWorldScene->updateObjectRotation(ptr, true);
|
const auto order = flags & MWBase::RotationFlag_inverseOrder
|
||||||
|
? RotationOrder::inverse : RotationOrder::direct;
|
||||||
|
mWorldScene->updateObjectRotation(ptr, order);
|
||||||
|
|
||||||
if (const auto object = mPhysics->getObject(ptr))
|
if (const auto object = mPhysics->getObject(ptr))
|
||||||
updateNavigatorObject(object);
|
updateNavigatorObject(object);
|
||||||
@ -1458,9 +1460,9 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
|
void World::rotateObject (const Ptr& ptr, float x, float y, float z, MWBase::RotationFlags flags)
|
||||||
{
|
{
|
||||||
rotateObjectImp(ptr, osg::Vec3f(x, y, z), adjust);
|
rotateObjectImp(ptr, osg::Vec3f(x, y, z), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::rotateWorldObject (const Ptr& ptr, osg::Quat rotate)
|
void World::rotateWorldObject (const Ptr& ptr, osg::Quat rotate)
|
||||||
@ -1638,7 +1640,7 @@ namespace MWWorld
|
|||||||
|
|
||||||
float diff = duration * osg::DegreesToRadians(90.f);
|
float diff = duration * osg::DegreesToRadians(90.f);
|
||||||
float targetRot = std::min(std::max(minRot, oldRot + diff * (state == MWWorld::DoorState::Opening ? 1 : -1)), maxRot);
|
float targetRot = std::min(std::max(minRot, oldRot + diff * (state == MWWorld::DoorState::Opening ? 1 : -1)), maxRot);
|
||||||
rotateObject(door, objPos.rot[0], objPos.rot[1], targetRot);
|
rotateObject(door, objPos.rot[0], objPos.rot[1], targetRot, MWBase::RotationFlag_none);
|
||||||
|
|
||||||
bool reached = (targetRot == maxRot && state != MWWorld::DoorState::Idle) || targetRot == minRot;
|
bool reached = (targetRot == maxRot && state != MWWorld::DoorState::Idle) || targetRot == minRot;
|
||||||
|
|
||||||
@ -1682,11 +1684,9 @@ namespace MWWorld
|
|||||||
MWBase::Environment::get().getSoundManager()->stopSound3D(door, closeSound);
|
MWBase::Environment::get().getSoundManager()->stopSound3D(door, closeSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
rotateObject(door, objPos.rot[0], objPos.rot[1], oldRot);
|
rotateObject(door, objPos.rot[0], objPos.rot[1], oldRot, MWBase::RotationFlag_none);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the rotation order we want to use
|
|
||||||
mWorldScene->updateObjectRotation(door, false);
|
|
||||||
return reached;
|
return reached;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2479,7 +2479,7 @@ namespace MWWorld
|
|||||||
player.getClass().getInventoryStore(player).setContListener(anim);
|
player.getClass().getInventoryStore(player).setContListener(anim);
|
||||||
|
|
||||||
scaleObject(player, player.getCellRef().getScale()); // apply race height
|
scaleObject(player, player.getCellRef().getScale()); // apply race height
|
||||||
rotateObject(player, 0.f, 0.f, 0.f, true);
|
rotateObject(player, 0.f, 0.f, 0.f, MWBase::RotationFlag_inverseOrder | MWBase::RotationFlag_adjust);
|
||||||
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->add(getPlayerPtr());
|
MWBase::Environment::get().getMechanicsManager()->add(getPlayerPtr());
|
||||||
MWBase::Environment::get().getMechanicsManager()->watchActor(getPlayerPtr());
|
MWBase::Environment::get().getMechanicsManager()->watchActor(getPlayerPtr());
|
||||||
|
@ -126,7 +126,7 @@ namespace MWWorld
|
|||||||
void updateWeather(float duration, bool paused = false);
|
void updateWeather(float duration, bool paused = false);
|
||||||
int getDaysPerMonth (int month) const;
|
int getDaysPerMonth (int month) const;
|
||||||
|
|
||||||
void rotateObjectImp (const Ptr& ptr, const osg::Vec3f& rot, bool adjust);
|
void rotateObjectImp (const Ptr& ptr, const osg::Vec3f& rot, MWBase::RotationFlags flags);
|
||||||
|
|
||||||
Ptr moveObjectImp (const Ptr& ptr, float x, float y, float z, bool movePhysics=true, bool moveToActive=false);
|
Ptr moveObjectImp (const Ptr& ptr, float x, float y, float z, bool movePhysics=true, bool moveToActive=false);
|
||||||
///< @return an updated Ptr in case the Ptr's cell changes
|
///< @return an updated Ptr in case the Ptr's cell changes
|
||||||
@ -393,7 +393,8 @@ namespace MWWorld
|
|||||||
/// @note Rotations via this method use a different rotation order than the initial rotations in the CS. This
|
/// @note Rotations via this method use a different rotation order than the initial rotations in the CS. This
|
||||||
/// could be considered a bug, but is needed for MW compatibility.
|
/// could be considered a bug, but is needed for MW compatibility.
|
||||||
/// \param adjust indicates rotation should be set or adjusted
|
/// \param adjust indicates rotation should be set or adjusted
|
||||||
void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false) override;
|
void rotateObject (const Ptr& ptr, float x, float y, float z,
|
||||||
|
MWBase::RotationFlags flags = MWBase::RotationFlag_inverseOrder) override;
|
||||||
|
|
||||||
MWWorld::Ptr placeObject(const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, ESM::Position pos) override;
|
MWWorld::Ptr placeObject(const MWWorld::ConstPtr& ptr, MWWorld::CellStore* cell, ESM::Position pos) override;
|
||||||
///< Place an object. Makes a copy of the Ptr.
|
///< Place an object. Makes a copy of the Ptr.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user