mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:53:50 +00:00
Rotate door object using direct rotation order once
Instead of rotating using inverse and then applying the direct rotation. To properly update object in navigator.
This commit is contained in:
parent
eec5d80566
commit
3cfd5fca4e
6 changed files with 49 additions and 21 deletions
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
|
||||
#define GAME_MWBASE_WORLD_H
|
||||
|
||||
#include "rotationflags.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
@ -280,7 +282,8 @@ namespace MWBase
|
|||
|
||||
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;
|
||||
///< Place an object. Makes a copy of the Ptr.
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
using MWWorld::RotationOrder;
|
||||
|
||||
osg::Quat makeActorOsgQuat(const ESM::Position& position)
|
||||
{
|
||||
return osg::Quat(position.rot[2], osg::Vec3(0, 0, -1));
|
||||
|
@ -67,7 +69,7 @@ namespace
|
|||
* 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())
|
||||
return;
|
||||
|
@ -75,7 +77,7 @@ namespace
|
|||
rendering.rotateObject(ptr,
|
||||
ptr.getClass().isActor()
|
||||
? makeActorOsgQuat(ptr.getRefData().getPosition())
|
||||
: (inverseRotationOrder
|
||||
: (order == RotationOrder::inverse
|
||||
? makeInversedOrderObjectOsgQuat(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
|
||||
|
||||
ptr.getClass().insertObjectRendering(ptr, model, rendering);
|
||||
setNodeRotation(ptr, rendering, false);
|
||||
setNodeRotation(ptr, rendering, RotationOrder::direct);
|
||||
|
||||
ptr.getClass().insertObject (ptr, model, physics);
|
||||
|
||||
|
@ -179,9 +181,9 @@ namespace
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -278,9 +280,9 @@ namespace
|
|||
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)
|
||||
|
|
|
@ -51,6 +51,12 @@ namespace MWWorld
|
|||
class CellStore;
|
||||
class CellPreloader;
|
||||
|
||||
enum class RotationOrder
|
||||
{
|
||||
direct,
|
||||
inverse
|
||||
};
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
|
@ -137,7 +143,7 @@ namespace MWWorld
|
|||
void removeObjectFromScene (const Ptr& ptr);
|
||||
///< 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);
|
||||
|
||||
bool isCellActive(const CellStore &cell);
|
||||
|
|
|
@ -1348,13 +1348,13 @@ namespace MWWorld
|
|||
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);
|
||||
|
||||
ESM::Position pos = ptr.getRefData().getPosition();
|
||||
float *objRot = pos.rot;
|
||||
if(adjust)
|
||||
if (flags & MWBase::RotationFlag_adjust)
|
||||
{
|
||||
objRot[0] += rot.x();
|
||||
objRot[1] += rot.y();
|
||||
|
@ -1386,7 +1386,9 @@ namespace MWWorld
|
|||
|
||||
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))
|
||||
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)
|
||||
|
@ -1638,7 +1640,7 @@ namespace MWWorld
|
|||
|
||||
float diff = duration * osg::DegreesToRadians(90.f);
|
||||
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;
|
||||
|
||||
|
@ -1682,11 +1684,9 @@ namespace MWWorld
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -2479,7 +2479,7 @@ namespace MWWorld
|
|||
player.getClass().getInventoryStore(player).setContListener(anim);
|
||||
|
||||
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()->watchActor(getPlayerPtr());
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace MWWorld
|
|||
void updateWeather(float duration, bool paused = false);
|
||||
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);
|
||||
///< @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
|
||||
/// could be considered a bug, but is needed for MW compatibility.
|
||||
/// \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;
|
||||
///< Place an object. Makes a copy of the Ptr.
|
||||
|
|
Loading…
Reference in a new issue