@quenty/depthoffield 11.0.0 → 11.1.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 +11 -0
- package/package.json +14 -7
- package/src/Client/DepthOfFieldEffect.lua +314 -0
- package/src/Client/DepthOfFieldEffect.story.lua +79 -0
- package/src/Client/DepthOfFieldModifier.lua +0 -164
- package/src/Client/DepthOfFieldService.lua +0 -135
- package/src/Client/DepthOfFieldTweener.lua +0 -203
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [11.1.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/depthoffield@11.0.0...@quenty/depthoffield@11.1.0) (2024-03-09)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Refactor DepthOfFieldService (Technically a breaking change, but I don't think anyone is using this package) ([b43d54e](https://github.com/Quenty/NevermoreEngine/commit/b43d54ea4edccf33def7e8d60c97d9dbec694379))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [11.0.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/depthoffield@10.0.0...@quenty/depthoffield@11.0.0) (2024-02-14)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/depthoffield
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/depthoffield",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.1.0",
|
|
4
4
|
"description": "Depth of field service to allow multiple systems to write depth of field",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,15 +26,22 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@quenty/acceltween": "^2.3.0",
|
|
29
|
-
"@quenty/baseobject": "^10.
|
|
30
|
-
"@quenty/
|
|
31
|
-
"@quenty/
|
|
32
|
-
"@quenty/
|
|
29
|
+
"@quenty/baseobject": "^10.1.0",
|
|
30
|
+
"@quenty/basicpane": "^13.1.0",
|
|
31
|
+
"@quenty/blend": "^12.1.0",
|
|
32
|
+
"@quenty/brio": "^14.1.0",
|
|
33
|
+
"@quenty/instanceutils": "^13.1.0",
|
|
34
|
+
"@quenty/loader": "^10.1.0",
|
|
35
|
+
"@quenty/maid": "^3.1.0",
|
|
36
|
+
"@quenty/math": "^2.6.0",
|
|
37
|
+
"@quenty/rx": "^13.1.0",
|
|
38
|
+
"@quenty/signal": "^7.1.0",
|
|
33
39
|
"@quenty/steputils": "^3.3.0",
|
|
34
|
-
"@quenty/
|
|
40
|
+
"@quenty/transitionmodel": "^7.1.0",
|
|
41
|
+
"@quenty/valueobject": "^13.1.0"
|
|
35
42
|
},
|
|
36
43
|
"publishConfig": {
|
|
37
44
|
"access": "public"
|
|
38
45
|
},
|
|
39
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "e0148dde5ca3864389a0faa2da66153a776acc1e"
|
|
40
47
|
}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
--[=[
|
|
2
|
+
Handles interpolation of depth of field, which is tricky due to how Roblox implemented the shader
|
|
3
|
+
and how it interacts with other depth of field effects.
|
|
4
|
+
|
|
5
|
+
@class DepthOfFieldEffect
|
|
6
|
+
]=]
|
|
7
|
+
|
|
8
|
+
local require = require(script.Parent.loader).load(script)
|
|
9
|
+
|
|
10
|
+
local Lighting = game:GetService("Lighting")
|
|
11
|
+
local Workspace = game:GetService("Workspace")
|
|
12
|
+
|
|
13
|
+
local Blend = require("Blend")
|
|
14
|
+
local Maid = require("Maid")
|
|
15
|
+
local Math = require("Math")
|
|
16
|
+
local Observable = require("Observable")
|
|
17
|
+
local Rx = require("Rx")
|
|
18
|
+
local RxBrioUtils = require("RxBrioUtils")
|
|
19
|
+
local RxInstanceUtils = require("RxInstanceUtils")
|
|
20
|
+
local SpringObject = require("SpringObject")
|
|
21
|
+
local SpringTransitionModel = require("SpringTransitionModel")
|
|
22
|
+
local TransitionModel = require("TransitionModel")
|
|
23
|
+
local ValueObject = require("ValueObject")
|
|
24
|
+
local RxAttributeUtils = require("RxAttributeUtils")
|
|
25
|
+
|
|
26
|
+
local DepthOfFieldEffect = setmetatable({}, TransitionModel)
|
|
27
|
+
DepthOfFieldEffect.ClassName = "DepthOfFieldEffect"
|
|
28
|
+
DepthOfFieldEffect.__index = DepthOfFieldEffect
|
|
29
|
+
|
|
30
|
+
function DepthOfFieldEffect.new()
|
|
31
|
+
local self = setmetatable(TransitionModel.new(), DepthOfFieldEffect)
|
|
32
|
+
|
|
33
|
+
self._focusDistanceSpring = self._maid:Add(SpringObject.new(40, 30))
|
|
34
|
+
self._inFocusRadiusSpring = self._maid:Add(SpringObject.new(35, 30))
|
|
35
|
+
self._nearIntensitySpring = self._maid:Add(SpringObject.new(1, 30))
|
|
36
|
+
self._farIntensitySpring = self._maid:Add(SpringObject.new(1, 30))
|
|
37
|
+
|
|
38
|
+
self._focusDistanceSpring.Epsilon = 1e-3
|
|
39
|
+
self._focusDistanceSpring.Epsilon = 1e-3
|
|
40
|
+
self._nearIntensitySpring.Epsilon = 1e-4
|
|
41
|
+
self._farIntensitySpring.Epsilon = 1e-4
|
|
42
|
+
|
|
43
|
+
self._percentVisibleModel = self._maid:Add(SpringTransitionModel.new())
|
|
44
|
+
self._percentVisibleModel:SetSpeed(10)
|
|
45
|
+
self._percentVisibleModel:BindToPaneVisbility(self)
|
|
46
|
+
|
|
47
|
+
self:SetPromiseShow(function(_, doNotAnimate)
|
|
48
|
+
return self._percentVisibleModel:PromiseShow(doNotAnimate)
|
|
49
|
+
end)
|
|
50
|
+
self:SetPromiseHide(function(_, doNotAnimate)
|
|
51
|
+
return self._percentVisibleModel:PromiseHide(doNotAnimate)
|
|
52
|
+
end)
|
|
53
|
+
|
|
54
|
+
self._maid:GiveTask(self:_render():Subscribe(function(gui)
|
|
55
|
+
self.Gui = gui
|
|
56
|
+
end))
|
|
57
|
+
|
|
58
|
+
return self
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
function DepthOfFieldEffect:SetShowSpeed(speed)
|
|
62
|
+
self._percentVisibleModel:SetSpeed(speed)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
--[=[
|
|
66
|
+
Sets the target depth of field distance
|
|
67
|
+
@param focusDistanceTarget number
|
|
68
|
+
@param doNotAnimate boolean
|
|
69
|
+
]=]
|
|
70
|
+
function DepthOfFieldEffect:SetFocusDistanceTarget(focusDistanceTarget, doNotAnimate)
|
|
71
|
+
assert(type(focusDistanceTarget) == "number", "Bad focusDistanceTarget")
|
|
72
|
+
|
|
73
|
+
self._focusDistanceSpring:SetTarget(focusDistanceTarget, doNotAnimate)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
--[=[
|
|
77
|
+
Sets the target depth of field radius
|
|
78
|
+
@param inFocusRadiusTarget number
|
|
79
|
+
@param doNotAnimate boolean
|
|
80
|
+
]=]
|
|
81
|
+
function DepthOfFieldEffect:SetInFocusRadiusTarget(inFocusRadiusTarget, doNotAnimate)
|
|
82
|
+
assert(type(inFocusRadiusTarget) == "number", "Bad inFocusRadiusTarget")
|
|
83
|
+
|
|
84
|
+
self._inFocusRadiusSpring:SetTarget(inFocusRadiusTarget, doNotAnimate)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
--[=[
|
|
88
|
+
Sets the near intensity target
|
|
89
|
+
@param nearIntensityTarget number
|
|
90
|
+
@param doNotAnimate boolean
|
|
91
|
+
]=]
|
|
92
|
+
function DepthOfFieldEffect:SetNearIntensityTarget(nearIntensityTarget, doNotAnimate)
|
|
93
|
+
assert(type(nearIntensityTarget) == "number", "Bad nearIntensityTarget")
|
|
94
|
+
|
|
95
|
+
self._nearIntensitySpring:SetTarget(nearIntensityTarget, doNotAnimate)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
--[=[
|
|
99
|
+
Sets the far intensity target
|
|
100
|
+
@param farIntensityTarget number
|
|
101
|
+
@param doNotAnimate boolean
|
|
102
|
+
]=]
|
|
103
|
+
function DepthOfFieldEffect:SetFarIntensityTarget(farIntensityTarget, doNotAnimate)
|
|
104
|
+
assert(type(farIntensityTarget) == "number", "Bad farIntensityTarget")
|
|
105
|
+
|
|
106
|
+
self._farIntensitySpring:SetTarget(farIntensityTarget, doNotAnimate)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
--[=[
|
|
110
|
+
Retrieves the distance target
|
|
111
|
+
@return number
|
|
112
|
+
]=]
|
|
113
|
+
function DepthOfFieldEffect:GetFocusDistanceTarget()
|
|
114
|
+
return self._focusDistanceSpring.Target
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
--[=[
|
|
118
|
+
Retrieves the radius target
|
|
119
|
+
@return number
|
|
120
|
+
]=]
|
|
121
|
+
function DepthOfFieldEffect:GetInFocusRadiusTarget()
|
|
122
|
+
return self._inFocusRadiusSpring.Target
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
--[=[
|
|
126
|
+
Retrieve the near intensity target
|
|
127
|
+
@return number
|
|
128
|
+
]=]
|
|
129
|
+
function DepthOfFieldEffect:GetNearIntensityTarget()
|
|
130
|
+
return self._nearIntensitySpring.Target
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
--[=[
|
|
134
|
+
Retrieve the far intensity target
|
|
135
|
+
@return number
|
|
136
|
+
]=]
|
|
137
|
+
function DepthOfFieldEffect:GetFarIntensityTarget()
|
|
138
|
+
return self._farIntensitySpring.Target
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
function DepthOfFieldEffect:_render()
|
|
142
|
+
-- Note: Roblox blends DepthOfField by picking highest value in each category, so we always drive the "hidden"
|
|
143
|
+
-- state towards zero. The only issue is `InFocusRadius` must be rendered at target of 500 to fade "out" the effect
|
|
144
|
+
-- if other
|
|
145
|
+
|
|
146
|
+
return Blend.New "DepthOfFieldEffect" {
|
|
147
|
+
Name = "DepthOfField";
|
|
148
|
+
Enabled = Blend.Computed(self._percentVisibleModel, function(visible)
|
|
149
|
+
return visible > 0
|
|
150
|
+
end);
|
|
151
|
+
FocusDistance = Blend.Computed(
|
|
152
|
+
self._percentVisibleModel,
|
|
153
|
+
self._focusDistanceSpring,
|
|
154
|
+
self:_observeRenderedDepthOfFieldState(),
|
|
155
|
+
function(percentVisible, focusDistance, externalRenderedState)
|
|
156
|
+
-- This help smooth out interpolation
|
|
157
|
+
|
|
158
|
+
local externalFocusDistance = focusDistance
|
|
159
|
+
if externalRenderedState and externalRenderedState.focusDistance then
|
|
160
|
+
externalFocusDistance = externalRenderedState.focusDistance
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
return Math.map(percentVisible, 0, 1, externalFocusDistance, focusDistance)
|
|
164
|
+
end);
|
|
165
|
+
InFocusRadius = Blend.Computed(
|
|
166
|
+
self._percentVisibleModel,
|
|
167
|
+
self._inFocusRadiusSpring,
|
|
168
|
+
self:_observeRenderedDepthOfFieldState(),
|
|
169
|
+
function(percentVisible, inFocusRadius, externalRenderedState)
|
|
170
|
+
-- If we tween this to 0 then we create lots of blur as we do so
|
|
171
|
+
-- However, if we tween out to 500 then we get picked, blocking in-focus blur...
|
|
172
|
+
-- So tween to the minimum of other enabled depth of fields
|
|
173
|
+
|
|
174
|
+
-- Tweening just intensity doesn't work because of the way Roblox shaders work.
|
|
175
|
+
|
|
176
|
+
local externalInFocusRadius = 500
|
|
177
|
+
if externalRenderedState and externalRenderedState.inFocusRadius then
|
|
178
|
+
externalInFocusRadius = externalRenderedState.inFocusRadius
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
return Math.map(percentVisible, 0, 1, externalInFocusRadius, inFocusRadius)
|
|
182
|
+
end);
|
|
183
|
+
NearIntensity = Blend.Computed(self._percentVisibleModel, self._nearIntensitySpring, function(percentVisible, intensity)
|
|
184
|
+
return Math.map(percentVisible, 0, 1, 0, intensity)
|
|
185
|
+
end);
|
|
186
|
+
FarIntensity = Blend.Computed(self._percentVisibleModel, self._farIntensitySpring, function(percentVisible, intensity)
|
|
187
|
+
return Math.map(percentVisible, 0, 1, 0, intensity)
|
|
188
|
+
end);
|
|
189
|
+
[Blend.Instance] = function(gui)
|
|
190
|
+
self._depthOfField = gui
|
|
191
|
+
|
|
192
|
+
-- Setup attributes so multiple tweening depth off fields with this system isn't sad
|
|
193
|
+
self._maid:GiveTask(Blend.Computed(self._percentVisibleModel, self._inFocusRadiusSpring, function(percentVisible, inFocusRadius)
|
|
194
|
+
return Math.map(percentVisible, 0, 1, 0, inFocusRadius)
|
|
195
|
+
end):Subscribe(function(targetDepthOfFieldRadius)
|
|
196
|
+
self._depthOfField:SetAttribute("DepthOfFieldEffect_TargetInFocusRadius", targetDepthOfFieldRadius)
|
|
197
|
+
end))
|
|
198
|
+
|
|
199
|
+
self._maid:GiveTask(Blend.Computed(self._percentVisibleModel, self._focusDistanceSpring, function(percentVisible, focusDistance)
|
|
200
|
+
return Math.map(percentVisible, 0, 1, 0, focusDistance)
|
|
201
|
+
end):Subscribe(function(targetDepthOfFieldRadius)
|
|
202
|
+
self._depthOfField:SetAttribute("DepthOfFieldEffect_TargetFocusDistance", targetDepthOfFieldRadius)
|
|
203
|
+
end))
|
|
204
|
+
end;
|
|
205
|
+
}
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
function DepthOfFieldEffect:_observeRenderedDepthOfFieldState()
|
|
209
|
+
if self._observeOtherStates then
|
|
210
|
+
return self._observeOtherStates
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
self._observeOtherStates = Observable.new(function(sub)
|
|
214
|
+
local topMaid = Maid.new()
|
|
215
|
+
|
|
216
|
+
local result = topMaid:Add(ValueObject.new(nil))
|
|
217
|
+
|
|
218
|
+
local latestStates = {}
|
|
219
|
+
|
|
220
|
+
local function update()
|
|
221
|
+
local output = {
|
|
222
|
+
inFocusRadius = 0;
|
|
223
|
+
focusDistance = 0;
|
|
224
|
+
externalCount = 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
for _, state in pairs(latestStates) do
|
|
228
|
+
if state.depthOfField == self._depthOfField then
|
|
229
|
+
continue
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
if state.enabled then
|
|
233
|
+
output.externalCount += 1
|
|
234
|
+
local inFocusRadius
|
|
235
|
+
if state.targetInFocusRadius then
|
|
236
|
+
inFocusRadius = state.targetInFocusRadius
|
|
237
|
+
else
|
|
238
|
+
inFocusRadius = state.inFocusRadius
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
output.inFocusRadius = math.max(output.inFocusRadius, inFocusRadius)
|
|
242
|
+
|
|
243
|
+
local focusDistance
|
|
244
|
+
if state.targetFocusDistance then
|
|
245
|
+
focusDistance = state.targetFocusDistance
|
|
246
|
+
else
|
|
247
|
+
focusDistance = state.focusDistance
|
|
248
|
+
end
|
|
249
|
+
output.focusDistance = math.max(output.focusDistance, focusDistance)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
if output.externalCount == 0 then
|
|
254
|
+
result.Value = nil
|
|
255
|
+
else
|
|
256
|
+
result.Value = output
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
topMaid:GiveTask(self:_observeAllDepthOfFieldBrio():Subscribe(function(brio)
|
|
261
|
+
if brio:IsDead() then
|
|
262
|
+
return
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
local maid, depthOfField = brio:ToMaidAndValue()
|
|
266
|
+
maid:GiveTask(Rx.combineLatest({
|
|
267
|
+
depthOfField = depthOfField;
|
|
268
|
+
|
|
269
|
+
inFocusRadius = RxInstanceUtils.observeProperty(depthOfField, "InFocusRadius");
|
|
270
|
+
targetInFocusRadius = RxAttributeUtils.observeAttribute(depthOfField, "DepthOfFieldEffect_TargetInFocusRadius");
|
|
271
|
+
|
|
272
|
+
focusDistance = RxInstanceUtils.observeProperty(depthOfField, "FocusDistance");
|
|
273
|
+
targetFocusDistance = RxAttributeUtils.observeAttribute(depthOfField, "DepthOfFieldEffect_TargetFocusDistance");
|
|
274
|
+
|
|
275
|
+
enabled = RxInstanceUtils.observeProperty(depthOfField, "Enabled");
|
|
276
|
+
}):Subscribe(function(state)
|
|
277
|
+
if state.depthOfField == self._depthOfField then
|
|
278
|
+
latestStates[maid] = nil
|
|
279
|
+
else
|
|
280
|
+
latestStates[maid] = state
|
|
281
|
+
update()
|
|
282
|
+
end
|
|
283
|
+
end))
|
|
284
|
+
|
|
285
|
+
maid:GiveTask(function()
|
|
286
|
+
latestStates[maid] = nil
|
|
287
|
+
update()
|
|
288
|
+
end)
|
|
289
|
+
end))
|
|
290
|
+
|
|
291
|
+
topMaid:GiveTask(result:Observe():Subscribe(sub:GetFireFailComplete()))
|
|
292
|
+
|
|
293
|
+
return topMaid
|
|
294
|
+
end):Pipe({
|
|
295
|
+
Rx.cache()
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
return self._observeOtherStates
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
function DepthOfFieldEffect:_observeAllDepthOfFieldBrio()
|
|
302
|
+
return Rx.merge({
|
|
303
|
+
RxInstanceUtils.observeChildrenOfClassBrio(Lighting, "DepthOfFieldEffect");
|
|
304
|
+
RxInstanceUtils.observePropertyBrio(Workspace, "CurrentCamera", function(camera)
|
|
305
|
+
return camera ~= nil
|
|
306
|
+
end):Pipe({
|
|
307
|
+
RxBrioUtils.flatMapBrio(function(currentCamera)
|
|
308
|
+
return RxInstanceUtils.observeChildrenOfClassBrio(currentCamera, "DepthOfFieldEffect")
|
|
309
|
+
end)
|
|
310
|
+
})
|
|
311
|
+
})
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
return DepthOfFieldEffect
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
--[[
|
|
2
|
+
@class DepthOfFieldEffect.story
|
|
3
|
+
]]
|
|
4
|
+
|
|
5
|
+
local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).load(script)
|
|
6
|
+
|
|
7
|
+
local Workspace = game:GetService("Workspace")
|
|
8
|
+
|
|
9
|
+
local Maid = require("Maid")
|
|
10
|
+
local DepthOfFieldEffect = require("DepthOfFieldEffect")
|
|
11
|
+
local Blend = require("Blend")
|
|
12
|
+
|
|
13
|
+
return function(target)
|
|
14
|
+
local maid = Maid.new()
|
|
15
|
+
|
|
16
|
+
local depthOfFieldEffect = maid:Add(DepthOfFieldEffect.new())
|
|
17
|
+
depthOfFieldEffect:SetShowSpeed(10)
|
|
18
|
+
depthOfFieldEffect.Gui.Parent = Workspace.CurrentCamera
|
|
19
|
+
depthOfFieldEffect:Show()
|
|
20
|
+
|
|
21
|
+
local depthOfFieldEffect2 = maid:Add(DepthOfFieldEffect.new())
|
|
22
|
+
depthOfFieldEffect2:SetFocusDistanceTarget(100, true)
|
|
23
|
+
depthOfFieldEffect2:SetInFocusRadiusTarget(50, true)
|
|
24
|
+
depthOfFieldEffect2:SetShowSpeed(10)
|
|
25
|
+
depthOfFieldEffect2.Gui.Parent = Workspace.CurrentCamera
|
|
26
|
+
-- depthOfFieldEffect2:Show()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
maid:Add(Blend.mount(target, {
|
|
30
|
+
Blend.New "Frame" {
|
|
31
|
+
Size = UDim2.new(1, 0, 1, 0);
|
|
32
|
+
BackgroundTransparency = 1;
|
|
33
|
+
|
|
34
|
+
Blend.New "UIListLayout" {
|
|
35
|
+
Padding = UDim.new(0, 5);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Blend.New "TextButton" {
|
|
39
|
+
Text = Blend.Computed(depthOfFieldEffect:ObserveVisible(), function(visible)
|
|
40
|
+
return string.format("Toggle 1 (%s)", visible and "on" or "off")
|
|
41
|
+
end);
|
|
42
|
+
BackgroundColor3 = Blend.Computed(depthOfFieldEffect:ObserveVisible(), function(visible)
|
|
43
|
+
return visible and Color3.new(0.5, 1, 0.5) or Color3.new(1, 0.5, 0.5)
|
|
44
|
+
end);
|
|
45
|
+
AutoButtonColor = true;
|
|
46
|
+
Size = UDim2.new(0, 100, 0, 30);
|
|
47
|
+
[Blend.OnEvent "Activated"] = function()
|
|
48
|
+
depthOfFieldEffect:Toggle()
|
|
49
|
+
end;
|
|
50
|
+
|
|
51
|
+
Blend.New "UICorner" {
|
|
52
|
+
CornerRadius = UDim.new(0, 5);
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
Blend.New "TextButton" {
|
|
57
|
+
Text = Blend.Computed(depthOfFieldEffect2:ObserveVisible(), function(visible)
|
|
58
|
+
return string.format("Toggle 2 (%s)", visible and "on" or "off")
|
|
59
|
+
end);
|
|
60
|
+
BackgroundColor3 = Blend.Computed(depthOfFieldEffect2:ObserveVisible(), function(visible)
|
|
61
|
+
return visible and Color3.new(0.5, 1, 0.5) or Color3.new(1, 0.5, 0.5)
|
|
62
|
+
end);
|
|
63
|
+
AutoButtonColor = true;
|
|
64
|
+
Size = UDim2.new(0, 100, 0, 30);
|
|
65
|
+
[Blend.OnEvent "Activated"] = function()
|
|
66
|
+
depthOfFieldEffect2:Toggle()
|
|
67
|
+
end;
|
|
68
|
+
|
|
69
|
+
Blend.New "UICorner" {
|
|
70
|
+
CornerRadius = UDim.new(0, 5);
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
}))
|
|
75
|
+
|
|
76
|
+
return function()
|
|
77
|
+
maid:DoCleaning()
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
@class DepthOfFieldModifier
|
|
3
|
-
]=]
|
|
4
|
-
|
|
5
|
-
local require = require(script.Parent.loader).load(script)
|
|
6
|
-
|
|
7
|
-
local BaseObject = require("BaseObject")
|
|
8
|
-
local Signal = require("Signal")
|
|
9
|
-
|
|
10
|
-
local DepthOfFieldModifier = setmetatable({}, BaseObject)
|
|
11
|
-
DepthOfFieldModifier.ClassName = "DepthOfFieldModifier"
|
|
12
|
-
DepthOfFieldModifier.__index = DepthOfFieldModifier
|
|
13
|
-
|
|
14
|
-
function DepthOfFieldModifier.new(distance, radius, nearIntensity, farIntensity)
|
|
15
|
-
local self = setmetatable(BaseObject.new(), DepthOfFieldModifier)
|
|
16
|
-
|
|
17
|
-
assert(type(distance) == "number", "Bad distance")
|
|
18
|
-
assert(type(radius) == "number", "Bad radius")
|
|
19
|
-
assert(type(nearIntensity) == "number", "Bad nearIntensity")
|
|
20
|
-
assert(type(farIntensity) == "number", "Bad farIntensity")
|
|
21
|
-
|
|
22
|
-
self._originalDistance = distance
|
|
23
|
-
self._originalRadius = radius
|
|
24
|
-
self._originalNearIntensity = nearIntensity
|
|
25
|
-
self._originalFarIntensity = farIntensity
|
|
26
|
-
|
|
27
|
-
self._distance = distance
|
|
28
|
-
self._radius = radius
|
|
29
|
-
self._nearIntensity = nearIntensity
|
|
30
|
-
self._farIntensity = farIntensity
|
|
31
|
-
|
|
32
|
-
--[=[
|
|
33
|
-
Fires when the modifier is removing.
|
|
34
|
-
@prop Removing Signal
|
|
35
|
-
@within DepthOfFieldModifier
|
|
36
|
-
]=]
|
|
37
|
-
self.Removing = Signal.new()
|
|
38
|
-
self._maid:GiveTask(function()
|
|
39
|
-
self.Removing:Fire()
|
|
40
|
-
self.Removing:Destroy()
|
|
41
|
-
end)
|
|
42
|
-
|
|
43
|
-
--[=[
|
|
44
|
-
Fires when the distance changes.
|
|
45
|
-
@prop DistanceChanged Signal
|
|
46
|
-
@within DepthOfFieldModifier
|
|
47
|
-
]=]
|
|
48
|
-
self.DistanceChanged = Signal.new()
|
|
49
|
-
self._maid:GiveTask(self.DistanceChanged)
|
|
50
|
-
|
|
51
|
-
--[=[
|
|
52
|
-
Fires when the radius changes.
|
|
53
|
-
@prop RadiusChanged Signal
|
|
54
|
-
@within DepthOfFieldModifier
|
|
55
|
-
]=]
|
|
56
|
-
self.RadiusChanged = Signal.new()
|
|
57
|
-
self._maid:GiveTask(self.RadiusChanged)
|
|
58
|
-
|
|
59
|
-
self.NearIntensityChanged = Signal.new()
|
|
60
|
-
self._maid:GiveTask(self.NearIntensityChanged)
|
|
61
|
-
|
|
62
|
-
self.FarIntensityChanged = Signal.new()
|
|
63
|
-
self._maid:GiveTask(self.FarIntensityChanged)
|
|
64
|
-
|
|
65
|
-
return self
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
--[=[
|
|
69
|
-
Sets the target depth of field distance
|
|
70
|
-
@param distance number
|
|
71
|
-
@param doNotAnimate boolean
|
|
72
|
-
]=]
|
|
73
|
-
function DepthOfFieldModifier:SetDistance(distance, doNotAnimate)
|
|
74
|
-
assert(type(distance) == "number", "Bad distance")
|
|
75
|
-
|
|
76
|
-
if self._distance == distance then
|
|
77
|
-
return
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
self._distance = distance
|
|
81
|
-
self.DistanceChanged:Fire(distance, doNotAnimate)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
function DepthOfFieldModifier:GetOriginalDistance()
|
|
85
|
-
return self._originalDistance
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
function DepthOfFieldModifier:GetOriginalRadius()
|
|
89
|
-
return self._originalRadius
|
|
90
|
-
end
|
|
91
|
-
--[=[
|
|
92
|
-
Sets the target depth of field distance
|
|
93
|
-
@param radius number
|
|
94
|
-
@param doNotAnimate boolean
|
|
95
|
-
]=]
|
|
96
|
-
function DepthOfFieldModifier:SetRadius(radius, doNotAnimate)
|
|
97
|
-
assert(type(radius) == "number", "Bad radius")
|
|
98
|
-
|
|
99
|
-
if self._radius == radius then
|
|
100
|
-
return
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
self._radius = radius
|
|
104
|
-
self.RadiusChanged:Fire(radius, doNotAnimate)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
function DepthOfFieldModifier:SetNearIntensity(nearIntensity, doNotAnimate)
|
|
108
|
-
assert(type(nearIntensity) == "number", "Bad nearIntensity")
|
|
109
|
-
|
|
110
|
-
if self._nearIntensity == nearIntensity then
|
|
111
|
-
return
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
self._nearIntensity = nearIntensity
|
|
115
|
-
self.NearIntensityChanged:Fire(nearIntensity, doNotAnimate)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
function DepthOfFieldModifier:SetFarIntensity(farIntensity, doNotAnimate)
|
|
119
|
-
assert(type(farIntensity) == "number", "Bad farIntensity")
|
|
120
|
-
|
|
121
|
-
if self._farIntensity == farIntensity then
|
|
122
|
-
return
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
self._farIntensity = farIntensity
|
|
126
|
-
self.FarIntensityChanged:Fire(farIntensity, doNotAnimate)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
--[=[
|
|
130
|
-
Retrieves the distance
|
|
131
|
-
@return number
|
|
132
|
-
]=]
|
|
133
|
-
function DepthOfFieldModifier:GetDistance()
|
|
134
|
-
return self._distance
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
--[=[
|
|
138
|
-
Retrieves the radius
|
|
139
|
-
@return number
|
|
140
|
-
]=]
|
|
141
|
-
function DepthOfFieldModifier:GetRadius()
|
|
142
|
-
return self._radius
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
function DepthOfFieldModifier:GetNearIntensity()
|
|
146
|
-
return self._nearIntensity
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
function DepthOfFieldModifier:GetFarIntensity()
|
|
150
|
-
return self._farIntensity
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
--[=[
|
|
154
|
-
Resets the radius
|
|
155
|
-
@param doNotAnimate boolean
|
|
156
|
-
]=]
|
|
157
|
-
function DepthOfFieldModifier:Reset(doNotAnimate)
|
|
158
|
-
self:SetDistance(self._originalDistance, doNotAnimate)
|
|
159
|
-
self:SetRadius(self._originalRadius, doNotAnimate)
|
|
160
|
-
self:SetNearIntensity(self._originalNearIntensity, doNotAnimate)
|
|
161
|
-
self:SetFarIntensity(self._originalFarIntensity, doNotAnimate)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
return DepthOfFieldModifier
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
@class DepthOfFieldService
|
|
3
|
-
]=]
|
|
4
|
-
|
|
5
|
-
local require = require(script.Parent.loader).load(script)
|
|
6
|
-
|
|
7
|
-
local Lighting = game:GetService("Lighting")
|
|
8
|
-
|
|
9
|
-
local DepthOfFieldTweener = require("DepthOfFieldTweener")
|
|
10
|
-
local DepthOfFieldModifier = require("DepthOfFieldModifier")
|
|
11
|
-
local Maid = require("Maid")
|
|
12
|
-
local ValueObject = require("ValueObject")
|
|
13
|
-
|
|
14
|
-
local DepthOfFieldService = {}
|
|
15
|
-
DepthOfFieldService.ServiceName = "DepthOfFieldService"
|
|
16
|
-
|
|
17
|
-
--[=[
|
|
18
|
-
Initializes the DepthOfFieldService. Should be done via [ServiceBag].
|
|
19
|
-
@param _serviceBag ServiceBag
|
|
20
|
-
]=]
|
|
21
|
-
function DepthOfFieldService:Init(_serviceBag)
|
|
22
|
-
self._maid = Maid.new()
|
|
23
|
-
|
|
24
|
-
self._topOfStack = self._maid:Add(ValueObject.new())
|
|
25
|
-
|
|
26
|
-
self._depthOfField = self:_createDepthOfFIeld()
|
|
27
|
-
|
|
28
|
-
self._tweener = self._maid:Add(DepthOfFieldTweener.new(self._depthOfField))
|
|
29
|
-
|
|
30
|
-
-- TODO: Reprogram completely to be independent...
|
|
31
|
-
|
|
32
|
-
-- Assume we can enable now that we've recorded values
|
|
33
|
-
-- self._depthOfField.InFocusRadius = self._tweener:GetOriginalRadius()
|
|
34
|
-
-- self._depthOfField.FocusDistance = self._tweener:GetOriginalDistance()
|
|
35
|
-
-- self._depthOfField.NearIntensity = self._tweener:GetOriginalNearIntensity()
|
|
36
|
-
-- self._depthOfField.FarIntensity = self._tweener:GetOriginalFarIntensity()
|
|
37
|
-
-- self._depthOfField.Enabled = true
|
|
38
|
-
|
|
39
|
-
self._maid:GiveTask(self._topOfStack.Changed:Connect(function(new)
|
|
40
|
-
local maid = Maid.new()
|
|
41
|
-
|
|
42
|
-
if new then
|
|
43
|
-
self._tweener:SetDistance(new:GetDistance(), false)
|
|
44
|
-
self._tweener:SetRadius(new:GetRadius(), false)
|
|
45
|
-
self._tweener:SetNearIntensity(new:GetNearIntensity(), false)
|
|
46
|
-
self._tweener:SetFarIntensity(new:GetFarIntensity(), false)
|
|
47
|
-
|
|
48
|
-
maid:GiveTask(new.DistanceChanged:Connect(function(distance, doNotAnimate)
|
|
49
|
-
self._tweener:SetDistance(distance, doNotAnimate)
|
|
50
|
-
end))
|
|
51
|
-
maid:GiveTask(new.RadiusChanged:Connect(function(radius, doNotAnimate)
|
|
52
|
-
self._tweener:SetRadius(radius, doNotAnimate)
|
|
53
|
-
end))
|
|
54
|
-
maid:GiveTask(new.NearIntensityChanged:Connect(function(nearIntensity, doNotAnimate)
|
|
55
|
-
self._tweener:SetNearIntensity(nearIntensity, doNotAnimate)
|
|
56
|
-
end))
|
|
57
|
-
maid:GiveTask(new.FarIntensityChanged:Connect(function(farIntensity, doNotAnimate)
|
|
58
|
-
self._tweener:SetFarIntensity(farIntensity, doNotAnimate)
|
|
59
|
-
end))
|
|
60
|
-
else
|
|
61
|
-
self._tweener:Reset()
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
self._maid._currentVisible = maid
|
|
65
|
-
end))
|
|
66
|
-
|
|
67
|
-
self._modifierStack = {}
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
--[=[
|
|
71
|
-
Creates a new depth of field modifier
|
|
72
|
-
@return DepthOfFieldModifier
|
|
73
|
-
]=]
|
|
74
|
-
function DepthOfFieldService:CreateModifier()
|
|
75
|
-
local maid = Maid.new()
|
|
76
|
-
|
|
77
|
-
local modifier = DepthOfFieldModifier.new(
|
|
78
|
-
500,
|
|
79
|
-
500,
|
|
80
|
-
1,
|
|
81
|
-
1)
|
|
82
|
-
maid:GiveTask(modifier)
|
|
83
|
-
|
|
84
|
-
maid:GiveTask(function()
|
|
85
|
-
local index = table.find(self._modifierStack, modifier)
|
|
86
|
-
if index then
|
|
87
|
-
table.remove(self._modifierStack, index)
|
|
88
|
-
else
|
|
89
|
-
warn("[DepthOfFieldService] - Somehow modifier not in stack")
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
self:_updateTopOfStack()
|
|
93
|
-
end)
|
|
94
|
-
|
|
95
|
-
maid:GiveTask(modifier.Removing:Connect(function()
|
|
96
|
-
self:_removeModifier(modifier)
|
|
97
|
-
end))
|
|
98
|
-
|
|
99
|
-
self._maid[modifier] = maid
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
table.insert(self._modifierStack, modifier)
|
|
103
|
-
self:_updateTopOfStack()
|
|
104
|
-
|
|
105
|
-
if #self._modifierStack >= 10 then
|
|
106
|
-
warn("[DepthOfFieldService.PushEffect] - Memory leak possible in stack")
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
return modifier
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
function DepthOfFieldService:_updateTopOfStack()
|
|
113
|
-
self._topOfStack.Value = self._modifierStack[#self._modifierStack]
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
function DepthOfFieldService:_removeModifier(modifier)
|
|
117
|
-
self._maid[modifier] = nil
|
|
118
|
-
self:_updateTopOfStack()
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
function DepthOfFieldService:_createDepthOfFIeld()
|
|
122
|
-
local depthOfField = Instance.new("DepthOfFieldEffect")
|
|
123
|
-
depthOfField.Name = "DepthOfFieldService_DepthOfField"
|
|
124
|
-
depthOfField.FarIntensity = 0
|
|
125
|
-
depthOfField.FocusDistance = 500
|
|
126
|
-
depthOfField.InFocusRadius = 500
|
|
127
|
-
depthOfField.NearIntensity = 0
|
|
128
|
-
depthOfField.Enabled = true
|
|
129
|
-
depthOfField.Parent = Lighting
|
|
130
|
-
self._maid:GiveTask(depthOfField)
|
|
131
|
-
|
|
132
|
-
return depthOfField
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
return DepthOfFieldService
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
--[=[
|
|
2
|
-
Tweens DepthOfField. Prefer to use [DepthOfFieldService].
|
|
3
|
-
@class DepthOfFieldTweener
|
|
4
|
-
]=]
|
|
5
|
-
|
|
6
|
-
local require = require(script.Parent.loader).load(script)
|
|
7
|
-
|
|
8
|
-
local AccelTween = require("AccelTween")
|
|
9
|
-
local BaseObject = require("BaseObject")
|
|
10
|
-
local StepUtils = require("StepUtils")
|
|
11
|
-
|
|
12
|
-
local DepthOfFieldTweener = setmetatable({}, BaseObject)
|
|
13
|
-
DepthOfFieldTweener.ClassName = "DepthOfFieldTweener"
|
|
14
|
-
DepthOfFieldTweener.__index = DepthOfFieldTweener
|
|
15
|
-
|
|
16
|
-
--[=[
|
|
17
|
-
Create a new DepthOfFieldTweener.
|
|
18
|
-
@param depthOfField number
|
|
19
|
-
@return DepthOfFieldTweener
|
|
20
|
-
]=]
|
|
21
|
-
function DepthOfFieldTweener.new(depthOfField)
|
|
22
|
-
local self = setmetatable(BaseObject.new(), DepthOfFieldTweener)
|
|
23
|
-
|
|
24
|
-
self._depthOfField = assert(depthOfField, "No depthOfField")
|
|
25
|
-
|
|
26
|
-
-- If we aren't enabled we make sure to set distance to be far
|
|
27
|
-
self._originalDistance = self._depthOfField.Enabled and self._depthOfField.FocusDistance or 500
|
|
28
|
-
self._originalRadius = self._depthOfField.Enabled and self._depthOfField.InFocusRadius or 500
|
|
29
|
-
self._originalNearIntensity = self._depthOfField.NearIntensity
|
|
30
|
-
self._originalFarIntensity = self._depthOfField.FarIntensity
|
|
31
|
-
|
|
32
|
-
self._distance = AccelTween.new(10000)
|
|
33
|
-
self._distance.t = self._originalDistance
|
|
34
|
-
self._distance.p = self._originalDistance
|
|
35
|
-
|
|
36
|
-
self._radius = AccelTween.new(10000)
|
|
37
|
-
self._radius.t = self._originalRadius
|
|
38
|
-
self._radius.p = self._originalRadius
|
|
39
|
-
|
|
40
|
-
self._nearIntensity = AccelTween.new(30)
|
|
41
|
-
self._nearIntensity.t = self._originalNearIntensity
|
|
42
|
-
self._nearIntensity.p = self._originalNearIntensity
|
|
43
|
-
|
|
44
|
-
self._farIntensity = AccelTween.new(30)
|
|
45
|
-
self._farIntensity.t = self._originalFarIntensity
|
|
46
|
-
self._farIntensity.p = self._originalFarIntensity
|
|
47
|
-
|
|
48
|
-
self._maid:GiveTask(function()
|
|
49
|
-
self._depthOfField.FocusDistance = self._originalDistance
|
|
50
|
-
self._depthOfField.InFocusRadius = self._originalRadius
|
|
51
|
-
self._depthOfField.NearIntensity = self._originalNearIntensity
|
|
52
|
-
self._depthOfField.FarIntensity = self._originalFarIntensity
|
|
53
|
-
end)
|
|
54
|
-
|
|
55
|
-
self._startAnimation, self._maid._stop = StepUtils.bindToRenderStep(self._update)
|
|
56
|
-
self:_startAnimation()
|
|
57
|
-
|
|
58
|
-
return self
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
function DepthOfFieldTweener:SetNearIntensity(nearIntensity, doNotAnimate)
|
|
62
|
-
assert(type(nearIntensity) == "number", "Bad nearIntensity")
|
|
63
|
-
|
|
64
|
-
local target = math.clamp(nearIntensity, 0, 1)
|
|
65
|
-
self._nearIntensity.t = target
|
|
66
|
-
if doNotAnimate then
|
|
67
|
-
self._nearIntensity.p = target
|
|
68
|
-
self._nearIntensity.v = 0
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
self:_startAnimation()
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
function DepthOfFieldTweener:SetFarIntensity(farIntensity, doNotAnimate)
|
|
75
|
-
assert(type(farIntensity) == "number", "Bad farIntensity")
|
|
76
|
-
|
|
77
|
-
local target = math.clamp(farIntensity, 0, 1)
|
|
78
|
-
self._farIntensity.t = target
|
|
79
|
-
if doNotAnimate then
|
|
80
|
-
self._farIntensity.p = target
|
|
81
|
-
self._farIntensity.v = 0
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
self:_startAnimation()
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
--[=[
|
|
89
|
-
Sets the radius and starts any animation
|
|
90
|
-
@param radius number
|
|
91
|
-
@param doNotAnimate boolean
|
|
92
|
-
]=]
|
|
93
|
-
function DepthOfFieldTweener:SetRadius(radius, doNotAnimate)
|
|
94
|
-
assert(type(radius) == "number", "Bad radius")
|
|
95
|
-
|
|
96
|
-
local target = math.clamp(radius, 0, 500)
|
|
97
|
-
self._radius.t = target
|
|
98
|
-
if doNotAnimate then
|
|
99
|
-
self._radius.p = target
|
|
100
|
-
self._radius.v = 0
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
self:_startAnimation()
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
--[=[
|
|
107
|
-
Gets the current radius being rendered
|
|
108
|
-
@return number
|
|
109
|
-
]=]
|
|
110
|
-
function DepthOfFieldTweener:GetRadius()
|
|
111
|
-
return self._radius.p
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
--[=[
|
|
115
|
-
Gets the current distance being set
|
|
116
|
-
@return number
|
|
117
|
-
]=]
|
|
118
|
-
function DepthOfFieldTweener:GetDistance()
|
|
119
|
-
return self._distance.p
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
--[=[
|
|
123
|
-
Sets the distance to render
|
|
124
|
-
@param distance number
|
|
125
|
-
@param doNotAnimate boolean
|
|
126
|
-
]=]
|
|
127
|
-
function DepthOfFieldTweener:SetDistance(distance, doNotAnimate)
|
|
128
|
-
assert(type(distance) == "number", "Bad distance")
|
|
129
|
-
|
|
130
|
-
local target = math.clamp(distance, 0, 500)
|
|
131
|
-
self._distance.t = target
|
|
132
|
-
if doNotAnimate then
|
|
133
|
-
self._distance.p = target
|
|
134
|
-
self._distance.v = 0
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
self:_startAnimation()
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
--[=[
|
|
141
|
-
Resets the depth of field to the original distance
|
|
142
|
-
@param doNotAnimate boolean
|
|
143
|
-
]=]
|
|
144
|
-
function DepthOfFieldTweener:Reset(doNotAnimate)
|
|
145
|
-
self:ResetRadius(doNotAnimate)
|
|
146
|
-
self:ResetDistance(doNotAnimate)
|
|
147
|
-
self:ResetNearIntensity(doNotAnimate)
|
|
148
|
-
self:ResetFarIntensity(doNotAnimate)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
--[=[
|
|
152
|
-
Resets the radius
|
|
153
|
-
@param doNotAnimate boolean
|
|
154
|
-
]=]
|
|
155
|
-
function DepthOfFieldTweener:ResetRadius(doNotAnimate)
|
|
156
|
-
self:SetRadius(self._originalRadius, doNotAnimate)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
--[=[
|
|
160
|
-
Resets the distance
|
|
161
|
-
@param doNotAnimate boolean
|
|
162
|
-
]=]
|
|
163
|
-
function DepthOfFieldTweener:ResetDistance(doNotAnimate)
|
|
164
|
-
self:SetDistance(self._originalDistance, doNotAnimate)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
function DepthOfFieldTweener:ResetNearIntensity(doNotAnimate)
|
|
168
|
-
self:SetNearIntensity(self._originalNearIntensity, doNotAnimate)
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
function DepthOfFieldTweener:ResetFarIntensity(doNotAnimate)
|
|
172
|
-
self:SetFarIntensity(self._originalFarIntensity, doNotAnimate)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
function DepthOfFieldTweener:GetOriginalRadius()
|
|
176
|
-
return self._originalRadius
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
function DepthOfFieldTweener:GetOriginalDistance()
|
|
180
|
-
return self._originalDistance
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
function DepthOfFieldTweener:GetOriginalNearIntensity()
|
|
184
|
-
return self._originalNearIntensity
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
function DepthOfFieldTweener:GetOriginalFarIntensity()
|
|
188
|
-
return self._originalFarIntensity
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
function DepthOfFieldTweener:_update()
|
|
192
|
-
self._depthOfField.FocusDistance = self._distance.p
|
|
193
|
-
self._depthOfField.InFocusRadius = self._radius.p
|
|
194
|
-
self._depthOfField.NearIntensity = self._nearIntensity.p
|
|
195
|
-
self._depthOfField.FarIntensity = self._farIntensity.p
|
|
196
|
-
|
|
197
|
-
return self._radius.rtime > 0
|
|
198
|
-
or self._distance.rtime > 0
|
|
199
|
-
or self._nearIntensity.rtime > 0
|
|
200
|
-
or self._farIntensity.rtime > 0
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
return DepthOfFieldTweener
|