@quenty/camera 4.4.0 → 5.0.1-canary.238.2c4d310.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/README.md +2 -2
- package/package.json +14 -14
- package/src/Client/CameraStackService.lua +85 -27
- package/src/Client/CameraState.lua +23 -55
- package/src/Client/CameraUtils.lua +52 -4
- package/src/Client/CameraUtils.story.lua +3 -3
- package/src/Client/Controls/CameraControls.lua +7 -5
- package/src/Client/Controls/CameraGamepadInputUtils.lua +3 -3
- package/src/Client/Controls/GamepadRotateModel.lua +4 -2
- package/src/Client/Effects/CameraEffectUtils.lua +19 -0
- package/src/Client/Effects/CustomCameraEffect.lua +15 -4
- package/src/Client/Effects/DefaultCamera.lua +32 -3
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera.lua +15 -2
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera2.lua +14 -3
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera3.lua +15 -2
- package/src/Client/Effects/FadeBetween/FadeBetweenCamera4.lua +14 -3
- package/src/Client/Effects/FadingCamera.lua +13 -2
- package/src/Client/Effects/HeartbeatCamera.lua +13 -4
- package/src/Client/Effects/ImpulseCamera.lua +16 -3
- package/src/Client/Effects/InverseFader.lua +4 -2
- package/src/Client/Effects/LagPointCamera.lua +5 -3
- package/src/Client/Effects/PointCamera.lua +10 -6
- package/src/Client/Effects/PushCamera.lua +24 -5
- package/src/Client/Effects/RotatedCamera.lua +17 -5
- package/src/Client/Effects/SmoothPositionCamera.lua +4 -2
- package/src/Client/Effects/SmoothRotatedCamera.lua +7 -5
- package/src/Client/Effects/SmoothZoomedCamera.lua +7 -4
- package/src/Client/Effects/SummedCamera.lua +18 -10
- package/src/Client/Effects/TrackCamera.lua +27 -6
- package/src/Client/Effects/XZPlaneLockCamera.lua +4 -2
- package/src/Client/Effects/ZoomedCamera.lua +16 -10
- package/src/Client/Input/CameraInputUtils.lua +3 -3
- package/src/Client/Input/CameraTouchInputUtils.lua +13 -5
- package/src/Client/Utility/CameraFrame.lua +82 -4
- package/src/Client/Utility/CameraFrame.story.lua +3 -3
- package/src/Client/Utility/CameraStateTweener.lua +69 -8
- package/src/Client/Utility/FieldOfViewUtils.lua +34 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
--[=[
|
|
2
|
+
Represents a camera state at a certain point. Can perform math on this state.
|
|
3
|
+
@class CameraFrame
|
|
4
|
+
]=]
|
|
4
5
|
|
|
5
6
|
local require = require(script.Parent.loader).load(script)
|
|
6
7
|
|
|
@@ -10,6 +11,12 @@ local CameraFrame = {}
|
|
|
10
11
|
CameraFrame.ClassName = "CameraFrame"
|
|
11
12
|
CameraFrame.__index = CameraFrame
|
|
12
13
|
|
|
14
|
+
--[=[
|
|
15
|
+
Constructs a new CameraFrame
|
|
16
|
+
@param qFrame QFrame
|
|
17
|
+
@param fieldOfView number
|
|
18
|
+
@return CameraFrame
|
|
19
|
+
]=]
|
|
13
20
|
function CameraFrame.new(qFrame, fieldOfView)
|
|
14
21
|
local self = setmetatable({}, CameraFrame)
|
|
15
22
|
|
|
@@ -19,10 +26,40 @@ function CameraFrame.new(qFrame, fieldOfView)
|
|
|
19
26
|
return self
|
|
20
27
|
end
|
|
21
28
|
|
|
29
|
+
--[=[
|
|
30
|
+
Returns whether a value is a CameraFrame
|
|
31
|
+
@param value any
|
|
32
|
+
@return boolean
|
|
33
|
+
]=]
|
|
22
34
|
function CameraFrame.isCameraFrame(value)
|
|
23
35
|
return getmetatable(value) == CameraFrame
|
|
24
36
|
end
|
|
25
37
|
|
|
38
|
+
--[=[
|
|
39
|
+
@prop CFrame CFrame
|
|
40
|
+
@within CameraFrame
|
|
41
|
+
]=]
|
|
42
|
+
|
|
43
|
+
--[=[
|
|
44
|
+
@prop Position Vector3
|
|
45
|
+
@within CameraFrame
|
|
46
|
+
]=]
|
|
47
|
+
|
|
48
|
+
--[=[
|
|
49
|
+
@prop FieldOfView number
|
|
50
|
+
@within CameraFrame
|
|
51
|
+
]=]
|
|
52
|
+
|
|
53
|
+
--[=[
|
|
54
|
+
@prop QFrame QFrame
|
|
55
|
+
@within CameraFrame
|
|
56
|
+
]=]
|
|
57
|
+
|
|
58
|
+
--[=[
|
|
59
|
+
@prop QFrame QFrame
|
|
60
|
+
@within CameraFrame
|
|
61
|
+
]=]
|
|
62
|
+
|
|
26
63
|
function CameraFrame:__index(index)
|
|
27
64
|
if index == "CFrame" then
|
|
28
65
|
return QFrame.toCFrame(self.QFrame) or warn("[CameraFrame] - NaN")
|
|
@@ -48,13 +85,19 @@ function CameraFrame:__newindex(index, value)
|
|
|
48
85
|
|
|
49
86
|
local q = self.QFrame
|
|
50
87
|
rawset(self, "QFrame", QFrame.new(value.x, value.y, value.z, q.W, q.X, q.Y, q.Z))
|
|
51
|
-
elseif index == "FieldOfView" or index == "QFrame"
|
|
88
|
+
elseif index == "FieldOfView" or index == "QFrame" then
|
|
52
89
|
rawset(self, index, value)
|
|
53
90
|
else
|
|
54
91
|
error(("'%s' is not a valid index of CameraState"):format(tostring(index)))
|
|
55
92
|
end
|
|
56
93
|
end
|
|
57
94
|
|
|
95
|
+
--[=[
|
|
96
|
+
Linearly adds the camera frames together.
|
|
97
|
+
@param a CameraFrame
|
|
98
|
+
@param b CameraFrame
|
|
99
|
+
@return CameraFrame
|
|
100
|
+
]=]
|
|
58
101
|
function CameraFrame.__add(a, b)
|
|
59
102
|
assert(CameraFrame.isCameraFrame(a) and CameraFrame.isCameraFrame(b),
|
|
60
103
|
"CameraFrame + non-CameraFrame attempted")
|
|
@@ -62,6 +105,12 @@ function CameraFrame.__add(a, b)
|
|
|
62
105
|
return CameraFrame.new(a.QFrame + b.QFrame, a.FieldOfView + b.FieldOfView)
|
|
63
106
|
end
|
|
64
107
|
|
|
108
|
+
--[=[
|
|
109
|
+
Linearly subtractions the camera frames together.
|
|
110
|
+
@param a CameraFrame
|
|
111
|
+
@param b CameraFrame
|
|
112
|
+
@return CameraFrame
|
|
113
|
+
]=]
|
|
65
114
|
function CameraFrame.__sub(a, b)
|
|
66
115
|
assert(CameraFrame.isCameraFrame(a) and CameraFrame.isCameraFrame(b),
|
|
67
116
|
"CameraFrame - non-CameraFrame attempted")
|
|
@@ -69,10 +118,21 @@ function CameraFrame.__sub(a, b)
|
|
|
69
118
|
return CameraFrame.new(a.QFrame - b.QFrame, a.FieldOfView - b.FieldOfView)
|
|
70
119
|
end
|
|
71
120
|
|
|
121
|
+
--[=[
|
|
122
|
+
Inverts the QFrame and the field of view.
|
|
123
|
+
@param a CameraFrame
|
|
124
|
+
@return CameraFrame
|
|
125
|
+
]=]
|
|
72
126
|
function CameraFrame.__unm(a)
|
|
73
127
|
return CameraFrame.new(-a.QFrame, -a.FieldOfView)
|
|
74
128
|
end
|
|
75
129
|
|
|
130
|
+
--[=[
|
|
131
|
+
Multiplies the camera frame with the given value
|
|
132
|
+
@param a CameraFrame | number
|
|
133
|
+
@param b CameraFrame | number
|
|
134
|
+
@return CameraFrame
|
|
135
|
+
]=]
|
|
76
136
|
function CameraFrame.__mul(a, b)
|
|
77
137
|
if type(a) == "number" and CameraFrame.isCameraFrame(b) then
|
|
78
138
|
return CameraFrame.new(a*b.QFrame, a*b.FieldOfView)
|
|
@@ -85,6 +145,12 @@ function CameraFrame.__mul(a, b)
|
|
|
85
145
|
end
|
|
86
146
|
end
|
|
87
147
|
|
|
148
|
+
--[=[
|
|
149
|
+
Divides the camera frame by the value
|
|
150
|
+
@param a CameraFrame
|
|
151
|
+
@param b number
|
|
152
|
+
@return CameraFrame
|
|
153
|
+
]=]
|
|
88
154
|
function CameraFrame.__div(a, b)
|
|
89
155
|
if CameraFrame.isCameraFrame(a) and type(b) == "number" then
|
|
90
156
|
return CameraFrame.new(a.QFrame/b, a.FieldOfView/b)
|
|
@@ -93,6 +159,12 @@ function CameraFrame.__div(a, b)
|
|
|
93
159
|
end
|
|
94
160
|
end
|
|
95
161
|
|
|
162
|
+
--[=[
|
|
163
|
+
Takes the camera frame to the Nth power
|
|
164
|
+
@param a CameraFrame
|
|
165
|
+
@param b number
|
|
166
|
+
@return CameraFrame
|
|
167
|
+
]=]
|
|
96
168
|
function CameraFrame.__pow(a, b)
|
|
97
169
|
if CameraFrame.isCameraFrame(a) and type(b) == "number" then
|
|
98
170
|
return CameraFrame.new(a.QFrame^b, a.FieldOfView^b)
|
|
@@ -101,6 +173,12 @@ function CameraFrame.__pow(a, b)
|
|
|
101
173
|
end
|
|
102
174
|
end
|
|
103
175
|
|
|
176
|
+
--[=[
|
|
177
|
+
Compares the camera frame to make sure they're equal
|
|
178
|
+
@param a CameraFrame
|
|
179
|
+
@param b CameraFrame
|
|
180
|
+
@return boolean
|
|
181
|
+
]=]
|
|
104
182
|
function CameraFrame.__eq(a, b)
|
|
105
183
|
return a.QFrame == b.QFrame and a.FieldOfView == b.FieldOfView
|
|
106
184
|
end
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
--[=[
|
|
2
|
+
Makes transitions between states easier. Uses the `CameraStackService` to tween in and
|
|
3
|
+
out a new camera state Call `:Show()` and `:Hide()` to do so, and make sure to
|
|
4
|
+
call `:Destroy()` after usage
|
|
5
|
+
|
|
6
|
+
@class CameraStateTweener
|
|
7
|
+
]=]
|
|
5
8
|
|
|
6
9
|
local require = require(script.Parent.loader).load(script)
|
|
7
10
|
|
|
@@ -14,9 +17,14 @@ local CameraStateTweener = {}
|
|
|
14
17
|
CameraStateTweener.ClassName = "CameraStateTweener"
|
|
15
18
|
CameraStateTweener.__index = CameraStateTweener
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
--[=[
|
|
21
|
+
Constructs a new camera state tweener
|
|
22
|
+
|
|
23
|
+
@param serviceBag ServiceBag -- Service bag to find the CameraStackService in
|
|
24
|
+
@param cameraEffect CameraLike -- A camera effect
|
|
25
|
+
@param speed number? -- Speed that the camera tweener tweens at. Defaults to 20
|
|
26
|
+
@return CameraStateTweener
|
|
27
|
+
]=]
|
|
20
28
|
function CameraStateTweener.new(serviceBag, cameraEffect, speed)
|
|
21
29
|
local self = setmetatable({}, CameraStateTweener)
|
|
22
30
|
|
|
@@ -46,29 +54,51 @@ function CameraStateTweener.new(serviceBag, cameraEffect, speed)
|
|
|
46
54
|
return self
|
|
47
55
|
end
|
|
48
56
|
|
|
57
|
+
--[=[
|
|
58
|
+
Returns percent visible, from 0 to 1.
|
|
59
|
+
@return number
|
|
60
|
+
]=]
|
|
49
61
|
function CameraStateTweener:GetPercentVisible()
|
|
50
62
|
return self._fadeBetween.Value
|
|
51
63
|
end
|
|
52
64
|
|
|
65
|
+
--[=[
|
|
66
|
+
Shows the camera to fade in.
|
|
67
|
+
@param doNotAnimate? boolean -- Optional, defaults to animating
|
|
68
|
+
]=]
|
|
53
69
|
function CameraStateTweener:Show(doNotAnimate)
|
|
54
70
|
self:SetTarget(1, doNotAnimate)
|
|
55
71
|
end
|
|
56
72
|
|
|
73
|
+
--[=[
|
|
74
|
+
Hides the camera to fade in.
|
|
75
|
+
@param doNotAnimate? boolean -- Optional, defaults to animating
|
|
76
|
+
]=]
|
|
57
77
|
function CameraStateTweener:Hide(doNotAnimate)
|
|
58
78
|
self:SetTarget(0, doNotAnimate)
|
|
59
79
|
end
|
|
60
80
|
|
|
81
|
+
--[=[
|
|
82
|
+
Returns true if we're done hiding
|
|
83
|
+
@return boolean
|
|
84
|
+
]=]
|
|
61
85
|
function CameraStateTweener:IsFinishedHiding()
|
|
62
86
|
return self._fadeBetween.HasReachedTarget and self._fadeBetween.Target == 0
|
|
63
87
|
end
|
|
64
88
|
|
|
89
|
+
--[=[
|
|
90
|
+
Hides the tweener, and invokes the callback once the tweener
|
|
91
|
+
is finished hiding.
|
|
92
|
+
@param doNotAnimate boolean? -- Optional, defaults to animating
|
|
93
|
+
@param callback function
|
|
94
|
+
]=]
|
|
65
95
|
function CameraStateTweener:Finish(doNotAnimate, callback)
|
|
66
96
|
self:Hide(doNotAnimate)
|
|
67
97
|
|
|
68
98
|
if self._fadeBetween.HasReachedTarget then
|
|
69
99
|
callback()
|
|
70
100
|
else
|
|
71
|
-
spawn(function()
|
|
101
|
+
task.spawn(function()
|
|
72
102
|
while not self._fadeBetween.HasReachedTarget do
|
|
73
103
|
task.wait(0.05)
|
|
74
104
|
end
|
|
@@ -77,14 +107,28 @@ function CameraStateTweener:Finish(doNotAnimate, callback)
|
|
|
77
107
|
end
|
|
78
108
|
end
|
|
79
109
|
|
|
110
|
+
--[=[
|
|
111
|
+
Gets the current effect we're tweening
|
|
112
|
+
@return CameraEffect
|
|
113
|
+
]=]
|
|
80
114
|
function CameraStateTweener:GetCameraEffect()
|
|
81
115
|
return self._cameraEffect
|
|
82
116
|
end
|
|
83
117
|
|
|
118
|
+
--[=[
|
|
119
|
+
Gets the camera below this camera on the camera stack
|
|
120
|
+
@return CameraEffect
|
|
121
|
+
]=]
|
|
84
122
|
function CameraStateTweener:GetCameraBelow()
|
|
85
123
|
return self._cameraBelow
|
|
86
124
|
end
|
|
87
125
|
|
|
126
|
+
--[=[
|
|
127
|
+
Sets the percent visible target
|
|
128
|
+
@param target number
|
|
129
|
+
@param doNotAnimate boolean? -- Optional, defaults to animating
|
|
130
|
+
@return CameraStateTweener -- self
|
|
131
|
+
]=]
|
|
88
132
|
function CameraStateTweener:SetTarget(target, doNotAnimate)
|
|
89
133
|
self._fadeBetween.Target = target or error("No target")
|
|
90
134
|
if doNotAnimate then
|
|
@@ -94,12 +138,22 @@ function CameraStateTweener:SetTarget(target, doNotAnimate)
|
|
|
94
138
|
return self
|
|
95
139
|
end
|
|
96
140
|
|
|
141
|
+
--[=[
|
|
142
|
+
Sets the speed of transition
|
|
143
|
+
@param speed number
|
|
144
|
+
@return CameraStateTweener -- self
|
|
145
|
+
]=]
|
|
97
146
|
function CameraStateTweener:SetSpeed(speed)
|
|
98
147
|
self._fadeBetween.Speed = speed
|
|
99
148
|
|
|
100
149
|
return self
|
|
101
150
|
end
|
|
102
151
|
|
|
152
|
+
--[=[
|
|
153
|
+
Sets whether the tweener is visible
|
|
154
|
+
@param isVisible boolean
|
|
155
|
+
@param doNotAnimate boolean? -- Optional, defaults to animating
|
|
156
|
+
]=]
|
|
103
157
|
function CameraStateTweener:SetVisible(isVisible, doNotAnimate)
|
|
104
158
|
if isVisible then
|
|
105
159
|
self:Show(doNotAnimate)
|
|
@@ -108,10 +162,17 @@ function CameraStateTweener:SetVisible(isVisible, doNotAnimate)
|
|
|
108
162
|
end
|
|
109
163
|
end
|
|
110
164
|
|
|
165
|
+
--[=[
|
|
166
|
+
Retrieves the fading camera being used to interpolate.
|
|
167
|
+
@return CameraEffect
|
|
168
|
+
]=]
|
|
111
169
|
function CameraStateTweener:GetFader()
|
|
112
170
|
return self._fadeBetween
|
|
113
171
|
end
|
|
114
172
|
|
|
173
|
+
--[=[
|
|
174
|
+
Cleans up the fader, preventing any animation at all
|
|
175
|
+
]=]
|
|
115
176
|
function CameraStateTweener:Destroy()
|
|
116
177
|
self._maid:DoCleaning()
|
|
117
178
|
setmetatable(self, nil)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
--[=[
|
|
2
|
+
Utility functions involving field of view.
|
|
3
|
+
@class FieldOfViewUtils
|
|
4
|
+
]=]
|
|
4
5
|
|
|
5
6
|
local require = require(script.Parent.loader).load(script)
|
|
6
7
|
|
|
@@ -8,15 +9,30 @@ local Math = require("Math")
|
|
|
8
9
|
|
|
9
10
|
local FieldOfViewUtils = {}
|
|
10
11
|
|
|
12
|
+
--[=[
|
|
13
|
+
Converts field of view to height
|
|
14
|
+
@param fov number
|
|
15
|
+
@return number
|
|
16
|
+
]=]
|
|
11
17
|
function FieldOfViewUtils.fovToHeight(fov)
|
|
12
18
|
return 2*math.tan(math.rad(fov)/2)
|
|
13
19
|
end
|
|
14
20
|
|
|
21
|
+
--[=[
|
|
22
|
+
Converts height to field of view
|
|
23
|
+
@param height number
|
|
24
|
+
@return number
|
|
25
|
+
]=]
|
|
15
26
|
function FieldOfViewUtils.heightToFov(height)
|
|
16
27
|
return 2*math.deg(math.atan(height/2))
|
|
17
28
|
end
|
|
18
29
|
|
|
19
|
-
|
|
30
|
+
--[=[
|
|
31
|
+
Linear way to log a value so we don't get floating point errors or infinite values
|
|
32
|
+
@param height number
|
|
33
|
+
@param linearAt number
|
|
34
|
+
@return number
|
|
35
|
+
]=]
|
|
20
36
|
function FieldOfViewUtils.safeLog(height, linearAt)
|
|
21
37
|
if height < linearAt then
|
|
22
38
|
local slope = 1/linearAt
|
|
@@ -26,6 +42,13 @@ function FieldOfViewUtils.safeLog(height, linearAt)
|
|
|
26
42
|
end
|
|
27
43
|
end
|
|
28
44
|
|
|
45
|
+
--[=[
|
|
46
|
+
Linear way to exponentiate field of view so we don't get floating point errors or
|
|
47
|
+
infinite values.
|
|
48
|
+
@param logHeight number
|
|
49
|
+
@param linearAt number
|
|
50
|
+
@return number
|
|
51
|
+
]=]
|
|
29
52
|
function FieldOfViewUtils.safeExp(logHeight, linearAt)
|
|
30
53
|
local transitionAt = math.log(linearAt)
|
|
31
54
|
|
|
@@ -36,6 +59,13 @@ function FieldOfViewUtils.safeExp(logHeight, linearAt)
|
|
|
36
59
|
end
|
|
37
60
|
end
|
|
38
61
|
|
|
62
|
+
--[=[
|
|
63
|
+
Interpolates field of view in height space, instead of degrees.
|
|
64
|
+
@param fov0 number
|
|
65
|
+
@param fov1 number
|
|
66
|
+
@param percent number
|
|
67
|
+
@return number -- Fov in degrees
|
|
68
|
+
]=]
|
|
39
69
|
function FieldOfViewUtils.lerpInHeightSpace(fov0, fov1, percent)
|
|
40
70
|
local height0 = FieldOfViewUtils.fovToHeight(fov0)
|
|
41
71
|
local height1 = FieldOfViewUtils.fovToHeight(fov1)
|