@quenty/viewport 11.21.3-canary.550.afa1b3b.0 → 11.21.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 +12 -1
- package/package.json +15 -15
- package/src/Client/Viewport.lua +37 -22
- package/src/Client/Viewport.story.lua +10 -6
- package/src/Client/ViewportControls.lua +21 -8
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,18 @@
|
|
|
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.21.
|
|
6
|
+
## [11.21.4-canary.11a5dcf.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/viewport@11.21.3...@quenty/viewport@11.21.4-canary.11a5dcf.0) (2025-05-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Additional type checking updates ([05ba29a](https://github.com/Quenty/NevermoreEngine/commit/05ba29a03efc9f3feed74b34f1d9dfb237496214))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [11.21.3](https://github.com/Quenty/NevermoreEngine/compare/@quenty/viewport@11.21.2...@quenty/viewport@11.21.3) (2025-04-10)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/viewport
|
|
9
20
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/viewport",
|
|
3
|
-
"version": "11.21.
|
|
3
|
+
"version": "11.21.4-canary.11a5dcf.0",
|
|
4
4
|
"description": "Rendering functionality for viewportFrames",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,25 +25,25 @@
|
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@quenty/adorneeutils": "3.3.3",
|
|
28
|
-
"@quenty/baseobject": "10.8.
|
|
29
|
-
"@quenty/basicpane": "13.17.
|
|
30
|
-
"@quenty/blend": "12.18.
|
|
31
|
-
"@quenty/camera": "14.20.
|
|
32
|
-
"@quenty/geometryutils": "6.8.
|
|
33
|
-
"@quenty/inputobjectutils": "4.18.
|
|
34
|
-
"@quenty/loader": "10.8.
|
|
35
|
-
"@quenty/maid": "3.4.
|
|
28
|
+
"@quenty/baseobject": "10.8.4-canary.11a5dcf.0",
|
|
29
|
+
"@quenty/basicpane": "13.17.4-canary.11a5dcf.0",
|
|
30
|
+
"@quenty/blend": "12.18.4-canary.11a5dcf.0",
|
|
31
|
+
"@quenty/camera": "14.20.4-canary.11a5dcf.0",
|
|
32
|
+
"@quenty/geometryutils": "6.8.5-canary.11a5dcf.0",
|
|
33
|
+
"@quenty/inputobjectutils": "4.18.4-canary.11a5dcf.0",
|
|
34
|
+
"@quenty/loader": "10.8.4-canary.11a5dcf.0",
|
|
35
|
+
"@quenty/maid": "3.4.4-canary.11a5dcf.0",
|
|
36
36
|
"@quenty/math": "2.7.3",
|
|
37
|
-
"@quenty/rx": "13.17.
|
|
38
|
-
"@quenty/signal": "7.10.
|
|
39
|
-
"@quenty/spring": "10.8.
|
|
40
|
-
"@quenty/valueobject": "13.17.
|
|
37
|
+
"@quenty/rx": "13.17.4-canary.11a5dcf.0",
|
|
38
|
+
"@quenty/signal": "7.10.4-canary.11a5dcf.0",
|
|
39
|
+
"@quenty/spring": "10.8.5-canary.11a5dcf.0",
|
|
40
|
+
"@quenty/valueobject": "13.17.4-canary.11a5dcf.0"
|
|
41
41
|
},
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@quenty/insertserviceutils": "10.10.
|
|
46
|
+
"@quenty/insertserviceutils": "10.10.5-canary.11a5dcf.0"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "11a5dcf7d4c7a0bfbf3337e97d30e8346ea09d3f"
|
|
49
49
|
}
|
package/src/Client/Viewport.lua
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Creates a ViewportFrame with size fitting and drag controls. This means that the
|
|
3
4
|
viewport will center the camera around the given instance, and allow the user
|
|
@@ -25,28 +26,42 @@ local CircleUtils = require("CircleUtils")
|
|
|
25
26
|
local Maid = require("Maid")
|
|
26
27
|
local Math = require("Math")
|
|
27
28
|
local Observable = require("Observable")
|
|
29
|
+
local Rx = require("Rx")
|
|
30
|
+
local Signal = require("Signal")
|
|
28
31
|
local SpringObject = require("SpringObject")
|
|
29
32
|
local ValueObject = require("ValueObject")
|
|
30
33
|
local ViewportControls = require("ViewportControls")
|
|
31
|
-
local Signal = require("Signal")
|
|
32
|
-
local Rx = require("Rx")
|
|
33
34
|
|
|
34
|
-
local MAX_PITCH = math.pi/3
|
|
35
|
-
local MIN_PITCH = -math.pi/3
|
|
36
|
-
local TAU = math.pi*2
|
|
35
|
+
local MAX_PITCH = math.pi / 3
|
|
36
|
+
local MIN_PITCH = -math.pi / 3
|
|
37
|
+
local TAU = math.pi * 2
|
|
37
38
|
|
|
38
39
|
local Viewport = setmetatable({}, BasicPane)
|
|
39
40
|
Viewport.ClassName = "Viewport"
|
|
40
41
|
Viewport.__index = Viewport
|
|
41
42
|
|
|
43
|
+
export type Viewport = typeof(setmetatable(
|
|
44
|
+
{} :: {
|
|
45
|
+
_current: ValueObject.ValueObject<Instance?>,
|
|
46
|
+
_transparency: ValueObject.ValueObject<number>,
|
|
47
|
+
_absoluteSize: ValueObject.ValueObject<Vector2>,
|
|
48
|
+
_fieldOfView: ValueObject.ValueObject<number>,
|
|
49
|
+
_controlsEnabled: ValueObject.ValueObject<boolean>,
|
|
50
|
+
_rotationYawSpring: SpringObject.SpringObject<number>,
|
|
51
|
+
_rotationPitchSpring: SpringObject.SpringObject<number>,
|
|
52
|
+
_notifyInstanceSizeChanged: Signal.Signal<()>,
|
|
53
|
+
},
|
|
54
|
+
{} :: typeof({ __index = Viewport })
|
|
55
|
+
)) & BasicPane.BasicPane
|
|
56
|
+
|
|
42
57
|
--[=[
|
|
43
58
|
Constructs a new viewport. Unlike a normal [BasicPane] this will not render anything
|
|
44
59
|
immediately. See [Viewport.Render] for details.
|
|
45
60
|
|
|
46
61
|
@return Viewport
|
|
47
62
|
]=]
|
|
48
|
-
function Viewport.new()
|
|
49
|
-
local self = setmetatable(BasicPane.new(), Viewport)
|
|
63
|
+
function Viewport.new(): Viewport
|
|
64
|
+
local self: Viewport = setmetatable(BasicPane.new() :: any, Viewport)
|
|
50
65
|
|
|
51
66
|
self._current = self._maid:Add(ValueObject.new(nil))
|
|
52
67
|
self._transparency = self._maid:Add(ValueObject.new(0, "number"))
|
|
@@ -103,7 +118,7 @@ function Viewport.blend(props)
|
|
|
103
118
|
end)
|
|
104
119
|
end
|
|
105
120
|
|
|
106
|
-
function Viewport
|
|
121
|
+
function Viewport.ObserveTransparency(self: Viewport): Observable.Observable<number>
|
|
107
122
|
return self._transparency:Observe()
|
|
108
123
|
end
|
|
109
124
|
|
|
@@ -112,7 +127,7 @@ end
|
|
|
112
127
|
|
|
113
128
|
@param enabled boolean
|
|
114
129
|
]=]
|
|
115
|
-
function Viewport
|
|
130
|
+
function Viewport.SetControlsEnabled(self: Viewport, enabled: boolean)
|
|
116
131
|
assert(type(enabled) == "boolean", "Bad enabled")
|
|
117
132
|
|
|
118
133
|
self._controlsEnabled.Value = enabled
|
|
@@ -123,7 +138,7 @@ end
|
|
|
123
138
|
|
|
124
139
|
@param transparency number
|
|
125
140
|
]=]
|
|
126
|
-
function Viewport
|
|
141
|
+
function Viewport.SetTransparency(self: Viewport, transparency: number)
|
|
127
142
|
return self._transparency:Mount(transparency or 0)
|
|
128
143
|
end
|
|
129
144
|
|
|
@@ -132,7 +147,7 @@ end
|
|
|
132
147
|
|
|
133
148
|
@param fieldOfView number
|
|
134
149
|
]=]
|
|
135
|
-
function Viewport
|
|
150
|
+
function Viewport.SetFieldOfView(self: Viewport, fieldOfView: number)
|
|
136
151
|
return self._fieldOfView:Mount(fieldOfView or 20)
|
|
137
152
|
end
|
|
138
153
|
|
|
@@ -148,7 +163,7 @@ end
|
|
|
148
163
|
|
|
149
164
|
@param instance Instance?
|
|
150
165
|
]=]
|
|
151
|
-
function Viewport
|
|
166
|
+
function Viewport.SetInstance(self: Viewport, instance: Instance?): () -> ()
|
|
152
167
|
self._current:Mount(instance)
|
|
153
168
|
|
|
154
169
|
return function()
|
|
@@ -162,11 +177,11 @@ end
|
|
|
162
177
|
Notifies the viewport of the instance size changing. We don't connect to
|
|
163
178
|
any events here because the instance can be anything.
|
|
164
179
|
]=]
|
|
165
|
-
function Viewport
|
|
180
|
+
function Viewport.NotifyInstanceSizeChanged(self: Viewport)
|
|
166
181
|
self._notifyInstanceSizeChanged:Fire()
|
|
167
182
|
end
|
|
168
183
|
|
|
169
|
-
function Viewport
|
|
184
|
+
function Viewport.SetYaw(self: Viewport, yaw: number, doNotAnimate: boolean?)
|
|
170
185
|
yaw = yaw % TAU
|
|
171
186
|
|
|
172
187
|
self._rotationYawSpring.Position =
|
|
@@ -178,14 +193,14 @@ function Viewport:SetYaw(yaw: number, doNotAnimate: boolean?)
|
|
|
178
193
|
end
|
|
179
194
|
end
|
|
180
195
|
|
|
181
|
-
function Viewport
|
|
196
|
+
function Viewport.SetPitch(self: Viewport, pitch: number, doNotAnimate: boolean?)
|
|
182
197
|
self._rotationPitchSpring.Target = math.clamp(pitch, MIN_PITCH, MAX_PITCH)
|
|
183
198
|
if doNotAnimate then
|
|
184
199
|
self._rotationPitchSpring.Position = self._rotationPitchSpring.Target
|
|
185
200
|
end
|
|
186
201
|
end
|
|
187
202
|
|
|
188
|
-
function Viewport
|
|
203
|
+
function Viewport.RotateBy(self: Viewport, deltaV2: Vector2, doNotAnimate: boolean?)
|
|
189
204
|
self:SetYaw(self._rotationYawSpring.Value + deltaV2.X, doNotAnimate)
|
|
190
205
|
self:SetPitch(self._rotationPitchSpring.Value + deltaV2.Y, doNotAnimate)
|
|
191
206
|
end
|
|
@@ -211,7 +226,7 @@ end
|
|
|
211
226
|
@param props { any }
|
|
212
227
|
@return Observable<ViewportFrame>
|
|
213
228
|
]=]
|
|
214
|
-
function Viewport
|
|
229
|
+
function Viewport.Render(self: Viewport, props)
|
|
215
230
|
local currentCamera = ValueObject.new()
|
|
216
231
|
self._maid:GiveTask(currentCamera)
|
|
217
232
|
|
|
@@ -231,7 +246,7 @@ function Viewport:Render(props)
|
|
|
231
246
|
CurrentCamera = currentCamera,
|
|
232
247
|
-- selene:allow(roblox_incorrect_color3_new_bounds)
|
|
233
248
|
LightColor = props.LightColor or Color3.new(brightness, brightness, brightness + 0.15),
|
|
234
|
-
LightDirection = props.LightDirection or lightDirectionCFrame:
|
|
249
|
+
LightDirection = props.LightDirection or lightDirectionCFrame:VectorToWorldSpace(Vector3.new(0, 0, -1)),
|
|
235
250
|
Ambient = props.Ambient or Color3.new(ambientBrightness, ambientBrightness, ambientBrightness + 0.15),
|
|
236
251
|
ImageTransparency = Blend.Computed(
|
|
237
252
|
props.Transparency or 0,
|
|
@@ -294,16 +309,16 @@ function Viewport:Render(props)
|
|
|
294
309
|
self._rotationYawSpring:ObserveRenderStepped(),
|
|
295
310
|
self._rotationPitchSpring:ObserveRenderStepped(),
|
|
296
311
|
Rx.fromSignal(self._notifyInstanceSizeChanged):Pipe({
|
|
297
|
-
Rx.defaultsToNil,
|
|
312
|
+
Rx.defaultsToNil :: any,
|
|
298
313
|
}),
|
|
299
|
-
function(inst, absSize, fov, rotationYaw, rotationPitch)
|
|
314
|
+
function(inst: Instance, absSize: Vector2, fov: number, rotationYaw: number, rotationPitch: number)
|
|
300
315
|
if typeof(inst) ~= "Instance" then
|
|
301
316
|
return CFrame.new()
|
|
302
317
|
end
|
|
303
318
|
|
|
304
|
-
local aspectRatio = absSize.
|
|
319
|
+
local aspectRatio = absSize.X / absSize.Y
|
|
305
320
|
local bbCFrame, bbSize = AdorneeUtils.getBoundingBox(inst)
|
|
306
|
-
if not bbCFrame then
|
|
321
|
+
if not (bbCFrame and bbSize) then
|
|
307
322
|
return CFrame.new()
|
|
308
323
|
end
|
|
309
324
|
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
@class Viewport.story
|
|
3
3
|
]]
|
|
4
4
|
|
|
5
|
-
local require =
|
|
5
|
+
local require =
|
|
6
|
+
require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
|
|
6
7
|
|
|
7
|
-
local Maid = require("Maid")
|
|
8
8
|
local InsertServiceUtils = require("InsertServiceUtils")
|
|
9
|
+
local Maid = require("Maid")
|
|
9
10
|
|
|
10
11
|
local Viewport = require("Viewport")
|
|
11
12
|
|
|
@@ -15,14 +16,17 @@ return function(target)
|
|
|
15
16
|
local viewport = Viewport.new()
|
|
16
17
|
maid:GiveTask(viewport)
|
|
17
18
|
|
|
18
|
-
maid
|
|
19
|
+
maid
|
|
20
|
+
:GivePromise(InsertServiceUtils.promiseAsset(182451181)) --The account must own the asset in order to insert it.
|
|
19
21
|
:Then(function(crate)
|
|
20
22
|
viewport:SetInstance(crate)
|
|
21
23
|
end)
|
|
22
24
|
|
|
23
|
-
maid:GiveTask(viewport
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
maid:GiveTask(viewport
|
|
26
|
+
:Render({
|
|
27
|
+
Parent = target,
|
|
28
|
+
})
|
|
29
|
+
:Subscribe())
|
|
26
30
|
|
|
27
31
|
return function()
|
|
28
32
|
maid:DoCleaning()
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Controls for [Viewport]
|
|
3
4
|
@class ViewportControls
|
|
@@ -6,8 +7,8 @@
|
|
|
6
7
|
local require = require(script.Parent.loader).load(script)
|
|
7
8
|
|
|
8
9
|
local BaseObject = require("BaseObject")
|
|
9
|
-
local Maid = require("Maid")
|
|
10
10
|
local InputObjectUtils = require("InputObjectUtils")
|
|
11
|
+
local Maid = require("Maid")
|
|
11
12
|
local ValueObject = require("ValueObject")
|
|
12
13
|
|
|
13
14
|
local SENSITIVITY = Vector2.new(8, 4)
|
|
@@ -16,14 +17,23 @@ local ViewportControls = setmetatable({}, BaseObject)
|
|
|
16
17
|
ViewportControls.ClassName = "ViewportControls"
|
|
17
18
|
ViewportControls.__index = ViewportControls
|
|
18
19
|
|
|
20
|
+
export type ViewportControls = typeof(setmetatable(
|
|
21
|
+
{} :: {
|
|
22
|
+
_obj: ViewportFrame,
|
|
23
|
+
_viewportModel: any,
|
|
24
|
+
_enabled: ValueObject.ValueObject<boolean>,
|
|
25
|
+
},
|
|
26
|
+
{} :: typeof({ __index = ViewportControls })
|
|
27
|
+
)) & BaseObject.BaseObject
|
|
28
|
+
|
|
19
29
|
--[=[
|
|
20
30
|
Create the controls for dragging.
|
|
21
31
|
@param viewport Instance
|
|
22
32
|
@param viewportModel Viewport
|
|
23
33
|
@return BaseObject
|
|
24
34
|
]=]
|
|
25
|
-
function ViewportControls.new(viewport: ViewportFrame, viewportModel)
|
|
26
|
-
local self = setmetatable(BaseObject.new(viewport), ViewportControls)
|
|
35
|
+
function ViewportControls.new(viewport: ViewportFrame, viewportModel: any): ViewportControls
|
|
36
|
+
local self: ViewportControls = setmetatable(BaseObject.new(viewport) :: any, ViewportControls)
|
|
27
37
|
|
|
28
38
|
self._viewportModel = assert(viewportModel, "No rotationYaw")
|
|
29
39
|
self._enabled = self._maid:Add(ValueObject.new(true, "boolean"))
|
|
@@ -48,13 +58,13 @@ end
|
|
|
48
58
|
|
|
49
59
|
@param enabled boolean
|
|
50
60
|
]=]
|
|
51
|
-
function ViewportControls
|
|
61
|
+
function ViewportControls.SetEnabled(self: ViewportControls, enabled: boolean)
|
|
52
62
|
assert(type(enabled) == "boolean", "Bad enabled")
|
|
53
63
|
|
|
54
64
|
self._enabled.Value = enabled
|
|
55
65
|
end
|
|
56
66
|
|
|
57
|
-
function ViewportControls
|
|
67
|
+
function ViewportControls._startDrag(self: ViewportControls, startInputObject: InputObject)
|
|
58
68
|
if self._maid._dragging then
|
|
59
69
|
return
|
|
60
70
|
end
|
|
@@ -71,13 +81,16 @@ function ViewportControls:_startDrag(startInputObject: InputObject)
|
|
|
71
81
|
|
|
72
82
|
local lastDelta
|
|
73
83
|
maid:GiveTask(self._obj.InputChanged:Connect(function(inputObject)
|
|
74
|
-
if
|
|
84
|
+
if
|
|
85
|
+
InputObjectUtils.isSameInputObject(inputObject, startInputObject)
|
|
86
|
+
or inputObject.UserInputType == Enum.UserInputType.MouseMovement
|
|
87
|
+
then
|
|
75
88
|
local position = inputObject.Position
|
|
76
89
|
local delta = lastPosition - position
|
|
77
90
|
lastPosition = position
|
|
78
91
|
|
|
79
92
|
local absSize = self._obj.AbsoluteSize
|
|
80
|
-
local deltaV2 = Vector2.new(delta.
|
|
93
|
+
local deltaV2 = Vector2.new(delta.X, delta.Y) / absSize * SENSITIVITY
|
|
81
94
|
lastDelta = deltaV2
|
|
82
95
|
|
|
83
96
|
self._viewportModel:RotateBy(deltaV2, true)
|
|
@@ -104,7 +117,7 @@ function ViewportControls:_startDrag(startInputObject: InputObject)
|
|
|
104
117
|
self._maid._dragging = maid
|
|
105
118
|
end
|
|
106
119
|
|
|
107
|
-
function ViewportControls
|
|
120
|
+
function ViewportControls._stopDrag(self: ViewportControls)
|
|
108
121
|
self._maid._dragging = nil
|
|
109
122
|
end
|
|
110
123
|
|