@quenty/vector3utils 10.8.0 → 10.8.1
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,14 @@
|
|
|
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
|
+
## [10.8.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/vector3utils@10.8.0...@quenty/vector3utils@10.8.1) (2025-03-21)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/vector3utils
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# [10.8.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/vector3utils@10.7.1...@quenty/vector3utils@10.8.0) (2025-02-18)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @quenty/vector3utils
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/vector3utils",
|
|
3
|
-
"version": "10.8.
|
|
3
|
+
"version": "10.8.1",
|
|
4
4
|
"description": "Utilities involving Vector3 objects in Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@quenty/loader": "^10.8.0",
|
|
29
|
-
"@quenty/math": "^2.7.
|
|
29
|
+
"@quenty/math": "^2.7.1"
|
|
30
30
|
},
|
|
31
31
|
"publishConfig": {
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "6b7c3e15e60cdb185986207b574e2b5591261e7a"
|
|
35
35
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Utility functions involving RandomVector3Utils
|
|
3
4
|
@class RandomVector3Utils
|
|
@@ -10,17 +11,17 @@ local RandomVector3Utils = {}
|
|
|
10
11
|
@return Vector3
|
|
11
12
|
]=]
|
|
12
13
|
function RandomVector3Utils.getRandomUnitVector(): Vector3
|
|
13
|
-
local s = 2*(math.random()-0.5)
|
|
14
|
-
local t = 6.2831853071796*math.random()
|
|
14
|
+
local s = 2 * (math.random() - 0.5)
|
|
15
|
+
local t = 6.2831853071796 * math.random()
|
|
15
16
|
local rx = s
|
|
16
|
-
local m = (1-s*s)^0.5
|
|
17
|
-
local ry = m*math.cos(t)
|
|
18
|
-
local rz = m*math.sin(t)
|
|
17
|
+
local m = (1 - s * s) ^ 0.5
|
|
18
|
+
local ry = m * math.cos(t)
|
|
19
|
+
local rz = m * math.sin(t)
|
|
19
20
|
return Vector3.new(rx, ry, rz)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
local function gaussianRandom()
|
|
23
|
-
return math.sqrt(-2*math.log(1 - math.random()))*math.cos(2*math.pi*math.random())
|
|
23
|
+
local function gaussianRandom(): number
|
|
24
|
+
return math.sqrt(-2 * math.log(1 - math.random())) * math.cos(2 * math.pi * math.random())
|
|
24
25
|
end
|
|
25
26
|
|
|
26
27
|
--[=[
|
|
@@ -31,11 +32,7 @@ end
|
|
|
31
32
|
@return Vector3
|
|
32
33
|
]=]
|
|
33
34
|
function RandomVector3Utils.gaussianRandom(mean: Vector3, spread: Vector3): Vector3
|
|
34
|
-
return mean + spread*Vector3.new(
|
|
35
|
-
gaussianRandom(),
|
|
36
|
-
gaussianRandom(),
|
|
37
|
-
gaussianRandom()
|
|
38
|
-
)/math.sqrt(3)
|
|
35
|
+
return mean + spread * Vector3.new(gaussianRandom(), gaussianRandom(), gaussianRandom()) / math.sqrt(3)
|
|
39
36
|
end
|
|
40
37
|
|
|
41
38
|
--[=[
|
|
@@ -50,28 +47,25 @@ function RandomVector3Utils.getDirectedRandomUnitVector(direction: Vector3, angl
|
|
|
50
47
|
assert(typeof(direction) == "Vector3", "Bad direction")
|
|
51
48
|
assert(type(angleRad) == "number", "Bad angleRad")
|
|
52
49
|
|
|
53
|
-
local s = 1 - (1 - math.cos(angleRad))*math.random()
|
|
54
|
-
local t = 6.2831853071796*math.random()
|
|
50
|
+
local s = 1 - (1 - math.cos(angleRad)) * math.random()
|
|
51
|
+
local t = 6.2831853071796 * math.random()
|
|
55
52
|
local rx = s
|
|
56
|
-
local m = (1-s*s)^0.5
|
|
57
|
-
local ry = m*math.cos(t)
|
|
58
|
-
local rz = m*math.sin(t)
|
|
53
|
+
local m = (1 - s * s) ^ 0.5
|
|
54
|
+
local ry = m * math.cos(t)
|
|
55
|
+
local rz = m * math.sin(t)
|
|
59
56
|
|
|
60
|
-
local dx, dy, dz = direction.
|
|
61
|
-
local d = (dx*dx+dy*dy+dz*dz)^0.5
|
|
57
|
+
local dx, dy, dz = direction.X, direction.Y, direction.Z
|
|
58
|
+
local d = (dx * dx + dy * dy + dz * dz) ^ 0.5
|
|
62
59
|
|
|
63
|
-
if dx/d < -0.9999 then
|
|
60
|
+
if dx / d < -0.9999 then
|
|
64
61
|
return Vector3.new(-rx, ry, rz)
|
|
65
|
-
elseif dx/d < 0.9999 then
|
|
66
|
-
local coef1 = (rx- dx*(dy*ry+dz*rz)/(dy*dy+dz*dz))/d
|
|
67
|
-
local coef2 = (dz*ry-dy*rz)/(dy*dy+dz*dz)
|
|
68
|
-
return Vector3.new(
|
|
69
|
-
(dx*rx+dy*ry+dz*rz)/d,
|
|
70
|
-
dy*coef1+dz*coef2,
|
|
71
|
-
dz*coef1-dy*coef2)
|
|
62
|
+
elseif dx / d < 0.9999 then
|
|
63
|
+
local coef1 = (rx - dx * (dy * ry + dz * rz) / (dy * dy + dz * dz)) / d
|
|
64
|
+
local coef2 = (dz * ry - dy * rz) / (dy * dy + dz * dz)
|
|
65
|
+
return Vector3.new((dx * rx + dy * ry + dz * rz) / d, dy * coef1 + dz * coef2, dz * coef1 - dy * coef2)
|
|
72
66
|
else
|
|
73
67
|
return Vector3.new(rx, ry, rz)
|
|
74
68
|
end
|
|
75
69
|
end
|
|
76
70
|
|
|
77
|
-
return RandomVector3Utils
|
|
71
|
+
return RandomVector3Utils
|
|
@@ -1,26 +1,47 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class Vector3SerializationUtils
|
|
3
4
|
]=]
|
|
4
5
|
|
|
5
6
|
local Vector3SerializationUtils = {}
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
export type SerializedVector3 = { number }
|
|
9
|
+
|
|
10
|
+
--[=[
|
|
11
|
+
Returns true if this data is a serialized Vector3
|
|
12
|
+
|
|
13
|
+
@param data any
|
|
14
|
+
@return boolean
|
|
15
|
+
]=]
|
|
16
|
+
function Vector3SerializationUtils.isSerializedVector3(data: any): boolean
|
|
8
17
|
return type(data) == "table" and #data == 3
|
|
9
18
|
end
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
--[=[
|
|
21
|
+
Serialized a Vector3 into a Lua table, which should encode in JSON and be network safe.
|
|
22
|
+
|
|
23
|
+
@param vector3 Vector3
|
|
24
|
+
@return SerializedVector3
|
|
25
|
+
]=]
|
|
26
|
+
function Vector3SerializationUtils.serialize(vector3: Vector3): SerializedVector3
|
|
12
27
|
return {
|
|
13
|
-
vector3.
|
|
14
|
-
vector3.
|
|
15
|
-
vector3.
|
|
28
|
+
vector3.X,
|
|
29
|
+
vector3.Y,
|
|
30
|
+
vector3.Z,
|
|
16
31
|
}
|
|
17
32
|
end
|
|
18
33
|
|
|
19
|
-
|
|
34
|
+
--[=[
|
|
35
|
+
Deserializes a Vector3 from a Lua table
|
|
36
|
+
|
|
37
|
+
@param data SerializedVector3
|
|
38
|
+
@return Vector3
|
|
39
|
+
]=]
|
|
40
|
+
function Vector3SerializationUtils.deserialize(data: SerializedVector3): Vector3
|
|
20
41
|
assert(type(data) == "table", "Bad data")
|
|
21
42
|
assert(#data == 3, "Bad data")
|
|
22
43
|
|
|
23
44
|
return Vector3.new(data[1], data[2], data[3])
|
|
24
45
|
end
|
|
25
46
|
|
|
26
|
-
return Vector3SerializationUtils
|
|
47
|
+
return Vector3SerializationUtils
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Utilities involving Vector3 objects in Roblox.
|
|
3
4
|
@class Vector3Utils
|
|
@@ -16,7 +17,7 @@ local Vector3Utils = {}
|
|
|
16
17
|
@return Vector3
|
|
17
18
|
]=]
|
|
18
19
|
function Vector3Utils.fromVector2XY(vector2: Vector2): Vector3
|
|
19
|
-
return Vector3.new(vector2.
|
|
20
|
+
return Vector3.new(vector2.X, vector2.Y, 0)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
--[=[
|
|
@@ -26,7 +27,7 @@ end
|
|
|
26
27
|
@return Vector3
|
|
27
28
|
]=]
|
|
28
29
|
function Vector3Utils.fromVector2XZ(vector2: Vector2): Vector3
|
|
29
|
-
return Vector3.new(vector2.
|
|
30
|
+
return Vector3.new(vector2.X, 0, vector2.Y)
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
--[=[
|
|
@@ -36,8 +37,8 @@ end
|
|
|
36
37
|
@param b Vector3
|
|
37
38
|
@return number?
|
|
38
39
|
]=]
|
|
39
|
-
function Vector3Utils.getAngleRad(a: Vector3, b: Vector3): number
|
|
40
|
-
if a.
|
|
40
|
+
function Vector3Utils.getAngleRad(a: Vector3, b: Vector3): number?
|
|
41
|
+
if a.Magnitude == 0 then
|
|
41
42
|
return nil
|
|
42
43
|
end
|
|
43
44
|
|
|
@@ -52,7 +53,7 @@ end
|
|
|
52
53
|
@return Vector3
|
|
53
54
|
]=]
|
|
54
55
|
function Vector3Utils.reflect(vector: Vector3, unitNormal: Vector3): Vector3
|
|
55
|
-
return vector - 2*(unitNormal*vector:Dot(unitNormal))
|
|
56
|
+
return vector - 2 * (unitNormal * vector:Dot(unitNormal))
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
--[=[
|
|
@@ -63,9 +64,9 @@ end
|
|
|
63
64
|
@return number
|
|
64
65
|
]=]
|
|
65
66
|
function Vector3Utils.angleBetweenVectors(a: Vector3, b: Vector3): number
|
|
66
|
-
local u = b.
|
|
67
|
-
local v = a.
|
|
68
|
-
return 2*math.atan2((v - u).
|
|
67
|
+
local u = b.Magnitude * a
|
|
68
|
+
local v = a.Magnitude * b
|
|
69
|
+
return 2 * math.atan2((v - u).Magnitude, (u + v).Magnitude)
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
--[=[
|
|
@@ -76,12 +77,12 @@ end
|
|
|
76
77
|
@param t number -- Amount to slerp. 0 is start, 1 is finish. beyond that is extended as expected.
|
|
77
78
|
@return Vector3
|
|
78
79
|
]=]
|
|
79
|
-
function Vector3Utils.slerp(start: Vector3, finish: Vector3, t: number)
|
|
80
|
+
function Vector3Utils.slerp(start: Vector3, finish: Vector3, t: number): Vector3
|
|
80
81
|
local dot = math.clamp(start:Dot(finish), -1, 1)
|
|
81
82
|
|
|
82
|
-
local theta = math.acos(dot)*t
|
|
83
|
-
local relVec = (finish - start*dot).
|
|
84
|
-
return ((start*math.cos(theta)) + (relVec*math.sin(theta)))
|
|
83
|
+
local theta = math.acos(dot) * t
|
|
84
|
+
local relVec = (finish - start * dot).Unit
|
|
85
|
+
return ((start * math.cos(theta)) + (relVec * math.sin(theta)))
|
|
85
86
|
end
|
|
86
87
|
|
|
87
88
|
--[=[
|
|
@@ -94,11 +95,11 @@ end
|
|
|
94
95
|
]=]
|
|
95
96
|
function Vector3Utils.constrainToCone(direction: Vector3, coneDirection: Vector3, coneAngleRad: number): Vector3
|
|
96
97
|
local angle = Vector3Utils.angleBetweenVectors(direction, coneDirection)
|
|
97
|
-
local coneHalfAngle = 0.5*coneAngleRad
|
|
98
|
+
local coneHalfAngle = 0.5 * coneAngleRad
|
|
98
99
|
|
|
99
100
|
if angle > coneHalfAngle then
|
|
100
101
|
local proportion = coneHalfAngle / angle
|
|
101
|
-
return Vector3Utils.slerp(coneDirection.
|
|
102
|
+
return Vector3Utils.slerp(coneDirection.Unit, direction.Unit, proportion) * direction.Magnitude
|
|
102
103
|
end
|
|
103
104
|
|
|
104
105
|
return direction
|
|
@@ -116,8 +117,8 @@ end
|
|
|
116
117
|
@param amount number
|
|
117
118
|
@return Vector3
|
|
118
119
|
]=]
|
|
119
|
-
function Vector3Utils.round(vector3: Vector3, amount: number):
|
|
120
|
-
return Vector3.new(Math.round(vector3.
|
|
120
|
+
function Vector3Utils.round(vector3: Vector3, amount: number): Vector3
|
|
121
|
+
return Vector3.new(Math.round(vector3.X, amount), Math.round(vector3.Y, amount), Math.round(vector3.Z, amount))
|
|
121
122
|
end
|
|
122
123
|
|
|
123
124
|
--[=[
|
|
@@ -128,12 +129,10 @@ end
|
|
|
128
129
|
@param epsilon number
|
|
129
130
|
@return boolean
|
|
130
131
|
]=]
|
|
131
|
-
function Vector3Utils.areClose(a, b, epsilon)
|
|
132
|
+
function Vector3Utils.areClose(a: Vector3, b: Vector3, epsilon: number): boolean
|
|
132
133
|
assert(type(epsilon) == "number", "Bad epsilon")
|
|
133
134
|
|
|
134
|
-
return math.abs(a.
|
|
135
|
-
and math.abs(a.y - b.y) <= epsilon
|
|
136
|
-
and math.abs(a.z - b.z) <= epsilon
|
|
135
|
+
return math.abs(a.X - b.X) <= epsilon and math.abs(a.Y - b.Y) <= epsilon and math.abs(a.Z - b.Z) <= epsilon
|
|
137
136
|
end
|
|
138
137
|
|
|
139
|
-
return Vector3Utils
|
|
138
|
+
return Vector3Utils
|