|
|
|
@ -84,21 +84,27 @@ namespace MWScript
|
|
|
|
|
Interpreter::Type_Float angle = runtime[0].mFloat;
|
|
|
|
|
runtime.pop();
|
|
|
|
|
|
|
|
|
|
float ax = Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees();
|
|
|
|
|
float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees();
|
|
|
|
|
float az = Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees();
|
|
|
|
|
float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees();
|
|
|
|
|
float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees();
|
|
|
|
|
float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees();
|
|
|
|
|
|
|
|
|
|
float *objRot = ptr.getRefData().getPosition().rot;
|
|
|
|
|
|
|
|
|
|
float lx = Ogre::Radian(objRot[0]).valueDegrees();
|
|
|
|
|
float ly = Ogre::Radian(objRot[1]).valueDegrees();
|
|
|
|
|
float lz = Ogre::Radian(objRot[2]).valueDegrees();
|
|
|
|
|
|
|
|
|
|
if (axis == "x")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az);
|
|
|
|
|
MWBase::Environment::get().getWorld()->localRotateObject(ptr,angle-lx,ay,az);
|
|
|
|
|
}
|
|
|
|
|
else if (axis == "y")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az);
|
|
|
|
|
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,angle-ly,az);
|
|
|
|
|
}
|
|
|
|
|
else if (axis == "z")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle);
|
|
|
|
|
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay,angle-lz);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw std::runtime_error ("invalid ration axis: " + axis);
|
|
|
|
@ -148,15 +154,15 @@ namespace MWScript
|
|
|
|
|
|
|
|
|
|
if (axis=="x")
|
|
|
|
|
{
|
|
|
|
|
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees());
|
|
|
|
|
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees()+Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees());
|
|
|
|
|
}
|
|
|
|
|
else if (axis=="y")
|
|
|
|
|
{
|
|
|
|
|
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees());
|
|
|
|
|
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees()+Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees());
|
|
|
|
|
}
|
|
|
|
|
else if (axis=="z")
|
|
|
|
|
{
|
|
|
|
|
runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees());
|
|
|
|
|
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees()+Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw std::runtime_error ("invalid ration axis: " + axis);
|
|
|
|
@ -542,6 +548,78 @@ namespace MWScript
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class R>
|
|
|
|
|
class OpRotate : public Interpreter::Opcode0
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
virtual void execute (Interpreter::Runtime& runtime)
|
|
|
|
|
{
|
|
|
|
|
const MWWorld::Ptr& ptr = R()(runtime);
|
|
|
|
|
|
|
|
|
|
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
|
|
|
|
runtime.pop();
|
|
|
|
|
Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
|
|
|
|
|
runtime.pop();
|
|
|
|
|
|
|
|
|
|
float ax = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[0]).valueDegrees();
|
|
|
|
|
float ay = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[1]).valueDegrees();
|
|
|
|
|
float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees();
|
|
|
|
|
|
|
|
|
|
if (axis == "x")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax+rotation,ay,az);
|
|
|
|
|
}
|
|
|
|
|
else if (axis == "y")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay+rotation,az);
|
|
|
|
|
}
|
|
|
|
|
else if (axis == "z")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->localRotateObject(ptr,ax,ay,az+rotation);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw std::runtime_error ("invalid ration axis: " + axis);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class R>
|
|
|
|
|
class OpRotateWorld : public Interpreter::Opcode0
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
virtual void execute (Interpreter::Runtime& runtime)
|
|
|
|
|
{
|
|
|
|
|
MWWorld::Ptr ptr = R()(runtime);
|
|
|
|
|
|
|
|
|
|
std::string axis = runtime.getStringLiteral (runtime[0].mInteger);
|
|
|
|
|
runtime.pop();
|
|
|
|
|
Interpreter::Type_Float rotation = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
|
|
|
|
|
runtime.pop();
|
|
|
|
|
|
|
|
|
|
float *objRot = ptr.getRefData().getPosition().rot;
|
|
|
|
|
|
|
|
|
|
float ax = Ogre::Radian(objRot[0]).valueDegrees();
|
|
|
|
|
float ay = Ogre::Radian(objRot[1]).valueDegrees();
|
|
|
|
|
float az = Ogre::Radian(objRot[2]).valueDegrees();
|
|
|
|
|
|
|
|
|
|
if (axis == "x")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax+rotation,ay,az);
|
|
|
|
|
}
|
|
|
|
|
else if (axis == "y")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay+rotation,az);
|
|
|
|
|
}
|
|
|
|
|
else if (axis == "z")
|
|
|
|
|
{
|
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,az+rotation);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
throw std::runtime_error ("invalid rotation axis: " + axis);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const int opcodeSetScale = 0x2000164;
|
|
|
|
|
const int opcodeSetScaleExplicit = 0x2000165;
|
|
|
|
|
const int opcodeSetAngle = 0x2000166;
|
|
|
|
@ -568,6 +646,10 @@ namespace MWScript
|
|
|
|
|
const int opcodePlaceAtMeExplicit = 0x200019e;
|
|
|
|
|
const int opcodeModScale = 0x20001e3;
|
|
|
|
|
const int opcodeModScaleExplicit = 0x20001e4;
|
|
|
|
|
const int opcodeRotate = 0x20001ff;
|
|
|
|
|
const int opcodeRotateExplicit = 0x2000200;
|
|
|
|
|
const int opcodeRotateWorld = 0x2000201;
|
|
|
|
|
const int opcodeRotateWorldExplicit = 0x2000202;
|
|
|
|
|
|
|
|
|
|
void registerExtensions (Compiler::Extensions& extensions)
|
|
|
|
|
{
|
|
|
|
@ -585,6 +667,8 @@ namespace MWScript
|
|
|
|
|
extensions.registerInstruction("placeatpc","clfl",opcodePlaceAtPc);
|
|
|
|
|
extensions.registerInstruction("placeatme","clfl",opcodePlaceAtMe,opcodePlaceAtMeExplicit);
|
|
|
|
|
extensions.registerInstruction("modscale","f",opcodeModScale,opcodeModScaleExplicit);
|
|
|
|
|
extensions.registerInstruction("rotate","cf",opcodeRotate,opcodeRotateExplicit);
|
|
|
|
|
extensions.registerInstruction("rotateworld","cf",opcodeRotateWorld,opcodeRotateWorldExplicit);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
|
|
|
@ -614,6 +698,10 @@ namespace MWScript
|
|
|
|
|
interpreter.installSegment5(opcodePlaceAtMeExplicit,new OpPlaceAtMe<ExplicitRef>);
|
|
|
|
|
interpreter.installSegment5(opcodeModScale,new OpModScale<ImplicitRef>);
|
|
|
|
|
interpreter.installSegment5(opcodeModScaleExplicit,new OpModScale<ExplicitRef>);
|
|
|
|
|
interpreter.installSegment5(opcodeRotate,new OpRotate<ImplicitRef>);
|
|
|
|
|
interpreter.installSegment5(opcodeRotateExplicit,new OpRotate<ExplicitRef>);
|
|
|
|
|
interpreter.installSegment5(opcodeRotateWorld,new OpRotateWorld<ImplicitRef>);
|
|
|
|
|
interpreter.installSegment5(opcodeRotateWorldExplicit,new OpRotateWorld<ExplicitRef>);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|