Skip to content

Commit d6185c3

Browse files
committed
Revert "freecam: Smoothen camera movement"
This reverts commit 0f857bc.
1 parent 4ba66c7 commit d6185c3

File tree

1 file changed

+36
-92
lines changed

1 file changed

+36
-92
lines changed

[editor]/freecam/freecam.lua

Lines changed: 36 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ end
6464

6565
-- PRIVATE
6666

67-
local function freecamFrame (deltaTime)
68-
freecamMouseApply(deltaTime)
67+
local function freecamFrame ()
6968
-- work out an angle in radians based on the number of pixels the cursor has moved (ever)
7069
local cameraAngleX = rotX
7170
local cameraAngleY = rotY
@@ -218,103 +217,48 @@ local function freecamFrame (deltaTime)
218217
setCameraMatrix ( camPosX, camPosY, camPosZ, camTargetX, camTargetY, camTargetZ, 0, options.fov )
219218
end
220219

221-
-- Internal state (module-level)
222-
local mouseFrameDelay = 0 -- frames to ignore after cursor/window toggles
223-
local accumDX, accumDY = 0, 0 -- accumulated raw mouse deltas (pixels)
224-
local lastEventTick = 0
225-
local PI, RAD = math.pi, math.pi / 180
226-
227-
-- Tunables (adjust to taste)
228-
local RESUME_FRAMES = 5 -- frames to wait after cursor/window active
229-
local DEADZONE_PX = 0.15 -- ignore tiny jitters
230-
local MAX_EVENT_DELTA = 200 -- clamp a single event spike (px)
231-
local APPLY_K_60FPS = 0.42 -- how quickly to drain accumulator at 60fps (0..1)
232-
233-
-- Normalize angle to [-PI, PI]
234-
local function normPI(a)
235-
a = a % (2 * PI)
236-
if a > PI then
237-
a = a - 2 * PI
220+
local function freecamMouse (cX,cY,aX,aY)
221+
--ignore mouse movement if the cursor or MTA window is on
222+
--and do not resume it until at least 5 frames after it is toggled off
223+
--(prevents cursor mousemove data from reaching this handler)
224+
if isCursorShowing() or isMTAWindowActive() or (not isMTAWindowFocused()) then
225+
mouseFrameDelay = 5
226+
return
227+
elseif mouseFrameDelay > 0 then
228+
mouseFrameDelay = mouseFrameDelay - 1
229+
return
238230
end
239-
return a
240-
end
241-
242-
function freecamMouse(cX, cY, aX, aY)
243-
-- Gate input when the UI is up / focus lost
244-
if isCursorShowing() or isMTAWindowActive() or (not isMTAWindowFocused()) then
245-
mouseFrameDelay = RESUME_FRAMES
246-
accumDX, accumDY = 0, 0
247-
return
248-
elseif mouseFrameDelay > 0 then
249-
mouseFrameDelay = mouseFrameDelay - 1
250-
accumDX, accumDY = 0, 0
251-
return
252-
end
253231

254-
-- How far from screen center?
255-
local dx = (aX - width * 0.5)
256-
local dy = (aY - height * 0.5)
232+
-- how far have we moved the mouse from the screen center?
233+
aX = aX - width / 2
234+
aY = aY - height / 2
257235

258-
-- Optional invert
259-
if options.invertMouseLook then
260-
dy = -dy
261-
end
262-
263-
-- Deadzone + spike clamp
264-
if math.abs(dx) < DEADZONE_PX then
265-
dx = 0
266-
end
267-
if math.abs(dy) < DEADZONE_PX then
268-
dy = 0
269-
end
270-
if dx > MAX_EVENT_DELTA then
271-
dx = MAX_EVENT_DELTA
272-
elseif dx < -MAX_EVENT_DELTA then
273-
dx = -MAX_EVENT_DELTA
274-
end
275-
if dy > MAX_EVENT_DELTA then
276-
dy = MAX_EVENT_DELTA
277-
elseif dy < -MAX_EVENT_DELTA then
278-
dy = -MAX_EVENT_DELTA
236+
--invert the mouse look if specified
237+
if options.invertMouseLook then
238+
aY = -aY
279239
end
280240

281-
-- Accumulate; application to rot happens in freecamMouseApply() every frame
282-
accumDX = accumDX + dx
283-
accumDY = accumDY + dy
284-
lastEventTick = getTickCount()
285-
end
241+
rotX = rotX + aX * options.mouseSensitivity * 0.01745
242+
rotY = rotY - aY * options.mouseSensitivity * 0.01745
286243

287-
function freecamMouseApply(deltaTime)
288-
-- If UI pops up mid-frame, bail early
289-
if isCursorShowing() or isMTAWindowActive() or (not isMTAWindowFocused()) then
290-
mouseFrameDelay = RESUME_FRAMES
291-
accumDX, accumDY = 0, 0
292-
return
293-
end
244+
local PI = math.pi
245+
if rotX > PI then
246+
rotX = rotX - 2 * PI
247+
elseif rotX < -PI then
248+
rotX = rotX + 2 * PI
249+
end
294250

295-
-- Frame-rate–independent smoothing: convert APPLY_K_60FPS to current deltaTime
296-
-- factor = 1 - (1 - k)^(deltaTime * 60ms^-1)
297-
local factor = 1 - ((1 - APPLY_K_60FPS) ^ math.max(deltaTime / 16.666, 0.001))
298-
299-
-- Take a smooth chunk out of the accumulator
300-
local useDX = accumDX * factor
301-
local useDY = accumDY * factor
302-
accumDX = accumDX - useDX
303-
accumDY = accumDY - useDY
304-
305-
-- Convert pixels -> radians (sensitivity is in degrees/pixel)
306-
local rpp = (options.mouseSensitivity or 1) * RAD
307-
308-
-- Apply to camera (note Y is typically "pitch" and inverted vs screen Y)
309-
rotX = normPI(rotX + useDX * rpp)
310-
rotY = rotY - useDY * rpp
311-
312-
-- Clamp pitch to avoid gimbal lock / upside-down strafing
313-
local limit = PI / 2.05
314-
if rotY < -limit then
315-
rotY = -limit
316-
elseif rotY > limit then
317-
rotY = limit
251+
if rotY > PI then
252+
rotY = rotY - 2 * PI
253+
elseif rotY < -PI then
254+
rotY = rotY + 2 * PI
255+
end
256+
-- limit the camera to stop it going too far up or down - PI/2 is the limit, but we can't let it quite reach that or it will lock up
257+
-- and strafeing will break entirely as the camera loses any concept of what is 'up'
258+
if rotY < -PI / 2.05 then
259+
rotY = -PI / 2.05
260+
elseif rotY > PI / 2.05 then
261+
rotY = PI / 2.05
318262
end
319263
end
320264

0 commit comments

Comments
 (0)