@quenty/camera 14.20.3 → 14.20.4-canary.11a5dcf.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/package.json +17 -17
- package/src/Client/CameraStack.lua +27 -20
- package/src/Client/CameraStackService.lua +53 -35
- package/src/Client/CameraState.lua +8 -8
- package/src/Client/CameraUtils.lua +1 -1
- package/src/Client/CameraUtils.story.lua +5 -4
- package/src/Client/Controls/CameraControls.lua +107 -60
- package/src/Client/Controls/CameraGamepadInputUtils.lua +36 -21
- package/src/Client/Controls/GamepadRotateModel.lua +22 -12
- package/src/Client/Effects/CameraEffectUtils.lua +10 -1
- package/src/Client/Effects/CustomCameraEffect.lua +21 -5
- package/src/Client/Effects/DefaultCamera.lua +50 -32
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera.lua +7 -7
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera2.lua +11 -11
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera3.lua +57 -21
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera4.lua +17 -9
- package/src/Client/Effects/FadingCamera.lua +21 -5
- package/src/Client/Effects/HeartbeatCamera.lua +22 -9
- package/src/Client/Effects/ImpulseCamera.lua +44 -28
- package/src/Client/Effects/ImpulseCamera.story.lua +6 -6
- package/src/Client/Effects/InverseFader.lua +22 -6
- package/src/Client/Effects/LagPointCamera.lua +27 -8
- package/src/Client/Effects/OverrideDefaultCameraToo.lua +26 -4
- package/src/Client/Effects/PointCamera.lua +22 -6
- package/src/Client/Effects/PushCamera.lua +35 -14
- package/src/Client/Effects/RotatedCamera.lua +23 -9
- package/src/Client/Effects/SmoothPositionCamera.lua +22 -10
- package/src/Client/Effects/SmoothRotatedCamera.lua +52 -24
- package/src/Client/Effects/SmoothZoomedCamera.lua +31 -12
- package/src/Client/Effects/SummedCamera.lua +38 -16
- package/src/Client/Effects/TrackCamera.lua +24 -11
- package/src/Client/Effects/XZPlaneLockCamera.lua +21 -8
- package/src/Client/Effects/ZoomedCamera.lua +24 -7
- package/src/Client/Input/CameraInputUtils.lua +49 -13
- package/src/Client/Input/CameraTouchInputUtils.lua +17 -16
- package/src/Client/Utility/CameraFrame.lua +2 -2
- package/src/Client/Utility/CameraFrame.story.lua +21 -12
- package/src/Client/Utility/CameraStateTweener.lua +39 -19
- package/src/Client/Utility/FieldOfViewUtils.lua +1 -1
- package/test/scripts/Client/ClientMain.client.lua +1 -1
- package/test/scripts/Server/ServerMain.server.lua +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Hack to maintain default camera control by binding before and after the camera update cycle
|
|
3
4
|
This allows other cameras to build off of the "default" camera while maintaining the same Roblox control scheme.
|
|
@@ -8,31 +9,44 @@
|
|
|
8
9
|
|
|
9
10
|
local require = require(script.Parent.loader).load(script)
|
|
10
11
|
|
|
12
|
+
local HttpService = game:GetService("HttpService")
|
|
11
13
|
local RunService = game:GetService("RunService")
|
|
12
14
|
local Workspace = game:GetService("Workspace")
|
|
13
|
-
local HttpService = game:GetService("HttpService")
|
|
14
15
|
|
|
15
|
-
local CameraState = require("CameraState")
|
|
16
|
-
local SummedCamera = require("SummedCamera")
|
|
17
|
-
local Maid = require("Maid")
|
|
18
16
|
local CFrameUtils = require("CFrameUtils")
|
|
17
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
19
18
|
local CameraFrame = require("CameraFrame")
|
|
19
|
+
local CameraState = require("CameraState")
|
|
20
|
+
local Maid = require("Maid")
|
|
21
|
+
local Observable = require("Observable")
|
|
22
|
+
local Rx = require("Rx")
|
|
23
|
+
local SummedCamera = require("SummedCamera")
|
|
20
24
|
local ValueObject = require("ValueObject")
|
|
21
|
-
local _Rx = require("Rx")
|
|
22
|
-
local _Observable = require("Observable")
|
|
23
25
|
|
|
24
26
|
local EPSILON = 0.001
|
|
25
27
|
|
|
26
28
|
local DefaultCamera = {}
|
|
27
29
|
DefaultCamera.ClassName = "DefaultCamera"
|
|
28
30
|
|
|
31
|
+
export type DefaultCamera = typeof(setmetatable(
|
|
32
|
+
{} :: {
|
|
33
|
+
CameraState: CameraState.CameraState,
|
|
34
|
+
_key: string,
|
|
35
|
+
_maid: Maid.Maid,
|
|
36
|
+
_isFirstPerson: ValueObject.ValueObject<boolean>,
|
|
37
|
+
_cameraState: CameraState.CameraState,
|
|
38
|
+
_lastCameraFrame: CameraFrame.CameraFrame?,
|
|
39
|
+
},
|
|
40
|
+
{} :: typeof({ __index = DefaultCamera })
|
|
41
|
+
)) & CameraEffectUtils.CameraEffect
|
|
42
|
+
|
|
29
43
|
--[=[
|
|
30
44
|
Constructs a new DefaultCamera
|
|
31
45
|
|
|
32
46
|
@return DefaultCamera
|
|
33
47
|
]=]
|
|
34
|
-
function DefaultCamera.new()
|
|
35
|
-
local self = setmetatable({}, DefaultCamera)
|
|
48
|
+
function DefaultCamera.new(): DefaultCamera
|
|
49
|
+
local self: DefaultCamera = setmetatable({} :: any, DefaultCamera)
|
|
36
50
|
|
|
37
51
|
self._key = HttpService:GenerateGUID(false)
|
|
38
52
|
self._maid = Maid.new()
|
|
@@ -43,7 +57,7 @@ function DefaultCamera.new()
|
|
|
43
57
|
return self
|
|
44
58
|
end
|
|
45
59
|
|
|
46
|
-
function DefaultCamera
|
|
60
|
+
function DefaultCamera.__add(self: DefaultCamera, other: CameraEffectUtils.CameraEffect)
|
|
47
61
|
return SummedCamera.new(self, other)
|
|
48
62
|
end
|
|
49
63
|
|
|
@@ -51,7 +65,7 @@ end
|
|
|
51
65
|
Overrides the global field of view in the cached camera state
|
|
52
66
|
@param fieldOfView number
|
|
53
67
|
]=]
|
|
54
|
-
function DefaultCamera
|
|
68
|
+
function DefaultCamera.SetRobloxFieldOfView(self: DefaultCamera, fieldOfView: number)
|
|
55
69
|
self._cameraState.FieldOfView = fieldOfView
|
|
56
70
|
end
|
|
57
71
|
|
|
@@ -63,7 +77,7 @@ DefaultCamera.OverrideGlobalFieldOfView = DefaultCamera.SetRobloxFieldOfView
|
|
|
63
77
|
|
|
64
78
|
@param cameraState CameraState
|
|
65
79
|
]=]
|
|
66
|
-
function DefaultCamera
|
|
80
|
+
function DefaultCamera.SetRobloxCameraState(self: DefaultCamera, cameraState: CameraState.CameraState)
|
|
67
81
|
self._cameraState = cameraState or error("No CameraState")
|
|
68
82
|
end
|
|
69
83
|
|
|
@@ -75,7 +89,7 @@ DefaultCamera.OverrideCameraState = DefaultCamera.SetRobloxCameraState
|
|
|
75
89
|
|
|
76
90
|
@param cframe CFrame
|
|
77
91
|
]=]
|
|
78
|
-
function DefaultCamera
|
|
92
|
+
function DefaultCamera.SetRobloxCFrame(self: DefaultCamera, cframe: CFrame)
|
|
79
93
|
self._cameraState.CFrame = cframe
|
|
80
94
|
end
|
|
81
95
|
|
|
@@ -84,7 +98,7 @@ end
|
|
|
84
98
|
|
|
85
99
|
@return CameraState
|
|
86
100
|
]=]
|
|
87
|
-
function DefaultCamera
|
|
101
|
+
function DefaultCamera.GetRobloxCameraState(self: DefaultCamera): CameraState.CameraState
|
|
88
102
|
return self._cameraState
|
|
89
103
|
end
|
|
90
104
|
|
|
@@ -93,14 +107,14 @@ end
|
|
|
93
107
|
|
|
94
108
|
@param cameraFrame CameraState | nil
|
|
95
109
|
]=]
|
|
96
|
-
function DefaultCamera
|
|
110
|
+
function DefaultCamera.SetLastSetCameraFrame(self: DefaultCamera, cameraFrame: CameraFrame.CameraFrame)
|
|
97
111
|
self._lastCameraFrame = CameraFrame.new(cameraFrame.QFrame, cameraFrame.FieldOfView)
|
|
98
112
|
end
|
|
99
113
|
|
|
100
114
|
--[=[
|
|
101
115
|
Gets whether the Roblox camera is in first person
|
|
102
116
|
]=]
|
|
103
|
-
function DefaultCamera
|
|
117
|
+
function DefaultCamera.IsFirstPerson(self: DefaultCamera): boolean
|
|
104
118
|
return self._isFirstPerson.Value
|
|
105
119
|
end
|
|
106
120
|
|
|
@@ -109,7 +123,7 @@ end
|
|
|
109
123
|
|
|
110
124
|
@return Observable<boolean>
|
|
111
125
|
]=]
|
|
112
|
-
function DefaultCamera
|
|
126
|
+
function DefaultCamera.ObserveIsFirstPerson(self: DefaultCamera): Observable.Observable<boolean>
|
|
113
127
|
return self._isFirstPerson:Observe()
|
|
114
128
|
end
|
|
115
129
|
|
|
@@ -119,8 +133,8 @@ end
|
|
|
119
133
|
@param predicate ((inFirstPerson: boolean) -> boolean)?
|
|
120
134
|
@return Observable<Brio<boolean>>
|
|
121
135
|
]=]
|
|
122
|
-
function DefaultCamera
|
|
123
|
-
return self._isFirstPerson:
|
|
136
|
+
function DefaultCamera.ObserveIsFirstPersonBrio(self: DefaultCamera, predicate: Rx.Predicate<boolean>?)
|
|
137
|
+
return self._isFirstPerson:ObserveBrio(predicate)
|
|
124
138
|
end
|
|
125
139
|
|
|
126
140
|
--[=[
|
|
@@ -130,10 +144,10 @@ end
|
|
|
130
144
|
Be sure to call UnbindFromRenderStep when using this.
|
|
131
145
|
:::
|
|
132
146
|
]=]
|
|
133
|
-
function DefaultCamera
|
|
147
|
+
function DefaultCamera.BindToRenderStep(self: DefaultCamera): Maid.Maid
|
|
134
148
|
local maid = Maid.new()
|
|
135
149
|
|
|
136
|
-
RunService:BindToRenderStep("DefaultCamera_Preupdate" .. self._key, Enum.RenderPriority.Camera.Value-2, function()
|
|
150
|
+
RunService:BindToRenderStep("DefaultCamera_Preupdate" .. self._key, Enum.RenderPriority.Camera.Value - 2, function()
|
|
137
151
|
local camera = Workspace.CurrentCamera
|
|
138
152
|
|
|
139
153
|
if self._lastCameraFrame then
|
|
@@ -155,16 +169,20 @@ function DefaultCamera:BindToRenderStep()
|
|
|
155
169
|
self._cameraState:Set(camera)
|
|
156
170
|
end)
|
|
157
171
|
|
|
158
|
-
RunService:BindToRenderStep(
|
|
159
|
-
|
|
172
|
+
RunService:BindToRenderStep(
|
|
173
|
+
"DefaultCamera_PostUpdate" .. self._key,
|
|
174
|
+
Enum.RenderPriority.Camera.Value + 2,
|
|
175
|
+
function()
|
|
176
|
+
local camera = Workspace.CurrentCamera
|
|
160
177
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
178
|
+
-- Based upon Roblox's camera scripts
|
|
179
|
+
local distance = (camera.CFrame.Position - camera.Focus.Position).magnitude
|
|
180
|
+
self._isFirstPerson.Value = distance <= 0.75
|
|
164
181
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
182
|
+
-- Capture
|
|
183
|
+
self._cameraState = CameraState.new(camera)
|
|
184
|
+
end
|
|
185
|
+
)
|
|
168
186
|
|
|
169
187
|
maid:GiveTask(function()
|
|
170
188
|
self._isFirstPerson.Value = false
|
|
@@ -182,14 +200,14 @@ end
|
|
|
182
200
|
--[=[
|
|
183
201
|
Unbinds the camera from the RunService
|
|
184
202
|
]=]
|
|
185
|
-
function DefaultCamera
|
|
203
|
+
function DefaultCamera.UnbindFromRenderStep(self: DefaultCamera)
|
|
186
204
|
self._maid._binding = nil
|
|
187
205
|
end
|
|
188
206
|
|
|
189
207
|
--[=[
|
|
190
208
|
Cleans up the binding
|
|
191
209
|
]=]
|
|
192
|
-
function DefaultCamera
|
|
210
|
+
function DefaultCamera.Destroy(self: DefaultCamera)
|
|
193
211
|
self._maid:DoCleaning()
|
|
194
212
|
end
|
|
195
213
|
|
|
@@ -199,7 +217,7 @@ end
|
|
|
199
217
|
@prop CameraState CameraState
|
|
200
218
|
@within DefaultCamera
|
|
201
219
|
]=]
|
|
202
|
-
function DefaultCamera
|
|
220
|
+
function DefaultCamera.__index(self: DefaultCamera, index)
|
|
203
221
|
if index == "CameraState" then
|
|
204
222
|
return rawget(self, "_cameraState")
|
|
205
223
|
elseif index == "_maid" or index == "_lastCameraFrame" or index == "_key" then
|
|
@@ -209,4 +227,4 @@ function DefaultCamera:__index(index)
|
|
|
209
227
|
end
|
|
210
228
|
end
|
|
211
229
|
|
|
212
|
-
return DefaultCamera
|
|
230
|
+
return DefaultCamera
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
|
-
local Spring = require("Spring")
|
|
9
|
-
local SummedCamera = require("SummedCamera")
|
|
10
|
-
local SpringUtils = require("SpringUtils")
|
|
11
8
|
local CameraState = require("CameraState")
|
|
12
9
|
local CubicSplineUtils = require("CubicSplineUtils")
|
|
10
|
+
local Spring = require("Spring")
|
|
11
|
+
local SpringUtils = require("SpringUtils")
|
|
12
|
+
local SummedCamera = require("SummedCamera")
|
|
13
13
|
|
|
14
14
|
local FadeBetweenCamera = {}
|
|
15
15
|
FadeBetweenCamera.ClassName = "FadeBetweenCamera"
|
|
@@ -21,9 +21,9 @@ FadeBetweenCamera.ClassName = "FadeBetweenCamera"
|
|
|
21
21
|
]=]
|
|
22
22
|
function FadeBetweenCamera.new(cameraA, cameraB)
|
|
23
23
|
local self = setmetatable({
|
|
24
|
-
_spring = Spring.new(0)
|
|
25
|
-
CameraA = cameraA or error("No cameraA")
|
|
26
|
-
CameraB = cameraB or error("No cameraB")
|
|
24
|
+
_spring = Spring.new(0),
|
|
25
|
+
CameraA = cameraA or error("No cameraA"),
|
|
26
|
+
CameraB = cameraB or error("No cameraB"),
|
|
27
27
|
}, FadeBetweenCamera)
|
|
28
28
|
|
|
29
29
|
self.Damper = 1
|
|
@@ -127,4 +127,4 @@ function FadeBetweenCamera:__index(index)
|
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
return FadeBetweenCamera
|
|
130
|
+
return FadeBetweenCamera
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
|
-
local CubicSplineUtils = require("CubicSplineUtils")
|
|
8
7
|
local CameraState = require("CameraState")
|
|
8
|
+
local CubicSplineUtils = require("CubicSplineUtils")
|
|
9
9
|
|
|
10
10
|
local FadeBetweenCamera2 = {}
|
|
11
11
|
FadeBetweenCamera2.ClassName = "FadeBetweenCamera2"
|
|
@@ -18,13 +18,13 @@ FadeBetweenCamera2.__index = FadeBetweenCamera2
|
|
|
18
18
|
]=]
|
|
19
19
|
function FadeBetweenCamera2.new(cameraA, cameraB)
|
|
20
20
|
local self = setmetatable({
|
|
21
|
-
CameraA = cameraA or error("No cameraA")
|
|
22
|
-
CameraB = cameraB or error("No cameraB")
|
|
23
|
-
_state0 = cameraA.CameraState
|
|
24
|
-
_time0 = os.clock()
|
|
25
|
-
_target = 0
|
|
26
|
-
_position0 = 0
|
|
27
|
-
_speed = 15
|
|
21
|
+
CameraA = cameraA or error("No cameraA"),
|
|
22
|
+
CameraB = cameraB or error("No cameraB"),
|
|
23
|
+
_state0 = cameraA.CameraState,
|
|
24
|
+
_time0 = os.clock(),
|
|
25
|
+
_target = 0,
|
|
26
|
+
_position0 = 0,
|
|
27
|
+
_speed = 15,
|
|
28
28
|
}, FadeBetweenCamera2)
|
|
29
29
|
|
|
30
30
|
return self
|
|
@@ -138,9 +138,9 @@ function FadeBetweenCamera2:_computeDoneProportion(now)
|
|
|
138
138
|
return 1
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
local SPEED_CONSTANT = 0.5/15 -- 0.5 seconds is 15 speed in the other system
|
|
141
|
+
local SPEED_CONSTANT = 0.5 / 15 -- 0.5 seconds is 15 speed in the other system
|
|
142
142
|
|
|
143
|
-
return math.clamp(self._speed*(now - self._time0)*SPEED_CONSTANT/dist_to_travel, 0, 1)
|
|
143
|
+
return math.clamp(self._speed * (now - self._time0) * SPEED_CONSTANT / dist_to_travel, 0, 1)
|
|
144
144
|
end
|
|
145
145
|
|
|
146
|
-
return FadeBetweenCamera2
|
|
146
|
+
return FadeBetweenCamera2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Add another layer of effects that can be faded in/out
|
|
3
4
|
@class FadeBetweenCamera3
|
|
@@ -5,29 +6,51 @@
|
|
|
5
6
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
8
|
-
local
|
|
9
|
-
local SummedCamera = require("SummedCamera")
|
|
10
|
-
local SpringUtils = require("SpringUtils")
|
|
11
|
-
local QFrame = require("QFrame")
|
|
12
|
-
local FieldOfViewUtils = require("FieldOfViewUtils")
|
|
13
|
-
local CameraState = require("CameraState")
|
|
9
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
14
10
|
local CameraFrame = require("CameraFrame")
|
|
11
|
+
local CameraState = require("CameraState")
|
|
15
12
|
local CubicSplineUtils = require("CubicSplineUtils")
|
|
13
|
+
local FieldOfViewUtils = require("FieldOfViewUtils")
|
|
14
|
+
local QFrame = require("QFrame")
|
|
15
|
+
local Spring = require("Spring")
|
|
16
|
+
local SpringUtils = require("SpringUtils")
|
|
17
|
+
local SummedCamera = require("SummedCamera")
|
|
16
18
|
|
|
17
19
|
local FadeBetweenCamera3 = {}
|
|
18
20
|
FadeBetweenCamera3.ClassName = "FadeBetweenCamera3"
|
|
19
21
|
|
|
22
|
+
export type FadeBetweenCamera3 = typeof(setmetatable(
|
|
23
|
+
{} :: {
|
|
24
|
+
_spring: Spring.Spring<number>,
|
|
25
|
+
CameraA: CameraEffectUtils.CameraLike,
|
|
26
|
+
CameraB: CameraEffectUtils.CameraLike,
|
|
27
|
+
HasReachedTarget: boolean,
|
|
28
|
+
Damper: number,
|
|
29
|
+
Value: number,
|
|
30
|
+
Speed: number,
|
|
31
|
+
Velocity: number,
|
|
32
|
+
Target: number,
|
|
33
|
+
},
|
|
34
|
+
{} :: typeof({ __index = FadeBetweenCamera3 })
|
|
35
|
+
)) & CameraEffectUtils.CameraEffect
|
|
36
|
+
|
|
20
37
|
--[=[
|
|
21
38
|
@param cameraA CameraLike
|
|
22
39
|
@param cameraB CameraLike
|
|
23
40
|
@return FadeBetweenCamera3
|
|
24
41
|
]=]
|
|
25
|
-
function FadeBetweenCamera3.new(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
42
|
+
function FadeBetweenCamera3.new(
|
|
43
|
+
cameraA: CameraEffectUtils.CameraLike,
|
|
44
|
+
cameraB: CameraEffectUtils.CameraLike
|
|
45
|
+
): FadeBetweenCamera3
|
|
46
|
+
local self: FadeBetweenCamera3 = setmetatable(
|
|
47
|
+
{
|
|
48
|
+
_spring = Spring.new(0),
|
|
49
|
+
CameraA = cameraA or error("No cameraA"),
|
|
50
|
+
CameraB = cameraB or error("No cameraB"),
|
|
51
|
+
} :: any,
|
|
52
|
+
FadeBetweenCamera3
|
|
53
|
+
)
|
|
31
54
|
|
|
32
55
|
self.Damper = 1
|
|
33
56
|
self.Speed = 15
|
|
@@ -79,23 +102,36 @@ function FadeBetweenCamera3:__index(index)
|
|
|
79
102
|
|
|
80
103
|
local dist = (frameA.Position - frameB.Position).magnitude
|
|
81
104
|
|
|
82
|
-
local node0 = CubicSplineUtils.newSplineNode(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
105
|
+
local node0 = CubicSplineUtils.newSplineNode(
|
|
106
|
+
0,
|
|
107
|
+
frameA.Position,
|
|
108
|
+
stateA.CameraFrameDerivative.Position + frameA.CFrame.lookVector * dist * 0.3
|
|
109
|
+
)
|
|
110
|
+
local node1 = CubicSplineUtils.newSplineNode(
|
|
111
|
+
1,
|
|
112
|
+
frameB.Position,
|
|
113
|
+
stateB.CameraFrameDerivative.Position + frameB.CFrame.lookVector * dist * 0.3
|
|
114
|
+
)
|
|
86
115
|
|
|
87
116
|
-- We do the position this way because 0^-1 is undefined
|
|
88
117
|
--stateA.Position + (stateB.Position - stateA.Position)*t
|
|
89
118
|
local newNode = CubicSplineUtils.tweenSplineNodes(node0, node1, t)
|
|
90
|
-
local delta = (frameB*(frameA
|
|
119
|
+
local delta = (frameB * (frameA ^ -1))
|
|
91
120
|
|
|
92
121
|
local deltaQFrame = delta.QFrame
|
|
93
122
|
if deltaQFrame.W < 0 then
|
|
94
123
|
delta.QFrame = QFrame.new(
|
|
95
|
-
deltaQFrame.x,
|
|
124
|
+
deltaQFrame.x,
|
|
125
|
+
deltaQFrame.y,
|
|
126
|
+
deltaQFrame.z,
|
|
127
|
+
-deltaQFrame.W,
|
|
128
|
+
-deltaQFrame.X,
|
|
129
|
+
-deltaQFrame.Y,
|
|
130
|
+
-deltaQFrame.Z
|
|
131
|
+
)
|
|
96
132
|
end
|
|
97
133
|
|
|
98
|
-
local newState = delta^t*frameA
|
|
134
|
+
local newState = delta ^ t * frameA
|
|
99
135
|
newState.FieldOfView = FieldOfViewUtils.lerpInHeightSpace(frameA.FieldOfView, frameB.FieldOfView, t)
|
|
100
136
|
newState.Position = newNode.p
|
|
101
137
|
|
|
@@ -121,7 +157,7 @@ function FadeBetweenCamera3:__index(index)
|
|
|
121
157
|
if animating then
|
|
122
158
|
return self._spring.Velocity
|
|
123
159
|
else
|
|
124
|
-
return
|
|
160
|
+
return 0
|
|
125
161
|
end
|
|
126
162
|
elseif index == "HasReachedTarget" then
|
|
127
163
|
local animating = SpringUtils.animating(self._spring)
|
|
@@ -135,4 +171,4 @@ function FadeBetweenCamera3:__index(index)
|
|
|
135
171
|
end
|
|
136
172
|
end
|
|
137
173
|
|
|
138
|
-
return FadeBetweenCamera3
|
|
174
|
+
return FadeBetweenCamera3
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
|
-
local CubicSplineUtils = require("CubicSplineUtils")
|
|
8
7
|
local CameraState = require("CameraState")
|
|
8
|
+
local CubicSplineUtils = require("CubicSplineUtils")
|
|
9
9
|
local Spring = require("Spring")
|
|
10
10
|
local SpringUtils = require("SpringUtils")
|
|
11
11
|
|
|
@@ -20,11 +20,11 @@ FadeBetweenCamera4.__index = FadeBetweenCamera4
|
|
|
20
20
|
]=]
|
|
21
21
|
function FadeBetweenCamera4.new(cameraA, cameraB)
|
|
22
22
|
local self = setmetatable({
|
|
23
|
-
CameraA = cameraA or error("No cameraA")
|
|
24
|
-
CameraB = cameraB or error("No cameraB")
|
|
25
|
-
_spring = Spring.new()
|
|
26
|
-
_position0 = 0
|
|
27
|
-
_state0 = cameraA.CameraState
|
|
23
|
+
CameraA = cameraA or error("No cameraA"),
|
|
24
|
+
CameraB = cameraB or error("No cameraB"),
|
|
25
|
+
_spring = Spring.new(),
|
|
26
|
+
_position0 = 0,
|
|
27
|
+
_state0 = cameraA.CameraState,
|
|
28
28
|
}, FadeBetweenCamera4)
|
|
29
29
|
|
|
30
30
|
self._spring.s = 15
|
|
@@ -122,11 +122,19 @@ function FadeBetweenCamera4:_computeCameraState(position)
|
|
|
122
122
|
local a = self:_computeTargetState(0)
|
|
123
123
|
|
|
124
124
|
node0 = CubicSplineUtils.newSplineNode(0, a.CameraFrame, a.CameraFrameDerivative)
|
|
125
|
-
node1 = CubicSplineUtils.newSplineNode(
|
|
125
|
+
node1 = CubicSplineUtils.newSplineNode(
|
|
126
|
+
self._position0,
|
|
127
|
+
self._state0.CameraFrame,
|
|
128
|
+
self._state0.CameraFrameDerivative
|
|
129
|
+
)
|
|
126
130
|
else
|
|
127
131
|
local b = self:_computeTargetState(1)
|
|
128
132
|
|
|
129
|
-
node0 = CubicSplineUtils.newSplineNode(
|
|
133
|
+
node0 = CubicSplineUtils.newSplineNode(
|
|
134
|
+
self._position0,
|
|
135
|
+
self._state0.CameraFrame,
|
|
136
|
+
self._state0.CameraFrameDerivative
|
|
137
|
+
)
|
|
130
138
|
node1 = CubicSplineUtils.newSplineNode(1, b.CameraFrame, b.CameraFrameDerivative)
|
|
131
139
|
end
|
|
132
140
|
|
|
@@ -136,4 +144,4 @@ function FadeBetweenCamera4:_computeCameraState(position)
|
|
|
136
144
|
return newState, position
|
|
137
145
|
end
|
|
138
146
|
|
|
139
|
-
return FadeBetweenCamera4
|
|
147
|
+
return FadeBetweenCamera4
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Add another layer of effects that can be faded in/out
|
|
3
4
|
@class FadingCamera
|
|
@@ -5,17 +6,32 @@
|
|
|
5
6
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
9
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
10
|
+
local CameraState = require("CameraState")
|
|
8
11
|
local Spring = require("Spring")
|
|
9
12
|
local SummedCamera = require("SummedCamera")
|
|
10
13
|
|
|
11
14
|
local FadingCamera = {}
|
|
12
15
|
FadingCamera.ClassName = "FadingCamera"
|
|
13
16
|
|
|
17
|
+
export type FadingCamera = typeof(setmetatable(
|
|
18
|
+
{} :: {
|
|
19
|
+
CameraState: CameraState.CameraState,
|
|
20
|
+
Spring: Spring.Spring<number>,
|
|
21
|
+
Camera: CameraEffectUtils.CameraLike,
|
|
22
|
+
Damper: number,
|
|
23
|
+
Speed: number,
|
|
24
|
+
Target: number,
|
|
25
|
+
Value: number,
|
|
26
|
+
},
|
|
27
|
+
{} :: typeof({ __index = FadingCamera })
|
|
28
|
+
)) & CameraEffectUtils.CameraEffect
|
|
29
|
+
|
|
14
30
|
--[=[
|
|
15
31
|
@param camera CameraEffect
|
|
16
32
|
]=]
|
|
17
|
-
function FadingCamera.new(camera)
|
|
18
|
-
local self = setmetatable({}, FadingCamera)
|
|
33
|
+
function FadingCamera.new(camera: CameraEffectUtils.CameraLike): FadingCamera
|
|
34
|
+
local self: FadingCamera = setmetatable({} :: any, FadingCamera)
|
|
19
35
|
|
|
20
36
|
self.Spring = Spring.new(0)
|
|
21
37
|
|
|
@@ -33,7 +49,7 @@ end
|
|
|
33
49
|
function FadingCamera:__newindex(index, value)
|
|
34
50
|
if index == "Damper" then
|
|
35
51
|
self.Spring.Damper = value
|
|
36
|
-
elseif index == "
|
|
52
|
+
elseif index == "Value" then
|
|
37
53
|
self.Spring.Value = value
|
|
38
54
|
elseif index == "Speed" then
|
|
39
55
|
self.Spring.Speed = value
|
|
@@ -57,7 +73,7 @@ function FadingCamera:__index(index)
|
|
|
57
73
|
return (self.Camera.CameraState or self.Camera) * self.Spring.Value
|
|
58
74
|
elseif index == "Damper" then
|
|
59
75
|
return self.Spring.Damper
|
|
60
|
-
elseif index == "
|
|
76
|
+
elseif index == "Value" then
|
|
61
77
|
return self.Spring.Value
|
|
62
78
|
elseif index == "Speed" then
|
|
63
79
|
return self.Spring.Speed
|
|
@@ -72,4 +88,4 @@ function FadingCamera:__index(index)
|
|
|
72
88
|
end
|
|
73
89
|
end
|
|
74
90
|
|
|
75
|
-
return FadingCamera
|
|
91
|
+
return FadingCamera
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Update on heartbeat, must GC this camera state, unlike others. This
|
|
3
4
|
allows for camera effects to run on heartbeat and cache information once instead
|
|
@@ -10,17 +11,29 @@ local require = require(script.Parent.loader).load(script)
|
|
|
10
11
|
|
|
11
12
|
local RunService = game:GetService("RunService")
|
|
12
13
|
|
|
13
|
-
local
|
|
14
|
+
local CameraEffectUtils = require("CameraEffectUtils")
|
|
15
|
+
local CameraState = require("CameraState")
|
|
14
16
|
local Maid = require("Maid")
|
|
17
|
+
local SummedCamera = require("SummedCamera")
|
|
15
18
|
|
|
16
19
|
local HeartbeatCamera = {}
|
|
17
20
|
HeartbeatCamera.ClassName = "HeartbeatCamera"
|
|
18
21
|
HeartbeatCamera.ProfileName = "HeartbeatCamera"
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
export type HeartbeatCamera = typeof(setmetatable(
|
|
24
|
+
{} :: {
|
|
25
|
+
CameraState: CameraState.CameraState,
|
|
26
|
+
_maid: Maid.Maid,
|
|
27
|
+
_camera: CameraEffectUtils.CameraEffect,
|
|
28
|
+
_currentStateCache: CameraState.CameraState,
|
|
29
|
+
},
|
|
30
|
+
{} :: typeof({ __index = HeartbeatCamera })
|
|
31
|
+
)) & CameraEffectUtils.CameraEffect
|
|
32
|
+
|
|
33
|
+
function HeartbeatCamera.new(camera: CameraEffectUtils.CameraEffect): HeartbeatCamera
|
|
34
|
+
local self: HeartbeatCamera = setmetatable({} :: any, HeartbeatCamera)
|
|
22
35
|
|
|
23
|
-
self._camera = camera
|
|
36
|
+
self._camera = assert(camera, "No camera")
|
|
24
37
|
self._maid = Maid.new()
|
|
25
38
|
|
|
26
39
|
self._currentStateCache = self._camera.CameraState or error("Camera state returned null")
|
|
@@ -33,11 +46,11 @@ function HeartbeatCamera.new(camera)
|
|
|
33
46
|
return self
|
|
34
47
|
end
|
|
35
48
|
|
|
36
|
-
function HeartbeatCamera
|
|
49
|
+
function HeartbeatCamera.__add(self: HeartbeatCamera, other: CameraEffectUtils.CameraEffect): SummedCamera.SummedCamera
|
|
37
50
|
return SummedCamera.new(self, other)
|
|
38
51
|
end
|
|
39
52
|
|
|
40
|
-
function HeartbeatCamera
|
|
53
|
+
function HeartbeatCamera.ForceUpdateCache(self: HeartbeatCamera): ()
|
|
41
54
|
self._currentStateCache = self._camera.CameraState
|
|
42
55
|
end
|
|
43
56
|
|
|
@@ -47,7 +60,7 @@ end
|
|
|
47
60
|
@prop CameraState CameraState
|
|
48
61
|
@within HeartbeatCamera
|
|
49
62
|
]=]
|
|
50
|
-
function HeartbeatCamera
|
|
63
|
+
function HeartbeatCamera.__index(self: HeartbeatCamera, index)
|
|
51
64
|
if index == "CameraState" then
|
|
52
65
|
return self._currentStateCache
|
|
53
66
|
else
|
|
@@ -55,8 +68,8 @@ function HeartbeatCamera:__index(index)
|
|
|
55
68
|
end
|
|
56
69
|
end
|
|
57
70
|
|
|
58
|
-
function HeartbeatCamera
|
|
71
|
+
function HeartbeatCamera.Destroy(self: HeartbeatCamera)
|
|
59
72
|
self._maid:DoCleaning()
|
|
60
73
|
end
|
|
61
74
|
|
|
62
|
-
return HeartbeatCamera
|
|
75
|
+
return HeartbeatCamera
|