mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-27 05:10:26 +00:00
Addition camera features: move360, pov_auto_switch, slow_view_change
This commit is contained in:
parent
3fb470dcce
commit
1ca0a3a555
6 changed files with 169 additions and 8 deletions
|
@ -26,6 +26,8 @@ set(BUILTIN_DATA_FILES
|
||||||
scripts/omw/camera/head_bobbing.lua
|
scripts/omw/camera/head_bobbing.lua
|
||||||
scripts/omw/camera/third_person.lua
|
scripts/omw/camera/third_person.lua
|
||||||
scripts/omw/camera/settings.lua
|
scripts/omw/camera/settings.lua
|
||||||
|
scripts/omw/camera/move360.lua
|
||||||
|
scripts/omw/camera/first_person_auto_switch.lua
|
||||||
scripts/omw/console/player.lua
|
scripts/omw/console/player.lua
|
||||||
scripts/omw/console/global.lua
|
scripts/omw/console/global.lua
|
||||||
scripts/omw/console/local.lua
|
scripts/omw/console/local.lua
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Camera: "Camera"
|
Camera: "OpenMW Camera"
|
||||||
settingsPageDescription: "OpenMW camera settings"
|
settingsPageDescription: "OpenMW Camera settings"
|
||||||
|
|
||||||
thirdPersonSettings: "Third person mode"
|
thirdPersonSettings: "Third person mode"
|
||||||
|
|
||||||
|
@ -42,6 +42,19 @@ ignoreNC: "Ignore 'No Collision' flag"
|
||||||
ignoreNCDescription: >
|
ignoreNCDescription: >
|
||||||
Prevents camera from clipping through the objects with the NC (No Collision) NIF flag.
|
Prevents camera from clipping through the objects with the NC (No Collision) NIF flag.
|
||||||
|
|
||||||
|
move360: "Move 360"
|
||||||
|
move360Description: >
|
||||||
|
When without weapon in hands the character rotates to the direction of movement. I.e. looks to the camera when run backwards.
|
||||||
|
|
||||||
|
move360TurnSpeed: "Move 360 turning speed"
|
||||||
|
move360TurnSpeedDescription: A multiplier for the turning speed (5.0 by default)
|
||||||
|
|
||||||
|
slowViewChange: "Smooth view change"
|
||||||
|
slowViewChangeDescription: "Makes switching from 1st person to 3rd person view not instant."
|
||||||
|
|
||||||
|
povAutoSwitch: "First person auto switch"
|
||||||
|
povAutoSwitchDescription: "Auto switch to 1st person view if there is an obstacle right behind the player."
|
||||||
|
|
||||||
|
|
||||||
headBobbingSettings: "Head bobbing in first person view"
|
headBobbingSettings: "Head bobbing in first person view"
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,14 @@ local Actor = require('openmw.types').Actor
|
||||||
local settings = require('scripts.omw.camera.settings').thirdPerson
|
local settings = require('scripts.omw.camera.settings').thirdPerson
|
||||||
local head_bobbing = require('scripts.omw.camera.head_bobbing')
|
local head_bobbing = require('scripts.omw.camera.head_bobbing')
|
||||||
local third_person = require('scripts.omw.camera.third_person')
|
local third_person = require('scripts.omw.camera.third_person')
|
||||||
|
local pov_auto_switch = require('scripts.omw.camera.first_person_auto_switch')
|
||||||
|
local move360 = require('scripts.omw.camera.move360')
|
||||||
|
|
||||||
local MODE = camera.MODE
|
local MODE = camera.MODE
|
||||||
|
|
||||||
local previewIfStandStill = false
|
local previewIfStandStill = false
|
||||||
local showCrosshairInThirdPerson = false
|
local showCrosshairInThirdPerson = false
|
||||||
|
local slowViewChange = false
|
||||||
|
|
||||||
local function updateSettings()
|
local function updateSettings()
|
||||||
previewIfStandStill = settings:get('previewIfStandStill')
|
previewIfStandStill = settings:get('previewIfStandStill')
|
||||||
|
@ -27,6 +30,10 @@ local function updateSettings()
|
||||||
collisionType = util.bitOr(collisionType, nearby.COLLISION_TYPE.VisualOnly)
|
collisionType = util.bitOr(collisionType, nearby.COLLISION_TYPE.VisualOnly)
|
||||||
end
|
end
|
||||||
camera.setCollisionType(collisionType)
|
camera.setCollisionType(collisionType)
|
||||||
|
move360.enabled = settings:get('move360')
|
||||||
|
move360.turnSpeed = settings:get('move360TurnSpeed')
|
||||||
|
pov_auto_switch.enabled = settings:get('povAutoSwitch')
|
||||||
|
slowViewChange = settings:get('slowViewChange')
|
||||||
end
|
end
|
||||||
|
|
||||||
local primaryMode
|
local primaryMode
|
||||||
|
@ -167,6 +174,7 @@ local function onUpdate(dt)
|
||||||
camera.setExtraRoll(0)
|
camera.setExtraRoll(0)
|
||||||
camera.setFirstPersonOffset(util.vector3(0, 0, 0))
|
camera.setFirstPersonOffset(util.vector3(0, 0, 0))
|
||||||
updateSmoothedSpeed(dt)
|
updateSmoothedSpeed(dt)
|
||||||
|
pov_auto_switch.onUpdate(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onFrame(dt)
|
local function onFrame(dt)
|
||||||
|
@ -188,6 +196,12 @@ local function onFrame(dt)
|
||||||
applyControllerZoom(dt)
|
applyControllerZoom(dt)
|
||||||
third_person.update(dt, smoothedSpeed)
|
third_person.update(dt, smoothedSpeed)
|
||||||
if noHeadBobbing == 0 then head_bobbing.update(dt, smoothedSpeed) end
|
if noHeadBobbing == 0 then head_bobbing.update(dt, smoothedSpeed) end
|
||||||
|
if slowViewChange then
|
||||||
|
local maxIncrease = dt * (100 + third_person.baseDistance)
|
||||||
|
camera.setPreferredThirdPersonDistance(
|
||||||
|
math.min(camera.getThirdPersonDistance() + maxIncrease, third_person.preferredDistance))
|
||||||
|
end
|
||||||
|
move360.onFrame(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -255,6 +269,7 @@ return {
|
||||||
elseif action == input.ACTION.ZoomOut then
|
elseif action == input.ACTION.ZoomOut then
|
||||||
zoom(-10)
|
zoom(-10)
|
||||||
end
|
end
|
||||||
|
move360.onInputAction(action)
|
||||||
end,
|
end,
|
||||||
onActive = init,
|
onActive = init,
|
||||||
onLoad = function(data)
|
onLoad = function(data)
|
||||||
|
@ -265,4 +280,3 @@ return {
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
files/data/scripts/omw/camera/first_person_auto_switch.lua
Normal file
52
files/data/scripts/omw/camera/first_person_auto_switch.lua
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
local camera = require('openmw.camera')
|
||||||
|
local util = require('openmw.util')
|
||||||
|
local nearby = require('openmw.nearby')
|
||||||
|
local self = require('openmw.self')
|
||||||
|
|
||||||
|
local forcedFirstPerson = false
|
||||||
|
local limitSwitch = 40
|
||||||
|
local limitReturn = 65
|
||||||
|
|
||||||
|
local rayOptions = {collisionType = nearby.COLLISION_TYPE.Default - nearby.COLLISION_TYPE.Actor}
|
||||||
|
local function castRayBackward()
|
||||||
|
local from = camera.getTrackedPosition()
|
||||||
|
local orient = util.transform.rotateZ(camera.getYaw()) * util.transform.rotateX(camera.getPitch())
|
||||||
|
local resLeft = nearby.castRay(from, from + orient * util.vector3(-30, -limitReturn, 0), rayOptions)
|
||||||
|
local resRight = nearby.castRay(from, from + orient * util.vector3(30, -limitReturn, 0), rayOptions)
|
||||||
|
local distLeft = limitReturn + 1
|
||||||
|
local distRight = limitReturn + 1
|
||||||
|
if resLeft.hit then distLeft = (resLeft.hitPos - from):length() end
|
||||||
|
if resRight.hit then distRight = (resRight.hitPos - from):length() end
|
||||||
|
return math.min(distLeft, distRight)
|
||||||
|
end
|
||||||
|
|
||||||
|
local M = {
|
||||||
|
enabled = false,
|
||||||
|
}
|
||||||
|
|
||||||
|
function M.onUpdate(dt)
|
||||||
|
if camera.getMode() ~= camera.MODE.FirstPerson then forcedFirstPerson = false end
|
||||||
|
if not M.enabled then
|
||||||
|
if forcedFirstPerson then
|
||||||
|
camera.setMode(camera.MODE.ThirdPerson, false)
|
||||||
|
forcedFirstPerson = false
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if camera.getMode() == camera.MODE.ThirdPerson and camera.getThirdPersonDistance() < limitSwitch
|
||||||
|
and math.abs(util.normalizeAngle(camera.getYaw() - self.rotation.z)) < math.rad(10) then
|
||||||
|
if castRayBackward() <= limitSwitch then
|
||||||
|
camera.setMode(camera.MODE.FirstPerson, true)
|
||||||
|
forcedFirstPerson = true
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if forcedFirstPerson then
|
||||||
|
if castRayBackward() > limitReturn then
|
||||||
|
camera.setMode(camera.MODE.ThirdPerson, false)
|
||||||
|
forcedFirstPerson = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
73
files/data/scripts/omw/camera/move360.lua
Normal file
73
files/data/scripts/omw/camera/move360.lua
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
local core = require('openmw.core')
|
||||||
|
local camera = require('openmw.camera')
|
||||||
|
local input = require('openmw.input')
|
||||||
|
local self = require('openmw.self')
|
||||||
|
local util = require('openmw.util')
|
||||||
|
local I = require('openmw.interfaces')
|
||||||
|
|
||||||
|
local Actor = require('openmw.types').Actor
|
||||||
|
|
||||||
|
local MODE = camera.MODE
|
||||||
|
|
||||||
|
local active = false
|
||||||
|
|
||||||
|
local M = {
|
||||||
|
enabled = false,
|
||||||
|
turnSpeed = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function turnOn()
|
||||||
|
I.Camera.disableStandingPreview()
|
||||||
|
active = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function turnOff()
|
||||||
|
I.Camera.enableStandingPreview()
|
||||||
|
active = false
|
||||||
|
if camera.getMode() == MODE.Preview then
|
||||||
|
camera.setMode(MODE.ThirdPerson)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.onFrame(dt)
|
||||||
|
if core.isWorldPaused() then return end
|
||||||
|
local newActive = M.enabled and Actor.stance(self) == Actor.STANCE.Nothing
|
||||||
|
if newActive and not active then
|
||||||
|
turnOn()
|
||||||
|
elseif not newActive and active then
|
||||||
|
turnOff()
|
||||||
|
end
|
||||||
|
if not active then return end
|
||||||
|
if camera.getMode() == MODE.Static then return end
|
||||||
|
if camera.getMode() == MODE.ThirdPerson then camera.setMode(MODE.Preview) end
|
||||||
|
if camera.getMode() == MODE.Preview and not input.isActionPressed(input.ACTION.TogglePOV) then
|
||||||
|
camera.showCrosshair(camera.getFocalPreferredOffset():length() > 5)
|
||||||
|
local move = util.vector2(self.controls.sideMovement, self.controls.movement)
|
||||||
|
local yawDelta = camera.getYaw() - self.rotation.z
|
||||||
|
move = move:rotate(-yawDelta)
|
||||||
|
self.controls.sideMovement = move.x
|
||||||
|
self.controls.movement = move.y
|
||||||
|
self.controls.pitchChange = camera.getPitch() * math.cos(yawDelta) - self.rotation.x
|
||||||
|
if move:length() > 0.05 then
|
||||||
|
local delta = math.atan2(move.x, move.y)
|
||||||
|
local maxDelta = math.max(delta, 1) * M.turnSpeed * dt
|
||||||
|
self.controls.yawChange = util.clamp(delta, -maxDelta, maxDelta)
|
||||||
|
else
|
||||||
|
self.controls.yawChange = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.onInputAction(action)
|
||||||
|
if not active or core.isWorldPaused() then return end
|
||||||
|
if action == input.ACTION.ZoomIn and camera.getMode() == MODE.Preview
|
||||||
|
and I.Camera.getBaseThirdPersonDistance() == 30 then
|
||||||
|
self.controls.yawChange = camera.getYaw() - self.rotation.z
|
||||||
|
camera.setMode(MODE.FirstPerson)
|
||||||
|
elseif action == input.ACTION.ZoomOut and camera.getMode() == MODE.FirstPerson then
|
||||||
|
camera.setMode(MODE.Preview)
|
||||||
|
I.Camera.setBaseThirdPersonDistance(30)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
|
@ -48,6 +48,10 @@ I.Settings.registerGroup({
|
||||||
boolSetting('', 'previewIfStandStill', true),
|
boolSetting('', 'previewIfStandStill', true),
|
||||||
boolSetting('', 'deferredPreviewRotation', true),
|
boolSetting('', 'deferredPreviewRotation', true),
|
||||||
boolSetting('', 'ignoreNC', true),
|
boolSetting('', 'ignoreNC', true),
|
||||||
|
boolSetting('', 'move360', false),
|
||||||
|
floatSetting('', 'move360TurnSpeed', 5),
|
||||||
|
boolSetting('', 'slowViewChange', false),
|
||||||
|
boolSetting('', 'povAutoSwitch', false),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -72,11 +76,14 @@ local settings = {
|
||||||
}
|
}
|
||||||
|
|
||||||
local function updateViewOverShoulderDisabled()
|
local function updateViewOverShoulderDisabled()
|
||||||
local disabled = not settings.thirdPerson:get('viewOverShoulder')
|
local shoulderDisabled = not settings.thirdPerson:get('viewOverShoulder')
|
||||||
I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetX', {disabled = disabled})
|
I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetX', {disabled = shoulderDisabled})
|
||||||
I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetY', {disabled = disabled})
|
I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetY', {disabled = shoulderDisabled})
|
||||||
I.Settings.updateRendererArgument(thirdPersonGroup, 'autoSwitchShoulder', {disabled = disabled})
|
I.Settings.updateRendererArgument(thirdPersonGroup, 'autoSwitchShoulder', {disabled = shoulderDisabled})
|
||||||
I.Settings.updateRendererArgument(thirdPersonGroup, 'zoomOutWhenMoveCoef', {disabled = disabled})
|
I.Settings.updateRendererArgument(thirdPersonGroup, 'zoomOutWhenMoveCoef', {disabled = shoulderDisabled})
|
||||||
|
|
||||||
|
local move360Disabled = not settings.thirdPerson:get('move360')
|
||||||
|
I.Settings.updateRendererArgument(thirdPersonGroup, 'move360TurnSpeed', {disabled = move360Disabled})
|
||||||
end
|
end
|
||||||
|
|
||||||
local function updateHeadBobbingDisabled()
|
local function updateHeadBobbingDisabled()
|
||||||
|
|
Loading…
Reference in a new issue