Merge branch 'fix_get_angles_zyx' into 'master'

Fix getAnglesZYX (#7741)

Closes #7741

See merge request OpenMW/openmw!4199
pull/3236/head
psi29a 6 months ago
commit 664a844853

@ -241,7 +241,7 @@ namespace LuaUtil
return std::make_tuple(angles.x(), angles.z()); return std::make_tuple(angles.x(), angles.z());
}; };
transMType["getAnglesZYX"] = [](const TransformM& m) { transMType["getAnglesZYX"] = [](const TransformM& m) {
osg::Vec3f angles = Misc::toEulerAnglesXZ(m.mM); osg::Vec3f angles = Misc::toEulerAnglesZYX(m.mM);
return std::make_tuple(angles.z(), angles.y(), angles.x()); return std::make_tuple(angles.z(), angles.y(), angles.x());
}; };
@ -277,7 +277,7 @@ namespace LuaUtil
return std::make_tuple(angles.x(), angles.z()); return std::make_tuple(angles.x(), angles.z());
}; };
transQType["getAnglesZYX"] = [](const TransformQ& q) { transQType["getAnglesZYX"] = [](const TransformQ& q) {
osg::Vec3f angles = Misc::toEulerAnglesXZ(q.mQ); osg::Vec3f angles = Misc::toEulerAnglesZYX(q.mQ);
return std::make_tuple(angles.z(), angles.y(), angles.x()); return std::make_tuple(angles.z(), angles.y(), angles.x());
}; };

@ -13,18 +13,88 @@ types.Player.setControlSwitch(self, types.Player.CONTROL_SWITCH.Magic, false)
types.Player.setControlSwitch(self, types.Player.CONTROL_SWITCH.VanityMode, false) types.Player.setControlSwitch(self, types.Player.CONTROL_SWITCH.VanityMode, false)
types.Player.setControlSwitch(self, types.Player.CONTROL_SWITCH.ViewMode, false) types.Player.setControlSwitch(self, types.Player.CONTROL_SWITCH.ViewMode, false)
testing.registerLocalTest('playerRotation', local function rotate(object, targetPitch, targetYaw)
function()
local endTime = core.getSimulationTime() + 1 local endTime = core.getSimulationTime() + 1
while core.getSimulationTime() < endTime do while core.getSimulationTime() < endTime do
self.controls.jump = false object.controls.jump = false
self.controls.run = true object.controls.run = true
self.controls.movement = 0 object.controls.movement = 0
self.controls.sideMovement = 0 object.controls.sideMovement = 0
self.controls.yawChange = util.normalizeAngle(math.rad(90) - self.rotation:getYaw()) * 0.5 if targetPitch ~= nil then
object.controls.pitchChange = util.normalizeAngle(targetPitch - object.rotation:getPitch()) * 0.5
end
if targetYaw ~= nil then
object.controls.yawChange = util.normalizeAngle(targetYaw - object.rotation:getYaw()) * 0.5
end
coroutine.yield() coroutine.yield()
end end
testing.expectEqualWithDelta(self.rotation:getYaw(), math.rad(90), 0.05, 'Incorrect rotation') end
local function rotateByYaw(object, target)
rotate(object, nil, target)
end
local function rotateByPitch(object, target)
rotate(object, target, nil)
end
testing.registerLocalTest('playerYawRotation',
function()
local initialAlphaXZ, initialGammaXZ = self.rotation:getAnglesXZ()
local initialAlphaZYX, initialBetaZYX, initialGammaZYX = self.rotation:getAnglesZYX()
local targetYaw = math.rad(90)
rotateByYaw(self, targetYaw)
testing.expectEqualWithDelta(self.rotation:getYaw(), targetYaw, 0.05, 'Incorrect yaw rotation')
local alpha1, gamma1 = self.rotation:getAnglesXZ()
testing.expectEqualWithDelta(alpha1, initialAlphaXZ, 0.05, 'Alpha rotation in XZ convention should not change')
testing.expectEqualWithDelta(gamma1, targetYaw, 0.05, 'Incorrect gamma rotation in XZ convention')
local alpha2, beta2, gamma2 = self.rotation:getAnglesZYX()
testing.expectEqualWithDelta(alpha2, targetYaw, 0.05, 'Incorrect alpha rotation in ZYX convention')
testing.expectEqualWithDelta(beta2, initialBetaZYX, 0.05, 'Beta rotation in ZYX convention should not change')
testing.expectEqualWithDelta(gamma2, initialGammaZYX, 0.05, 'Gamma rotation in ZYX convention should not change')
end)
testing.registerLocalTest('playerPitchRotation',
function()
local initialAlphaXZ, initialGammaXZ = self.rotation:getAnglesXZ()
local initialAlphaZYX, initialBetaZYX, initialGammaZYX = self.rotation:getAnglesZYX()
local targetPitch = math.rad(90)
rotateByPitch(self, targetPitch)
testing.expectEqualWithDelta(self.rotation:getPitch(), targetPitch, 0.05, 'Incorrect pitch rotation')
local alpha1, gamma1 = self.rotation:getAnglesXZ()
testing.expectEqualWithDelta(alpha1, targetPitch, 0.05, 'Incorrect alpha rotation in XZ convention')
testing.expectEqualWithDelta(gamma1, initialGammaXZ, 0.05, 'Gamma rotation in XZ convention should not change')
local alpha2, beta2, gamma2 = self.rotation:getAnglesZYX()
testing.expectEqualWithDelta(alpha2, initialAlphaZYX, 0.05, 'Alpha rotation in ZYX convention should not change')
testing.expectEqualWithDelta(beta2, initialBetaZYX, 0.05, 'Beta rotation in ZYX convention should not change')
testing.expectEqualWithDelta(gamma2, targetPitch, 0.05, 'Incorrect gamma rotation in ZYX convention')
end)
testing.registerLocalTest('playerPitchAndYawRotation',
function()
local targetPitch = math.rad(-30)
local targetYaw = math.rad(-60)
rotate(self, targetPitch, targetYaw)
testing.expectEqualWithDelta(self.rotation:getPitch(), targetPitch, 0.05, 'Incorrect pitch rotation')
testing.expectEqualWithDelta(self.rotation:getYaw(), targetYaw, 0.05, 'Incorrect yaw rotation')
local alpha1, gamma1 = self.rotation:getAnglesXZ()
testing.expectEqualWithDelta(alpha1, targetPitch, 0.05, 'Incorrect alpha rotation in XZ convention')
testing.expectEqualWithDelta(gamma1, targetYaw, 0.05, 'Incorrect gamma rotation in XZ convention')
local alpha2, beta2, gamma2 = self.rotation:getAnglesZYX()
testing.expectEqualWithDelta(alpha2, math.rad(-56), 0.05, 'Incorrect alpha rotation in ZYX convention')
testing.expectEqualWithDelta(beta2, math.rad(-25), 0.05, 'Incorrect beta rotation in ZYX convention')
testing.expectEqualWithDelta(gamma2, math.rad(-16), 0.05, 'Incorrect gamma rotation in ZYX convention')
end) end)
testing.registerLocalTest('playerForwardRunning', testing.registerLocalTest('playerForwardRunning',

@ -44,7 +44,17 @@ local function testTeleport()
testing.expectEqualWithDelta(player.position.x, 100, 1, 'incorrect position after teleporting') testing.expectEqualWithDelta(player.position.x, 100, 1, 'incorrect position after teleporting')
testing.expectEqualWithDelta(player.position.y, 50, 1, 'incorrect position after teleporting') testing.expectEqualWithDelta(player.position.y, 50, 1, 'incorrect position after teleporting')
testing.expectEqualWithDelta(player.position.z, 500, 1, 'incorrect position after teleporting') testing.expectEqualWithDelta(player.position.z, 500, 1, 'incorrect position after teleporting')
testing.expectEqualWithDelta(player.rotation:getYaw(), math.rad(90), 0.05, 'incorrect rotation after teleporting') testing.expectEqualWithDelta(player.rotation:getYaw(), math.rad(90), 0.05, 'incorrect yaw rotation after teleporting')
testing.expectEqualWithDelta(player.rotation:getPitch(), math.rad(0), 0.05, 'incorrect pitch rotation after teleporting')
local rotationX1, rotationZ1 = player.rotation:getAnglesXZ()
testing.expectEqualWithDelta(rotationX1, math.rad(0), 0.05, 'incorrect x rotation from getAnglesXZ after teleporting')
testing.expectEqualWithDelta(rotationZ1, math.rad(90), 0.05, 'incorrect z rotation from getAnglesXZ after teleporting')
local rotationZ2, rotationY2, rotationX2 = player.rotation:getAnglesZYX()
testing.expectEqualWithDelta(rotationZ2, math.rad(90), 0.05, 'incorrect z rotation from getAnglesZYX after teleporting')
testing.expectEqualWithDelta(rotationY2, math.rad(0), 0.05, 'incorrect y rotation from getAnglesZYX after teleporting')
testing.expectEqualWithDelta(rotationX2, math.rad(0), 0.05, 'incorrect x rotation from getAnglesZYX after teleporting')
player:teleport('', player.position, {rotation=util.transform.rotateZ(math.rad(-90)), onGround=true}) player:teleport('', player.position, {rotation=util.transform.rotateZ(math.rad(-90)), onGround=true})
coroutine.yield() coroutine.yield()
@ -193,9 +203,17 @@ end
tests = { tests = {
{'timers', testTimers}, {'timers', testTimers},
{'playerRotation', function() {'rotating player with controls.yawChange should change rotation', function()
initPlayer()
testing.runLocalTest(player, 'playerYawRotation')
end},
{'rotating player with controls.pitchChange should change rotation', function()
initPlayer()
testing.runLocalTest(player, 'playerPitchRotation')
end},
{'rotating player with controls.pitchChange and controls.yawChange should change rotation', function()
initPlayer() initPlayer()
testing.runLocalTest(player, 'playerRotation') testing.runLocalTest(player, 'playerPitchAndYawRotation')
end}, end},
{'playerForwardRunning', function() {'playerForwardRunning', function()
initPlayer() initPlayer()

Loading…
Cancel
Save