@quenty/adorneeboundingbox 2.2.1 → 2.3.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 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
+ # [2.3.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/adorneeboundingbox@2.2.1...@quenty/adorneeboundingbox@2.3.0) (2023-12-14)
7
+
8
+
9
+ ### Features
10
+
11
+ * Fix bounding box calculations to handle parts that are unanchored ([c252a99](https://github.com/Quenty/NevermoreEngine/commit/c252a99bbb1ba76bf86ec73a0fe80d0cf057309b))
12
+
13
+
14
+
15
+
16
+
6
17
  ## [2.2.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/adorneeboundingbox@2.2.0...@quenty/adorneeboundingbox@2.2.1) (2023-10-28)
7
18
 
8
19
  **Note:** Version bump only for package @quenty/adorneeboundingbox
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/adorneeboundingbox",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "Handles logic for reactive bounding box monitoring",
5
5
  "keywords": [
6
6
  "Roblox",
@@ -25,20 +25,20 @@
25
25
  "Quenty"
26
26
  ],
27
27
  "dependencies": {
28
- "@quenty/baseobject": "^7.0.0",
29
- "@quenty/brio": "^9.1.1",
28
+ "@quenty/baseobject": "^7.1.0",
29
+ "@quenty/brio": "^9.2.0",
30
30
  "@quenty/draw": "^4.3.0",
31
- "@quenty/instanceutils": "^8.1.1",
32
- "@quenty/loader": "^7.0.0",
31
+ "@quenty/instanceutils": "^8.2.0",
32
+ "@quenty/loader": "^7.1.0",
33
33
  "@quenty/maid": "^2.6.0",
34
- "@quenty/observablecollection": "^6.2.1",
35
- "@quenty/rx": "^8.1.1",
36
- "@quenty/selectionutils": "^3.1.1",
37
- "@quenty/signal": "^3.0.0",
38
- "@quenty/valueobject": "^8.1.1"
34
+ "@quenty/observablecollection": "^6.3.0",
35
+ "@quenty/rx": "^8.2.0",
36
+ "@quenty/selectionutils": "^3.2.0",
37
+ "@quenty/signal": "^3.1.0",
38
+ "@quenty/valueobject": "^8.2.0"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"
42
42
  },
43
- "gitHead": "440aca7ce2b50b74317ee05fdc0b8d1e58001af3"
43
+ "gitHead": "2c2dbbc0cb2fbb46b4f3270c559c63890fe18b26"
44
44
  }
@@ -12,27 +12,45 @@ local RxBrioUtils = require("RxBrioUtils")
12
12
  local RxInstanceUtils = require("RxInstanceUtils")
13
13
  local RxPartBoundingBoxUtils = require("RxPartBoundingBoxUtils")
14
14
  local ValueObject = require("ValueObject")
15
+ local AdorneePartBoundingBox = require("AdorneePartBoundingBox")
15
16
 
16
17
  local AdorneeBoundingBox = setmetatable({}, BaseObject)
17
18
  AdorneeBoundingBox.ClassName = "AdorneeBoundingBox"
18
19
  AdorneeBoundingBox.__index = AdorneeBoundingBox
19
20
 
20
- function AdorneeBoundingBox.new(adornee)
21
- assert(typeof(adornee) == "Instance", "Bad adornee")
21
+ function AdorneeBoundingBox.new(initialAdornee)
22
+ local self = setmetatable(BaseObject.new(), AdorneeBoundingBox)
22
23
 
23
- local self = setmetatable(BaseObject.new(adornee), AdorneeBoundingBox)
24
+ self._adornee = self._maid:Add(ValueObject.new(initialAdornee))
25
+ self._bbCFrame = self._maid:Add(ValueObject.new(nil))
26
+ self._bbSize = self._maid:Add(ValueObject.new(Vector3.zero, "Vector3"))
24
27
 
25
- self._bbCFrame = ValueObject.new(nil)
26
- self._maid:GiveTask(self._bbCFrame)
27
-
28
- self._bbSize = ValueObject.new(Vector3.zero)
29
- self._maid:GiveTask(self._bbSize)
28
+ self._maid:GiveTask(self._adornee:ObserveBrio(function(adornee)
29
+ return adornee ~= nil
30
+ end):Subscribe(function(brio)
31
+ if brio:IsDead() then
32
+ return
33
+ end
30
34
 
31
- self:_setup()
35
+ local maid, adornee = brio:ToMaidAndValue()
36
+ self:_setup(maid, adornee)
37
+ end))
32
38
 
33
39
  return self
34
40
  end
35
41
 
42
+ function AdorneeBoundingBox:SetAdornee(adornee)
43
+ assert(typeof(adornee) == "Instance" or adornee == nil, "Bad adornee")
44
+
45
+ self._adornee.Value = adornee
46
+
47
+ return function()
48
+ if self._adornee.Value == adornee then
49
+ self._adornee.Value = nil
50
+ end
51
+ end
52
+ end
53
+
36
54
  --[=[
37
55
  Observes the cframe of the adornee
38
56
  @return Observable<Vector3>
@@ -65,22 +83,26 @@ function AdorneeBoundingBox:GetSize()
65
83
  return self._bbSize.Value
66
84
  end
67
85
 
68
- function AdorneeBoundingBox:_setup()
69
- if self._obj:IsA("BasePart") then
70
- self._maid:GiveTask(self:_setupPart(self._obj))
71
- elseif self._obj:IsA("Model") then
72
- self._maid:GiveTask(self:_setupModel(self._obj))
73
- elseif self._obj:IsA("Attachment") then
74
- self._maid:GiveTask(self:_setupAttachment(self._obj))
75
- elseif self._obj:IsA("Humanoid") then
76
- self._maid:GiveTask(self:_setupHumanoid(self._obj))
77
- elseif self._obj:IsA("Accessory") or self._obj:IsA("Clothing") then
86
+ function AdorneeBoundingBox:_setup(maid, adornee)
87
+ if adornee:IsA("BasePart") then
88
+ maid:GiveTask(self:_setupPart(adornee))
89
+ elseif adornee:IsA("Model") then
90
+ maid:GiveTask(self:_setupModel(adornee))
91
+ elseif adornee:IsA("Attachment") then
92
+ maid:GiveTask(self:_setupAttachment(adornee))
93
+ elseif adornee:IsA("Humanoid") then
94
+ maid:GiveTask(self:_setupHumanoid(adornee))
95
+ elseif adornee:IsA("Accessory") or adornee:IsA("Clothing") then
78
96
  -- TODO: Rethink this contract
79
- warn("Accessories and clothing not supported yet")
80
- elseif self._obj:IsA("Tool") then
81
- self._maid:GiveTask(self:_setupTool(self._obj))
97
+ warn("[AdorneeBoundingBox] - Accessories and clothing not supported yet")
98
+ self._bbCFrame.Value = nil
99
+ self._bbSize.Value = Vector3.zero
100
+ elseif adornee:IsA("Tool") then
101
+ maid:GiveTask(self:_setupTool(adornee))
82
102
  else
83
- warn("Unsupported adornee")
103
+ self._bbCFrame.Value = nil
104
+ self._bbSize.Value = Vector3.zero
105
+ warn("[AdorneeBoundingBox] - Unsupported adornee")
84
106
  end
85
107
  end
86
108
 
@@ -109,9 +131,7 @@ function AdorneeBoundingBox:_setupModel(model)
109
131
 
110
132
  local topMaid = Maid.new()
111
133
 
112
- local adorneeModelBoundingBox = AdorneeModelBoundingBox.new(model)
113
- topMaid:GiveTask(adorneeModelBoundingBox)
114
-
134
+ local adorneeModelBoundingBox = topMaid:Add(AdorneeModelBoundingBox.new(model))
115
135
  topMaid:GiveTask(adorneeModelBoundingBox:ObserveCFrame():Subscribe(function(cframe)
116
136
  self._bbCFrame.Value = cframe
117
137
  end))
@@ -180,12 +200,13 @@ function AdorneeBoundingBox:_setupPart(part)
180
200
 
181
201
  local maid = Maid.new()
182
202
 
183
- maid:GiveTask(RxInstanceUtils.observeProperty(part, "Size"):Subscribe(function(size)
184
- self._bbSize.Value = size
185
- end))
186
- maid:GiveTask(RxPartBoundingBoxUtils.observePartCFrame(part):Subscribe(function(cframe)
203
+ local partBoundingBox = maid:Add(AdorneePartBoundingBox.new(part))
204
+ maid:GiveTask(partBoundingBox:ObserveCFrame():Subscribe(function(cframe)
187
205
  self._bbCFrame.Value = cframe
188
206
  end))
207
+ maid:GiveTask(partBoundingBox:ObserveSize():Subscribe(function(size)
208
+ self._bbSize.Value = size
209
+ end))
189
210
 
190
211
  return maid
191
212
  end
@@ -20,17 +20,10 @@ AdorneeModelBoundingBox.__index = AdorneeModelBoundingBox
20
20
  function AdorneeModelBoundingBox.new(model)
21
21
  local self = setmetatable(BaseObject.new(model), AdorneeModelBoundingBox)
22
22
 
23
- self._bbCFrame = ValueObject.new(nil)
24
- self._maid:GiveTask(self._bbCFrame)
25
-
26
- self._bbSize = ValueObject.new(nil)
27
- self._maid:GiveTask(self._bbSize)
28
-
29
- self._isDirty = ValueObject.new(false, "boolean")
30
- self._maid:GiveTask(self._isDirty)
31
-
32
- self._unanchoredPartsSet = ObservableSet.new(false)
33
- self._maid:GiveTask(self._unanchoredPartsSet)
23
+ self._bbCFrame = self._maid:Add(ValueObject.new(nil))
24
+ self._bbSize = self._maid:Add(ValueObject.new(Vector3.zero, "Vector3"))
25
+ self._isDirty = self._maid:Add(ValueObject.new(false, "boolean"))
26
+ self._unanchoredPartsSet = self._maid:Add(ObservableSet.new(false))
34
27
 
35
28
  self._maid:GiveTask(RxInstanceUtils.observeDescendantsBrio(self._obj, function(part)
36
29
  return part:IsA("BasePart")
@@ -39,8 +32,7 @@ function AdorneeModelBoundingBox.new(model)
39
32
  return
40
33
  end
41
34
 
42
- local maid = brio:ToMaid()
43
- local part = brio:GetValue()
35
+ local maid, part = brio:ToMaidAndValue()
44
36
 
45
37
  self:_handlePart(maid, part)
46
38
  end))
@@ -0,0 +1,65 @@
1
+ --[=[
2
+ @class AdorneePartBoundingBox
3
+ ]=]
4
+
5
+ local require = require(script.Parent.loader).load(script)
6
+
7
+ local RunService = game:GetService("RunService")
8
+
9
+ local BaseObject = require("BaseObject")
10
+ local ValueObject = require("ValueObject")
11
+ local RxInstanceUtils = require("RxInstanceUtils")
12
+
13
+ local AdorneePartBoundingBox = setmetatable({}, BaseObject)
14
+ AdorneePartBoundingBox.ClassName = "AdorneePartBoundingBox"
15
+ AdorneePartBoundingBox.__index = AdorneePartBoundingBox
16
+
17
+ function AdorneePartBoundingBox.new(part)
18
+ assert(typeof(part) == "Instance" and part:IsA("BasePart"), "Bad part")
19
+
20
+ local self = setmetatable(BaseObject.new(part), AdorneePartBoundingBox)
21
+
22
+ self._bbCFrame = self._maid:Add(ValueObject.new(nil))
23
+ self._bbSize = self._maid:Add(ValueObject.new(Vector3.zero, "Vector3"))
24
+
25
+ self._maid:GiveTask(RxInstanceUtils.observePropertyBrio(self._obj, "Anchored", function(anchored)
26
+ return not anchored
27
+ end):Subscribe(function(brio)
28
+ if brio:IsDead() then
29
+ return
30
+ end
31
+
32
+ local maid = brio:ToMaid()
33
+ self:_setupUnanchoredLoop(maid)
34
+ end))
35
+
36
+ self._maid:GiveTask(self._obj:GetPropertyChangedSignal("Size"):Connect(function()
37
+ self._bbSize.Value = self._obj.Size
38
+ end))
39
+ self._maid:GiveTask(self._obj:GetPropertyChangedSignal("CFrame"):Connect(function()
40
+ self:_update()
41
+ end))
42
+
43
+ return self
44
+ end
45
+
46
+ function AdorneePartBoundingBox:_setupUnanchoredLoop(maid)
47
+ -- Paranoid
48
+ maid:GiveTask(RunService.Heartbeat:Connect(function()
49
+ self._bbCFrame.Value = self._obj.CFrame
50
+ end))
51
+ end
52
+
53
+ function AdorneePartBoundingBox:_update()
54
+ self._bbCFrame.Value = self._obj.CFrame
55
+ end
56
+
57
+ function AdorneePartBoundingBox:ObserveCFrame()
58
+ return self._bbCFrame:Observe()
59
+ end
60
+
61
+ function AdorneePartBoundingBox:ObserveSize()
62
+ return self._bbSize:Observe()
63
+ end
64
+
65
+ return AdorneePartBoundingBox