mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Rotations: remove LocalRotation
This never existed in vanilla MW in the first place. The reason we got confused was because of a strange behaviour where the order of applying rotations changes as soon as a script touches the object's rotation.
This commit is contained in:
parent
666fbba1e0
commit
b4ce73f179
10 changed files with 20 additions and 103 deletions
|
@ -270,8 +270,6 @@ namespace MWBase
|
||||||
|
|
||||||
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, bool adjust = false) = 0;
|
||||||
|
|
||||||
virtual void localRotateObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;
|
|
||||||
|
|
||||||
virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr, MWWorld::CellStore* cell, ESM::Position pos) = 0;
|
virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr, MWWorld::CellStore* cell, ESM::Position pos) = 0;
|
||||||
///< place an object in a "safe" location (ie not in the void, etc).
|
///< place an object in a "safe" location (ie not in the void, etc).
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,12 @@ namespace MWScript
|
||||||
if (ptr.getTypeName() == typeid(ESM::Door).name() && !ptr.getCellRef().getTeleport())
|
if (ptr.getTypeName() == typeid(ESM::Door).name() && !ptr.getCellRef().getTeleport())
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getWorld()->activateDoor(ptr, 0);
|
MWBase::Environment::get().getWorld()->activateDoor(ptr, 0);
|
||||||
MWBase::Environment::get().getWorld()->localRotateObject(ptr, 0, 0, 0);
|
|
||||||
|
float xr = ptr.getCellRef().getPosition().rot[0];
|
||||||
|
float yr = ptr.getCellRef().getPosition().rot[1];
|
||||||
|
float zr = ptr.getCellRef().getPosition().rot[2];
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWorld()->rotateObject(ptr, xr, yr, zr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,26 +92,12 @@ namespace MWScript
|
||||||
float ay = ptr.getRefData().getPosition().rot[1];
|
float ay = ptr.getRefData().getPosition().rot[1];
|
||||||
float az = ptr.getRefData().getPosition().rot[2];
|
float az = ptr.getRefData().getPosition().rot[2];
|
||||||
|
|
||||||
MWWorld::LocalRotation localRot = ptr.getRefData().getLocalRotation();
|
|
||||||
|
|
||||||
if (axis == "x")
|
if (axis == "x")
|
||||||
{
|
|
||||||
localRot.rot[0] = 0;
|
|
||||||
ptr.getRefData().setLocalRotation(localRot);
|
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az);
|
||||||
}
|
|
||||||
else if (axis == "y")
|
else if (axis == "y")
|
||||||
{
|
|
||||||
localRot.rot[1] = 0;
|
|
||||||
ptr.getRefData().setLocalRotation(localRot);
|
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az);
|
||||||
}
|
|
||||||
else if (axis == "z")
|
else if (axis == "z")
|
||||||
{
|
|
||||||
localRot.rot[2] = 0;
|
|
||||||
ptr.getRefData().setLocalRotation(localRot);
|
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
throw std::runtime_error ("invalid rotation axis: " + axis);
|
throw std::runtime_error ("invalid rotation axis: " + axis);
|
||||||
}
|
}
|
||||||
|
@ -568,25 +554,19 @@ namespace MWScript
|
||||||
|
|
||||||
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
|
Interpreter::Type_Float rotation = osg::DegreesToRadians(runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
float ax = osg::RadiansToDegrees(ptr.getRefData().getLocalRotation().rot[0]);
|
float ax = ptr.getRefData().getPosition().rot[0];
|
||||||
float ay = osg::RadiansToDegrees(ptr.getRefData().getLocalRotation().rot[1]);
|
float ay = ptr.getRefData().getPosition().rot[1];
|
||||||
float az = osg::RadiansToDegrees(ptr.getRefData().getLocalRotation().rot[2]);
|
float az = ptr.getRefData().getPosition().rot[2];
|
||||||
|
|
||||||
if (axis == "x")
|
if (axis == "x")
|
||||||
{
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax+rotation,ay,az);
|
||||||
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax+rotation,ay,az);
|
|
||||||
}
|
|
||||||
else if (axis == "y")
|
else if (axis == "y")
|
||||||
{
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay+rotation,az);
|
||||||
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay+rotation,az);
|
|
||||||
}
|
|
||||||
else if (axis == "z")
|
else if (axis == "z")
|
||||||
{
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,az+rotation);
|
||||||
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay,az+rotation);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
throw std::runtime_error ("invalid rotation axis: " + axis);
|
throw std::runtime_error ("invalid rotation axis: " + axis);
|
||||||
}
|
}
|
||||||
|
@ -641,13 +621,11 @@ namespace MWScript
|
||||||
if (!ptr.isInCell())
|
if (!ptr.isInCell())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MWWorld::LocalRotation rot;
|
float xr = ptr.getCellRef().getPosition().rot[0];
|
||||||
rot.rot[0] = 0;
|
float yr = ptr.getCellRef().getPosition().rot[1];
|
||||||
rot.rot[1] = 0;
|
float zr = ptr.getCellRef().getPosition().rot[2];
|
||||||
rot.rot[2] = 0;
|
|
||||||
ptr.getRefData().setLocalRotation(rot);
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0,0,0,true);
|
MWBase::Environment::get().getWorld()->rotateObject(ptr, xr, yr, zr);
|
||||||
|
|
||||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(
|
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(
|
||||||
MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().pos[0],
|
MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().pos[0],
|
||||||
|
|
|
@ -17,7 +17,6 @@ namespace MWWorld
|
||||||
mEnabled = refData.mEnabled;
|
mEnabled = refData.mEnabled;
|
||||||
mCount = refData.mCount;
|
mCount = refData.mCount;
|
||||||
mPosition = refData.mPosition;
|
mPosition = refData.mPosition;
|
||||||
mLocalRotation = refData.mLocalRotation;
|
|
||||||
mChanged = refData.mChanged;
|
mChanged = refData.mChanged;
|
||||||
mDeleted = refData.mDeleted;
|
mDeleted = refData.mDeleted;
|
||||||
|
|
||||||
|
@ -37,7 +36,6 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
{
|
{
|
||||||
mLocalRotation.rot[i] = 0;
|
|
||||||
mPosition.pos[i] = 0;
|
mPosition.pos[i] = 0;
|
||||||
mPosition.rot[i] = 0;
|
mPosition.rot[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -49,9 +47,6 @@ namespace MWWorld
|
||||||
mCustomData (0),
|
mCustomData (0),
|
||||||
mChanged(false) // Loading from ESM/ESP files -> assume unchanged
|
mChanged(false) // Loading from ESM/ESP files -> assume unchanged
|
||||||
{
|
{
|
||||||
mLocalRotation.rot[0]=0;
|
|
||||||
mLocalRotation.rot[1]=0;
|
|
||||||
mLocalRotation.rot[2]=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefData::RefData (const ESM::ObjectState& objectState)
|
RefData::RefData (const ESM::ObjectState& objectState)
|
||||||
|
@ -62,8 +57,6 @@ namespace MWWorld
|
||||||
mCustomData (0),
|
mCustomData (0),
|
||||||
mChanged(true) // Loading from a savegame -> assume changed
|
mChanged(true) // Loading from a savegame -> assume changed
|
||||||
{
|
{
|
||||||
for (int i=0; i<3; ++i)
|
|
||||||
mLocalRotation.rot[i] = objectState.mLocalRotation[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefData::RefData (const RefData& refData)
|
RefData::RefData (const RefData& refData)
|
||||||
|
@ -87,9 +80,6 @@ namespace MWWorld
|
||||||
objectState.mEnabled = mEnabled;
|
objectState.mEnabled = mEnabled;
|
||||||
objectState.mCount = mCount;
|
objectState.mCount = mCount;
|
||||||
objectState.mPosition = mPosition;
|
objectState.mPosition = mPosition;
|
||||||
|
|
||||||
for (int i=0; i<3; ++i)
|
|
||||||
objectState.mLocalRotation[i] = mLocalRotation.rot[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefData& RefData::operator= (const RefData& refData)
|
RefData& RefData::operator= (const RefData& refData)
|
||||||
|
@ -197,17 +187,6 @@ namespace MWWorld
|
||||||
return mPosition;
|
return mPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefData::setLocalRotation(const LocalRotation& rot)
|
|
||||||
{
|
|
||||||
mChanged = true;
|
|
||||||
mLocalRotation = rot;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LocalRotation& RefData::getLocalRotation()
|
|
||||||
{
|
|
||||||
return mLocalRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RefData::setCustomData (CustomData *data)
|
void RefData::setCustomData (CustomData *data)
|
||||||
{
|
{
|
||||||
mChanged = true; // We do not currently track CustomData, so assume anything with a CustomData is changed
|
mChanged = true; // We do not currently track CustomData, so assume anything with a CustomData is changed
|
||||||
|
|
|
@ -21,9 +21,6 @@ namespace ESM
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
struct LocalRotation{
|
|
||||||
float rot[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
class CustomData;
|
class CustomData;
|
||||||
|
|
||||||
|
@ -40,8 +37,6 @@ namespace MWWorld
|
||||||
|
|
||||||
ESM::Position mPosition;
|
ESM::Position mPosition;
|
||||||
|
|
||||||
LocalRotation mLocalRotation;
|
|
||||||
|
|
||||||
CustomData *mCustomData;
|
CustomData *mCustomData;
|
||||||
|
|
||||||
void copy (const RefData& refData);
|
void copy (const RefData& refData);
|
||||||
|
@ -110,9 +105,6 @@ namespace MWWorld
|
||||||
void setPosition (const ESM::Position& pos);
|
void setPosition (const ESM::Position& pos);
|
||||||
const ESM::Position& getPosition();
|
const ESM::Position& getPosition();
|
||||||
|
|
||||||
void setLocalRotation (const LocalRotation& rotation);
|
|
||||||
const LocalRotation& getLocalRotation();
|
|
||||||
|
|
||||||
void setCustomData (CustomData *data);
|
void setCustomData (CustomData *data);
|
||||||
///< Set custom data (potentially replacing old custom data). The ownership of \a data is
|
///< Set custom data (potentially replacing old custom data). The ownership of \a data is
|
||||||
/// transferred to this.
|
/// transferred to this.
|
||||||
|
|
|
@ -52,15 +52,7 @@ namespace
|
||||||
worldRotQuat = worldRotQuat * osg::Quat(ptr.getRefData().getPosition().rot[1], osg::Vec3(0,-1,0)) *
|
worldRotQuat = worldRotQuat * osg::Quat(ptr.getRefData().getPosition().rot[1], osg::Vec3(0,-1,0)) *
|
||||||
osg::Quat(ptr.getRefData().getPosition().rot[0], osg::Vec3(-1,0,0));
|
osg::Quat(ptr.getRefData().getPosition().rot[0], osg::Vec3(-1,0,0));
|
||||||
|
|
||||||
float x = ptr.getRefData().getLocalRotation().rot[0];
|
rendering.rotateObject(ptr, worldRotQuat);
|
||||||
float y = ptr.getRefData().getLocalRotation().rot[1];
|
|
||||||
float z = ptr.getRefData().getLocalRotation().rot[2];
|
|
||||||
|
|
||||||
osg::Quat rot(z, osg::Vec3(0,0,-1));
|
|
||||||
if (!ptr.getClass().isActor())
|
|
||||||
rot = rot * osg::Quat(y, osg::Vec3(0,-1,0)) * osg::Quat(x, osg::Vec3(-1,0,0));
|
|
||||||
|
|
||||||
rendering.rotateObject(ptr, rot * worldRotQuat);
|
|
||||||
physics.updateRotation(ptr);
|
physics.updateRotation(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1258,21 +1258,6 @@ namespace MWWorld
|
||||||
mWorldScene->updateObjectLocalRotation(ptr);
|
mWorldScene->updateObjectLocalRotation(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::localRotateObject (const Ptr& ptr, float x, float y, float z)
|
|
||||||
{
|
|
||||||
LocalRotation rot = ptr.getRefData().getLocalRotation();
|
|
||||||
rot.rot[0]=osg::DegreesToRadians(x);
|
|
||||||
rot.rot[1]=osg::DegreesToRadians(y);
|
|
||||||
rot.rot[2]=osg::DegreesToRadians(z);
|
|
||||||
|
|
||||||
ptr.getRefData().setLocalRotation(rot);
|
|
||||||
|
|
||||||
if (ptr.getRefData().getBaseNode() != 0)
|
|
||||||
{
|
|
||||||
mWorldScene->updateObjectLocalRotation(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void World::adjustPosition(const Ptr &ptr, bool force)
|
void World::adjustPosition(const Ptr &ptr, bool force)
|
||||||
{
|
{
|
||||||
ESM::Position pos (ptr.getRefData().getPosition());
|
ESM::Position pos (ptr.getRefData().getPosition());
|
||||||
|
@ -1829,11 +1814,6 @@ namespace MWWorld
|
||||||
object.getClass().copyToCell(object, *cell, pos);
|
object.getClass().copyToCell(object, *cell, pos);
|
||||||
|
|
||||||
// Reset some position values that could be uninitialized if this item came from a container
|
// Reset some position values that could be uninitialized if this item came from a container
|
||||||
LocalRotation localRotation;
|
|
||||||
localRotation.rot[0] = 0;
|
|
||||||
localRotation.rot[1] = 0;
|
|
||||||
localRotation.rot[2] = 0;
|
|
||||||
dropped.getRefData().setLocalRotation(localRotation);
|
|
||||||
dropped.getCellRef().setPosition(pos);
|
dropped.getCellRef().setPosition(pos);
|
||||||
dropped.getCellRef().unsetRefNum();
|
dropped.getCellRef().unsetRefNum();
|
||||||
|
|
||||||
|
|
|
@ -353,9 +353,6 @@ namespace MWWorld
|
||||||
/// \param adjust indicates rotation should be set or adjusted
|
/// \param adjust indicates rotation should be set or adjusted
|
||||||
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
|
virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false);
|
||||||
|
|
||||||
/// Local rotates object, uses degrees
|
|
||||||
virtual void localRotateObject (const Ptr& ptr, float x, float y, float z);
|
|
||||||
|
|
||||||
virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr, MWWorld::CellStore* cell, ESM::Position pos);
|
virtual MWWorld::Ptr safePlaceObject(const MWWorld::Ptr& ptr, MWWorld::CellStore* cell, ESM::Position pos);
|
||||||
///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
|
///< place an object in a "safe" location (ie not in the void, etc). Makes a copy of the Ptr.
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ void ESM::ObjectState::load (ESMReader &esm)
|
||||||
|
|
||||||
esm.getHNOT (mPosition, "POS_", 24);
|
esm.getHNOT (mPosition, "POS_", 24);
|
||||||
|
|
||||||
esm.getHNOT (mLocalRotation, "LROT", 12);
|
if (esm.isNextSub("LROT"))
|
||||||
|
esm.skipHSub(); // local rotation, no longer used
|
||||||
|
|
||||||
// obsolete
|
// obsolete
|
||||||
int unused;
|
int unused;
|
||||||
|
@ -51,10 +52,7 @@ void ESM::ObjectState::save (ESMWriter &esm, bool inInventory) const
|
||||||
esm.writeHNT ("COUN", mCount);
|
esm.writeHNT ("COUN", mCount);
|
||||||
|
|
||||||
if (!inInventory)
|
if (!inInventory)
|
||||||
{
|
|
||||||
esm.writeHNT ("POS_", mPosition, 24);
|
esm.writeHNT ("POS_", mPosition, 24);
|
||||||
esm.writeHNT ("LROT", mLocalRotation, 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mHasCustomState)
|
if (!mHasCustomState)
|
||||||
esm.writeHNT ("HCUS", false);
|
esm.writeHNT ("HCUS", false);
|
||||||
|
@ -70,7 +68,6 @@ void ESM::ObjectState::blank()
|
||||||
{
|
{
|
||||||
mPosition.pos[i] = 0;
|
mPosition.pos[i] = 0;
|
||||||
mPosition.rot[i] = 0;
|
mPosition.rot[i] = 0;
|
||||||
mLocalRotation[i] = 0;
|
|
||||||
}
|
}
|
||||||
mHasCustomState = true;
|
mHasCustomState = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ namespace ESM
|
||||||
unsigned char mEnabled;
|
unsigned char mEnabled;
|
||||||
int mCount;
|
int mCount;
|
||||||
ESM::Position mPosition;
|
ESM::Position mPosition;
|
||||||
float mLocalRotation[3];
|
|
||||||
|
|
||||||
// Is there any class-specific state following the ObjectState
|
// Is there any class-specific state following the ObjectState
|
||||||
bool mHasCustomState;
|
bool mHasCustomState;
|
||||||
|
|
Loading…
Reference in a new issue