@quenty/ik 15.24.4-canary.559.9f38947.0 → 15.25.0-canary.0a5db80.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 +2 -10
- package/package.json +26 -26
- package/src/Client/GripPointer.lua +1 -1
- package/src/Client/IKServiceClient.lua +1 -1
- package/src/Client/Rig/IKRigAimerLocalPlayer.lua +3 -3
- package/src/Client/Rig/IKRigClient.lua +1 -1
- package/src/Server/Rig/IKRig.lua +1 -1
- package/src/Shared/Arm/ArmIKBase.lua +104 -148
- package/src/Shared/Arm/ArmIKBase.story.lua +5 -5
- package/src/Shared/Arm/ArmIKUtils.lua +4 -10
- package/src/Shared/Arm/IKAimPositionPriorites.lua +5 -5
- package/src/Shared/Grip/IKGripBase.lua +10 -9
- package/src/Shared/Grip/IKGripUtils.lua +1 -1
- package/src/Shared/Grip/IKLeftGrip.lua +2 -2
- package/src/Shared/Grip/IKRightGrip.lua +2 -2
- package/src/Shared/IKDataService.lua +1 -1
- package/src/Shared/IKUtils.lua +4 -8
- package/src/Shared/Interfaces/IKRigInterface.lua +8 -8
- package/src/Shared/Resources/IKResource.lua +2 -2
- package/src/Shared/Resources/IKResourceUtils.lua +1 -1
- package/src/Shared/Rig/IKRigBase.lua +4 -4
- package/src/Shared/Rig/IKRigUtils.lua +1 -1
- package/src/Shared/Torso/TorsoIKBase.lua +2 -2
- package/src/Shared/Torso/TorsoIKUtils.lua +20 -11
- package/test/scripts/Server/ServerMain.server.lua +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,20 +3,12 @@
|
|
|
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
|
-
|
|
6
|
+
# [15.25.0-canary.0a5db80.0](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ik@15.24.2...@quenty/ik@15.25.0-canary.0a5db80.0) (2025-05-10)
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
### Bug Fixes
|
|
10
10
|
|
|
11
|
-
* Additional type checking updates ([
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
## [15.24.3](https://github.com/Quenty/NevermoreEngine/compare/@quenty/ik@15.24.2...@quenty/ik@15.24.3) (2025-04-10)
|
|
18
|
-
|
|
19
|
-
**Note:** Version bump only for package @quenty/ik
|
|
11
|
+
* Additional type checking updates ([7e008c5](https://github.com/Quenty/NevermoreEngine/commit/7e008c58547bd00b5904e56541454a38c8d72ccc))
|
|
20
12
|
|
|
21
13
|
|
|
22
14
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/ik",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.25.0-canary.0a5db80.0",
|
|
4
4
|
"description": "Inverse Kinematics for characters on Roblox",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,36 +26,36 @@
|
|
|
26
26
|
"Quenty"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@quenty/acceltween": "2.
|
|
30
|
-
"@quenty/baseobject": "10.
|
|
31
|
-
"@quenty/binder": "14.
|
|
32
|
-
"@quenty/brio": "14.
|
|
33
|
-
"@quenty/camera": "14.
|
|
34
|
-
"@quenty/characterutils": "12.
|
|
35
|
-
"@quenty/humanoidtracker": "13.
|
|
36
|
-
"@quenty/instanceutils": "13.
|
|
37
|
-
"@quenty/loader": "10.
|
|
38
|
-
"@quenty/maid": "3.
|
|
29
|
+
"@quenty/acceltween": "2.6.0-canary.0a5db80.0",
|
|
30
|
+
"@quenty/baseobject": "10.9.0-canary.0a5db80.0",
|
|
31
|
+
"@quenty/binder": "14.20.0-canary.0a5db80.0",
|
|
32
|
+
"@quenty/brio": "14.18.0-canary.0a5db80.0",
|
|
33
|
+
"@quenty/camera": "14.21.0-canary.0a5db80.0",
|
|
34
|
+
"@quenty/characterutils": "12.19.0-canary.0a5db80.0",
|
|
35
|
+
"@quenty/humanoidtracker": "13.18.0-canary.0a5db80.0",
|
|
36
|
+
"@quenty/instanceutils": "13.18.0-canary.0a5db80.0",
|
|
37
|
+
"@quenty/loader": "10.9.0-canary.0a5db80.0",
|
|
38
|
+
"@quenty/maid": "3.5.0-canary.0a5db80.0",
|
|
39
39
|
"@quenty/math": "2.7.3",
|
|
40
|
-
"@quenty/motor6d": "7.
|
|
41
|
-
"@quenty/optional": "11.
|
|
42
|
-
"@quenty/promise": "10.
|
|
43
|
-
"@quenty/qframe": "10.
|
|
44
|
-
"@quenty/r15utils": "13.
|
|
45
|
-
"@quenty/ragdoll": "15.
|
|
46
|
-
"@quenty/remoting": "12.
|
|
47
|
-
"@quenty/rx": "13.
|
|
48
|
-
"@quenty/servicebag": "11.
|
|
49
|
-
"@quenty/signal": "7.
|
|
50
|
-
"@quenty/table": "3.
|
|
51
|
-
"@quenty/tie": "10.
|
|
52
|
-
"@quenty/valueobject": "13.
|
|
40
|
+
"@quenty/motor6d": "7.21.0-canary.0a5db80.0",
|
|
41
|
+
"@quenty/optional": "11.9.0-canary.0a5db80.0",
|
|
42
|
+
"@quenty/promise": "10.11.0-canary.0a5db80.0",
|
|
43
|
+
"@quenty/qframe": "10.11.0-canary.0a5db80.0",
|
|
44
|
+
"@quenty/r15utils": "13.18.0-canary.0a5db80.0",
|
|
45
|
+
"@quenty/ragdoll": "15.24.0-canary.0a5db80.0",
|
|
46
|
+
"@quenty/remoting": "12.19.0-canary.0a5db80.0",
|
|
47
|
+
"@quenty/rx": "13.18.0-canary.0a5db80.0",
|
|
48
|
+
"@quenty/servicebag": "11.12.0-canary.0a5db80.0",
|
|
49
|
+
"@quenty/signal": "7.11.0-canary.0a5db80.0",
|
|
50
|
+
"@quenty/table": "3.8.0-canary.0a5db80.0",
|
|
51
|
+
"@quenty/tie": "10.21.0-canary.0a5db80.0",
|
|
52
|
+
"@quenty/valueobject": "13.18.0-canary.0a5db80.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@quenty/rigbuilderutils": "10.
|
|
55
|
+
"@quenty/rigbuilderutils": "10.20.0-canary.0a5db80.0"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "0a5db8004684dc3e76fd5944599a22602d48cfa9"
|
|
61
61
|
}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
local require = require(script.Parent.loader).load(script)
|
|
14
14
|
|
|
15
|
-
local Players = game:GetService("Players")
|
|
16
15
|
local RunService = game:GetService("RunService")
|
|
17
16
|
local Workspace = game:GetService("Workspace")
|
|
17
|
+
local Players = game:GetService("Players")
|
|
18
18
|
|
|
19
19
|
local IKRigUtils = require("IKRigUtils")
|
|
20
20
|
local Maid = require("Maid")
|
|
@@ -81,7 +81,7 @@ function IKRigAimerLocalPlayer:PushReplicationRate(replicateRate: number)
|
|
|
81
81
|
assert(type(replicateRate) == "number", "Bad replicateRate")
|
|
82
82
|
|
|
83
83
|
local data = {
|
|
84
|
-
replicateRate = replicateRate
|
|
84
|
+
replicateRate = replicateRate;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
table.insert(self._replicationRates, data)
|
|
@@ -118,7 +118,7 @@ end
|
|
|
118
118
|
]=]
|
|
119
119
|
function IKRigAimerLocalPlayer:GetAimPosition()
|
|
120
120
|
if self._aimData and (os.clock() - self._aimData.timeStamp) < MAX_AGE_FOR_AIM_DATA then
|
|
121
|
-
|
|
121
|
+
-- If we have aim data within the last 0.2 seconds start pointing at that
|
|
122
122
|
return self._aimData.position -- May be nil
|
|
123
123
|
end
|
|
124
124
|
|
|
@@ -173,4 +173,4 @@ function IKRigAimerLocalPlayer:UpdateStepped()
|
|
|
173
173
|
end
|
|
174
174
|
end
|
|
175
175
|
|
|
176
|
-
return IKRigAimerLocalPlayer
|
|
176
|
+
return IKRigAimerLocalPlayer
|
package/src/Server/Rig/IKRig.lua
CHANGED
|
@@ -20,9 +20,9 @@ local Rx = require("Rx")
|
|
|
20
20
|
local RxBrioUtils = require("RxBrioUtils")
|
|
21
21
|
local RxInstanceUtils = require("RxInstanceUtils")
|
|
22
22
|
local RxR15Utils = require("RxR15Utils")
|
|
23
|
-
local ServiceBag = require("ServiceBag")
|
|
24
|
-
local TieRealmService = require("TieRealmService")
|
|
25
23
|
local ValueObject = require("ValueObject")
|
|
24
|
+
local TieRealmService = require("TieRealmService")
|
|
25
|
+
local ServiceBag = require("ServiceBag")
|
|
26
26
|
|
|
27
27
|
local CFA_90X = CFrame.Angles(math.pi / 2, 0, 0)
|
|
28
28
|
local USE_OLD_IK_SYSTEM = (not LimbIKUtils) or false
|
|
@@ -101,7 +101,7 @@ function ArmIKBase:_startUpdateLoop(character)
|
|
|
101
101
|
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "LowerArm", self._armName .. "Elbow", function()
|
|
102
102
|
return self._elbowTransform
|
|
103
103
|
end))
|
|
104
|
-
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "Hand", self._armName ..
|
|
104
|
+
maid:GiveTask(self:_ensureAnimator(character, self._armName .. "Hand", self._armName .."Wrist", function()
|
|
105
105
|
return self._wristTransform
|
|
106
106
|
end))
|
|
107
107
|
|
|
@@ -111,33 +111,31 @@ end
|
|
|
111
111
|
function ArmIKBase:_ensureAnimator(character, partName, motorName, getTranform)
|
|
112
112
|
local topMaid = Maid.new()
|
|
113
113
|
|
|
114
|
-
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, partName, motorName)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return
|
|
123
|
-
end
|
|
114
|
+
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, partName, motorName):Pipe({
|
|
115
|
+
RxBrioUtils.switchMapBrio(function(motor)
|
|
116
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(motor, self._tieRealmService:GetTieRealm())
|
|
117
|
+
end);
|
|
118
|
+
}):Subscribe(function(brio)
|
|
119
|
+
if brio:IsDead() then
|
|
120
|
+
return
|
|
121
|
+
end
|
|
124
122
|
|
|
125
|
-
|
|
123
|
+
local maid, motor6DStack = brio:ToMaidAndValue()
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
local transformer = Motor6DSmoothTransformer.new(getTranform)
|
|
126
|
+
transformer:SetTarget(1)
|
|
129
127
|
|
|
130
|
-
|
|
128
|
+
local cleanup = motor6DStack:Push(transformer)
|
|
131
129
|
|
|
132
|
-
|
|
133
|
-
|
|
130
|
+
maid:GiveTask(function()
|
|
131
|
+
transformer:SetTarget(0)
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
end)
|
|
133
|
+
task.delay(2, function()
|
|
134
|
+
transformer:Destroy()
|
|
135
|
+
cleanup()
|
|
139
136
|
end)
|
|
140
|
-
end)
|
|
137
|
+
end)
|
|
138
|
+
end))
|
|
141
139
|
|
|
142
140
|
return topMaid
|
|
143
141
|
end
|
|
@@ -150,155 +148,116 @@ function ArmIKBase:_observeCharacterBrio()
|
|
|
150
148
|
self._characterObservable = RxInstanceUtils.observePropertyBrio(self._humanoid, "Parent", function(parent)
|
|
151
149
|
return parent ~= nil
|
|
152
150
|
end):Pipe({
|
|
153
|
-
Rx.shareReplay(1)
|
|
151
|
+
Rx.shareReplay(1);
|
|
154
152
|
})
|
|
155
153
|
|
|
156
154
|
return self._characterObservable
|
|
157
155
|
end
|
|
158
156
|
|
|
157
|
+
|
|
159
158
|
function ArmIKBase:_observeStateBrio()
|
|
160
159
|
return self:_observeCharacterBrio():Pipe({
|
|
161
160
|
RxBrioUtils.switchMapBrio(function(character)
|
|
162
|
-
local observeUpperTorsoBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", "UpperTorso")
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
local observeHandBrio =
|
|
175
|
-
RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "Hand"):Pipe({
|
|
176
|
-
Rx.shareReplay(1),
|
|
177
|
-
})
|
|
161
|
+
local observeUpperTorsoBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", "UpperTorso"):Pipe({
|
|
162
|
+
Rx.shareReplay(1);
|
|
163
|
+
})
|
|
164
|
+
local observeUpperArmBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "UpperArm"):Pipe({
|
|
165
|
+
Rx.shareReplay(1);
|
|
166
|
+
})
|
|
167
|
+
local observeLowerArmBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "LowerArm"):Pipe({
|
|
168
|
+
Rx.shareReplay(1);
|
|
169
|
+
})
|
|
170
|
+
local observeHandBrio = RxInstanceUtils.observeLastNamedChildBrio(character, "BasePart", self._armName .. "Hand"):Pipe({
|
|
171
|
+
Rx.shareReplay(1);
|
|
172
|
+
})
|
|
178
173
|
|
|
179
174
|
local observeShoulderBrio = observeUpperArmBrio:Pipe({
|
|
180
175
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
181
176
|
return RxInstanceUtils.observeLastNamedChildBrio(upperArm, "Motor6D", self._armName .. "Shoulder")
|
|
182
|
-
end)
|
|
183
|
-
Rx.shareReplay(1)
|
|
177
|
+
end);
|
|
178
|
+
Rx.shareReplay(1);
|
|
184
179
|
})
|
|
185
180
|
local observeElbowBrio = observeLowerArmBrio:Pipe({
|
|
186
181
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
187
182
|
return RxInstanceUtils.observeLastNamedChildBrio(lowerArm, "Motor6D", self._armName .. "Elbow")
|
|
188
|
-
end)
|
|
189
|
-
Rx.shareReplay(1)
|
|
183
|
+
end);
|
|
184
|
+
Rx.shareReplay(1);
|
|
190
185
|
})
|
|
191
186
|
local observeWristBrio = observeHandBrio:Pipe({
|
|
192
187
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
193
188
|
return RxInstanceUtils.observeLastNamedChildBrio(hand, "Motor6D", self._armName .. "Wrist")
|
|
194
|
-
end)
|
|
195
|
-
Rx.shareReplay(1)
|
|
189
|
+
end);
|
|
190
|
+
Rx.shareReplay(1);
|
|
196
191
|
})
|
|
197
192
|
|
|
198
193
|
return RxBrioUtils.flatCombineLatest({
|
|
199
|
-
UpperTorso = observeUpperTorsoBrio
|
|
200
|
-
UpperArm = observeUpperArmBrio
|
|
201
|
-
LowerArm = observeLowerArmBrio
|
|
202
|
-
Hand = observeHandBrio
|
|
194
|
+
UpperTorso = observeUpperTorsoBrio;
|
|
195
|
+
UpperArm = observeUpperArmBrio;
|
|
196
|
+
LowerArm = observeLowerArmBrio;
|
|
197
|
+
Hand = observeHandBrio;
|
|
203
198
|
|
|
204
|
-
Shoulder = observeShoulderBrio
|
|
205
|
-
Elbow = observeElbowBrio
|
|
206
|
-
Wrist = observeWristBrio
|
|
199
|
+
Shoulder = observeShoulderBrio;
|
|
200
|
+
Elbow = observeElbowBrio;
|
|
201
|
+
Wrist = observeWristBrio;
|
|
207
202
|
|
|
208
203
|
ShoulderMotor6DStack = observeShoulderBrio:Pipe({
|
|
209
204
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
210
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
end),
|
|
215
|
-
Rx.defaultsToNil,
|
|
216
|
-
}),
|
|
205
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(motor, self._tieRealmService:GetTieRealm())
|
|
206
|
+
end);
|
|
207
|
+
Rx.defaultsToNil;
|
|
208
|
+
});
|
|
217
209
|
ElbowMotor6DStack = observeElbowBrio:Pipe({
|
|
218
210
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
219
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
end),
|
|
224
|
-
Rx.defaultsToNil,
|
|
225
|
-
}),
|
|
211
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(motor, self._tieRealmService:GetTieRealm())
|
|
212
|
+
end);
|
|
213
|
+
Rx.defaultsToNil;
|
|
214
|
+
});
|
|
226
215
|
WristMotor6DStack = observeWristBrio:Pipe({
|
|
227
216
|
RxBrioUtils.switchMapBrio(function(motor)
|
|
228
|
-
return Motor6DStackInterface:ObserveLastImplementationBrio(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
end),
|
|
233
|
-
Rx.defaultsToNil,
|
|
234
|
-
}),
|
|
217
|
+
return Motor6DStackInterface:ObserveLastImplementationBrio(motor, self._tieRealmService:GetTieRealm())
|
|
218
|
+
end);
|
|
219
|
+
Rx.defaultsToNil;
|
|
220
|
+
});
|
|
235
221
|
|
|
236
222
|
UpperTorsoShoulderRigAttachment = observeUpperTorsoBrio:Pipe({
|
|
237
223
|
RxBrioUtils.switchMapBrio(function(upperTorso)
|
|
238
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
self._armName .. "ShoulderRigAttachment"
|
|
242
|
-
)
|
|
243
|
-
end),
|
|
244
|
-
}),
|
|
224
|
+
return RxInstanceUtils.observeLastNamedChildBrio(upperTorso, "Attachment", self._armName .. "ShoulderRigAttachment")
|
|
225
|
+
end)
|
|
226
|
+
});
|
|
245
227
|
UpperArmShoulderRigAttachment = observeUpperArmBrio:Pipe({
|
|
246
228
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
247
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
self._armName .. "ShoulderRigAttachment"
|
|
251
|
-
)
|
|
252
|
-
end),
|
|
253
|
-
}),
|
|
229
|
+
return RxInstanceUtils.observeLastNamedChildBrio(upperArm, "Attachment", self._armName .. "ShoulderRigAttachment")
|
|
230
|
+
end)
|
|
231
|
+
});
|
|
254
232
|
UpperArmElbowRigAttachment = observeUpperArmBrio:Pipe({
|
|
255
233
|
RxBrioUtils.switchMapBrio(function(upperArm)
|
|
256
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
self._armName .. "ElbowRigAttachment"
|
|
260
|
-
)
|
|
261
|
-
end),
|
|
262
|
-
}),
|
|
234
|
+
return RxInstanceUtils.observeLastNamedChildBrio(upperArm, "Attachment", self._armName .. "ElbowRigAttachment")
|
|
235
|
+
end)
|
|
236
|
+
});
|
|
263
237
|
LowerArmElbowRigAttachment = observeLowerArmBrio:Pipe({
|
|
264
238
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
265
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
self._armName .. "ElbowRigAttachment"
|
|
269
|
-
)
|
|
270
|
-
end),
|
|
271
|
-
}),
|
|
239
|
+
return RxInstanceUtils.observeLastNamedChildBrio(lowerArm, "Attachment", self._armName .. "ElbowRigAttachment")
|
|
240
|
+
end)
|
|
241
|
+
});
|
|
272
242
|
LowerArmWristRigAttachment = observeLowerArmBrio:Pipe({
|
|
273
243
|
RxBrioUtils.switchMapBrio(function(lowerArm)
|
|
274
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
self._armName .. "WristRigAttachment"
|
|
278
|
-
)
|
|
279
|
-
end),
|
|
280
|
-
}),
|
|
244
|
+
return RxInstanceUtils.observeLastNamedChildBrio(lowerArm, "Attachment", self._armName .. "WristRigAttachment")
|
|
245
|
+
end)
|
|
246
|
+
});
|
|
281
247
|
HandWristRigAttachment = observeHandBrio:Pipe({
|
|
282
248
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
283
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
self._armName .. "WristRigAttachment"
|
|
287
|
-
)
|
|
288
|
-
end),
|
|
289
|
-
}),
|
|
249
|
+
return RxInstanceUtils.observeLastNamedChildBrio(hand, "Attachment", self._armName .. "WristRigAttachment")
|
|
250
|
+
end)
|
|
251
|
+
});
|
|
290
252
|
HandGripAttachment = observeHandBrio:Pipe({
|
|
291
253
|
RxBrioUtils.switchMapBrio(function(hand)
|
|
292
|
-
return RxInstanceUtils.observeLastNamedChildBrio(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
self._armName .. "GripAttachment"
|
|
296
|
-
)
|
|
297
|
-
end),
|
|
298
|
-
}),
|
|
254
|
+
return RxInstanceUtils.observeLastNamedChildBrio(hand, "Attachment", self._armName .. "GripAttachment")
|
|
255
|
+
end)
|
|
256
|
+
});
|
|
299
257
|
})
|
|
300
|
-
end)
|
|
301
|
-
Rx.throttleDefer()
|
|
258
|
+
end);
|
|
259
|
+
Rx.throttleDefer();
|
|
260
|
+
|
|
302
261
|
})
|
|
303
262
|
end
|
|
304
263
|
|
|
@@ -309,8 +268,8 @@ function ArmIKBase:Grip(attachment, priority)
|
|
|
309
268
|
priority = priority or IKAimPositionPriorites.DEFAULT
|
|
310
269
|
|
|
311
270
|
local gripData = {
|
|
312
|
-
attachment = attachment
|
|
313
|
-
priority = priority
|
|
271
|
+
attachment = attachment;
|
|
272
|
+
priority = priority;
|
|
314
273
|
}
|
|
315
274
|
|
|
316
275
|
local i = 1
|
|
@@ -389,6 +348,7 @@ else
|
|
|
389
348
|
end
|
|
390
349
|
end
|
|
391
350
|
|
|
351
|
+
|
|
392
352
|
if USE_OLD_IK_SYSTEM then
|
|
393
353
|
function ArmIKBase:Update()
|
|
394
354
|
if self:_oldUpdatePoint() then
|
|
@@ -453,17 +413,13 @@ function ArmIKBase:_newUpdate()
|
|
|
453
413
|
local handWristRigAttachment = self._lastState["HandWristRigAttachment"]
|
|
454
414
|
local handGripAttachment = self._lastState["HandGripAttachment"]
|
|
455
415
|
|
|
456
|
-
if
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
and handWristRigAttachment
|
|
464
|
-
and handGripAttachment
|
|
465
|
-
)
|
|
466
|
-
then
|
|
416
|
+
if not (upperTorsoShoulderRigAttachment
|
|
417
|
+
and upperArmShoulderRigAttachment
|
|
418
|
+
and upperArmElbowRigAttachment
|
|
419
|
+
and lowerArmElbowRigAttachment
|
|
420
|
+
and lowerArmWristRigAttachment
|
|
421
|
+
and handWristRigAttachment
|
|
422
|
+
and handGripAttachment) then
|
|
467
423
|
return false
|
|
468
424
|
end
|
|
469
425
|
|
|
@@ -477,11 +433,7 @@ function ArmIKBase:_newUpdate()
|
|
|
477
433
|
|
|
478
434
|
-- TODO: Allow configuration
|
|
479
435
|
local ELBOW_ANGLE = math.rad(20)
|
|
480
|
-
local shoulderQFrame, elbowQFrame, wristQFrame = LimbIKUtils.solveLimb(
|
|
481
|
-
config,
|
|
482
|
-
QFrame.fromCFrameClosestTo(relTargetCFrame, QFrame.new()),
|
|
483
|
-
self._direction * ELBOW_ANGLE
|
|
484
|
-
)
|
|
436
|
+
local shoulderQFrame, elbowQFrame, wristQFrame = LimbIKUtils.solveLimb(config, QFrame.fromCFrameClosestTo(relTargetCFrame, QFrame.new()), self._direction*ELBOW_ANGLE)
|
|
485
437
|
|
|
486
438
|
self._shoulderTransform = QFrame.toCFrame(shoulderQFrame)
|
|
487
439
|
self._elbowTransform = QFrame.toCFrame(elbowQFrame)
|
|
@@ -499,7 +451,10 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
499
451
|
local elbow = self._lastState["Elbow"]
|
|
500
452
|
local wrist = self._lastState["Wrist"]
|
|
501
453
|
local gripAttachment = self._lastState["HandGripAttachment"]
|
|
502
|
-
if not (shoulder
|
|
454
|
+
if not (shoulder
|
|
455
|
+
and elbow
|
|
456
|
+
and wrist
|
|
457
|
+
and gripAttachment) then
|
|
503
458
|
return false
|
|
504
459
|
end
|
|
505
460
|
|
|
@@ -535,8 +490,8 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
535
490
|
end
|
|
536
491
|
|
|
537
492
|
elbowAngle = (elbowAngle - math.pi)
|
|
538
|
-
if elbowAngle > -math.pi
|
|
539
|
-
elbowAngle = -math.pi
|
|
493
|
+
if elbowAngle > -math.pi/32 then -- Force a bit of bent elbow
|
|
494
|
+
elbowAngle = -math.pi/32
|
|
540
495
|
end
|
|
541
496
|
|
|
542
497
|
self._shoulderXAngle = -baseAngle
|
|
@@ -546,4 +501,5 @@ function ArmIKBase:_oldCalculatePoint(targetPositionWorld)
|
|
|
546
501
|
return true
|
|
547
502
|
end
|
|
548
503
|
|
|
549
|
-
|
|
504
|
+
|
|
505
|
+
return ArmIKBase
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
@class ArmIKBase.story
|
|
3
3
|
]]
|
|
4
4
|
|
|
5
|
-
local require =
|
|
6
|
-
require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
|
|
5
|
+
local require = require(game:GetService("ServerScriptService"):FindFirstChild("LoaderUtils", true).Parent).bootstrapStory(script)
|
|
7
6
|
|
|
8
|
-
local RunService = game:GetService("RunService")
|
|
9
7
|
local Workspace = game:GetService("Workspace")
|
|
8
|
+
local RunService = game:GetService("RunService")
|
|
10
9
|
|
|
11
|
-
local ArmIKBase = require("ArmIKBase")
|
|
12
10
|
local Maid = require("Maid")
|
|
13
11
|
local RigBuilderUtils = require("RigBuilderUtils")
|
|
12
|
+
local ArmIKBase = require("ArmIKBase")
|
|
14
13
|
local ServiceBag = require("ServiceBag")
|
|
15
14
|
|
|
16
15
|
return function(_target)
|
|
@@ -43,7 +42,8 @@ return function(_target)
|
|
|
43
42
|
end))
|
|
44
43
|
end)
|
|
45
44
|
|
|
45
|
+
|
|
46
46
|
return function()
|
|
47
47
|
maid:DoCleaning()
|
|
48
48
|
end
|
|
49
|
-
end
|
|
49
|
+
end
|
|
@@ -27,17 +27,11 @@ function ArmIKUtils.ensureMotorAnimated(character: Model, armName)
|
|
|
27
27
|
end)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
topMaid:GiveTask(
|
|
31
|
-
|
|
32
|
-
)
|
|
33
|
-
topMaid:GiveTask(
|
|
34
|
-
RxR15Utils.observeRigMotorBrio(character, armName .. "LowerArm", armName .. "Elbow"):Subscribe(disable)
|
|
35
|
-
)
|
|
36
|
-
topMaid:GiveTask(
|
|
37
|
-
RxR15Utils.observeRigMotorBrio(character, armName .. "Hand", armName .. "Wrist"):Subscribe(disable)
|
|
38
|
-
)
|
|
30
|
+
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, armName .. "UpperArm", armName .. "Shoulder"):Subscribe(disable))
|
|
31
|
+
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, armName .. "LowerArm", armName .. "Elbow"):Subscribe(disable))
|
|
32
|
+
topMaid:GiveTask(RxR15Utils.observeRigMotorBrio(character, armName .. "Hand", armName .."Wrist"):Subscribe(disable))
|
|
39
33
|
|
|
40
34
|
return topMaid
|
|
41
35
|
end
|
|
42
36
|
|
|
43
|
-
return ArmIKUtils
|
|
37
|
+
return ArmIKUtils
|
|
@@ -7,8 +7,8 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
7
|
local Table = require("Table")
|
|
8
8
|
|
|
9
9
|
return Table.readonly({
|
|
10
|
-
DEFAULT = 0
|
|
11
|
-
LOW = 1000
|
|
12
|
-
MEDIUM = 3000
|
|
13
|
-
HIGH = 4000
|
|
14
|
-
})
|
|
10
|
+
DEFAULT = 0;
|
|
11
|
+
LOW = 1000;
|
|
12
|
+
MEDIUM = 3000;
|
|
13
|
+
HIGH = 4000;
|
|
14
|
+
})
|
|
@@ -8,9 +8,9 @@ local require = require(script.Parent.loader).load(script)
|
|
|
8
8
|
local RunService = game:GetService("RunService")
|
|
9
9
|
|
|
10
10
|
local BaseObject = require("BaseObject")
|
|
11
|
+
local promisePropertyValue = require("promisePropertyValue")
|
|
11
12
|
local Promise = require("Promise")
|
|
12
13
|
local ServiceBag = require("ServiceBag")
|
|
13
|
-
local promisePropertyValue = require("promisePropertyValue")
|
|
14
14
|
|
|
15
15
|
local IKGripBase = setmetatable({}, BaseObject)
|
|
16
16
|
IKGripBase.ClassName = "IKGripBase"
|
|
@@ -51,16 +51,17 @@ function IKGripBase:PromiseIKRig()
|
|
|
51
51
|
local promise = promisePropertyValue(self._obj, "Value")
|
|
52
52
|
self._maid:GiveTask(promise)
|
|
53
53
|
|
|
54
|
-
self._ikRigPromise = promise
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
self._ikRigPromise = promise
|
|
55
|
+
:Then(function(humanoid)
|
|
56
|
+
if not humanoid:IsA("Humanoid") then
|
|
57
|
+
warn("[IKGripBase.PromiseIKRig] - Humanoid in link is not a humanoid")
|
|
58
|
+
return Promise.rejected()
|
|
59
|
+
end
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
return self._maid:GivePromise(ikService:PromiseRig(humanoid))
|
|
62
|
+
end)
|
|
62
63
|
|
|
63
64
|
return self._ikRigPromise
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
return IKGripBase
|
|
67
|
+
return IKGripBase
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
|
-
local Binder = require("Binder")
|
|
9
8
|
local IKGripBase = require("IKGripBase")
|
|
9
|
+
local Binder = require("Binder")
|
|
10
10
|
local ServiceBag = require("ServiceBag")
|
|
11
11
|
|
|
12
12
|
local IKLeftGrip = setmetatable({}, IKGripBase)
|
|
@@ -27,4 +27,4 @@ function IKLeftGrip.new(objectValue, serviceBag: ServiceBag.ServiceBag)
|
|
|
27
27
|
return self
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
return Binder.new("IKLeftGrip", IKLeftGrip)
|
|
30
|
+
return Binder.new("IKLeftGrip", IKLeftGrip)
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
|
-
local Binder = require("Binder")
|
|
9
8
|
local IKGripBase = require("IKGripBase")
|
|
9
|
+
local Binder = require("Binder")
|
|
10
10
|
local ServiceBag = require("ServiceBag")
|
|
11
11
|
|
|
12
12
|
local IKRightGrip = setmetatable({}, IKGripBase)
|
|
@@ -27,4 +27,4 @@ function IKRightGrip.new(objectValue: ObjectValue, serviceBag: ServiceBag.Servic
|
|
|
27
27
|
return self
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
return Binder.new("IKRightGrip", IKRightGrip)
|
|
30
|
+
return Binder.new("IKRightGrip", IKRightGrip)
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
7
|
local IKRigInterface = require("IKRigInterface")
|
|
8
|
-
local ServiceBag = require("ServiceBag")
|
|
9
8
|
local TieRealmService = require("TieRealmService")
|
|
9
|
+
local ServiceBag = require("ServiceBag")
|
|
10
10
|
|
|
11
11
|
local IKDataService = {}
|
|
12
12
|
IKDataService.ServiceName = "IKDataService"
|
package/src/Shared/IKUtils.lua
CHANGED
|
@@ -6,11 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
local IKUtils = {}
|
|
8
8
|
|
|
9
|
-
function IKUtils.getDampenedAngleClamp(
|
|
10
|
-
maxAngle: number,
|
|
11
|
-
dampenAreaAngle: number,
|
|
12
|
-
dampenAreaFactor: number?
|
|
13
|
-
): (number) -> number
|
|
9
|
+
function IKUtils.getDampenedAngleClamp(maxAngle: number, dampenAreaAngle: number, dampenAreaFactor: number?): (number) -> number
|
|
14
10
|
local areaFactor = dampenAreaFactor or dampenAreaAngle
|
|
15
11
|
|
|
16
12
|
return function(angle)
|
|
@@ -21,11 +17,11 @@ function IKUtils.getDampenedAngleClamp(
|
|
|
21
17
|
-- dampenAreaFactor is the area that the bouncing happens
|
|
22
18
|
-- dampenAreaAngle is the amount of bounce that occurs
|
|
23
19
|
local timesOver = (math.abs(angle) - min) / areaFactor
|
|
24
|
-
local scale = (1 - 0.5
|
|
20
|
+
local scale = (1 - 0.5^timesOver)
|
|
25
21
|
|
|
26
|
-
return math.sign(angle) * (min + (scale
|
|
22
|
+
return math.sign(angle) * (min + (scale*dampenAreaAngle))
|
|
27
23
|
end
|
|
28
24
|
end
|
|
29
25
|
end
|
|
30
26
|
|
|
31
|
-
return IKUtils
|
|
27
|
+
return IKUtils
|
|
@@ -7,13 +7,13 @@ local require = require(script.Parent.loader).load(script)
|
|
|
7
7
|
local TieDefinition = require("TieDefinition")
|
|
8
8
|
|
|
9
9
|
return TieDefinition.new("IKRig", {
|
|
10
|
-
GetPlayer = TieDefinition.Types.METHOD
|
|
11
|
-
GetHumanoid = TieDefinition.Types.METHOD
|
|
10
|
+
GetPlayer = TieDefinition.Types.METHOD;
|
|
11
|
+
GetHumanoid = TieDefinition.Types.METHOD;
|
|
12
12
|
|
|
13
|
-
PromiseLeftArm = TieDefinition.Types.METHOD
|
|
14
|
-
PromiseRightArm = TieDefinition.Types.METHOD
|
|
15
|
-
GetLeftArm = TieDefinition.Types.METHOD
|
|
16
|
-
GetRightArm = TieDefinition.Types.METHOD
|
|
13
|
+
PromiseLeftArm = TieDefinition.Types.METHOD;
|
|
14
|
+
PromiseRightArm = TieDefinition.Types.METHOD;
|
|
15
|
+
GetLeftArm = TieDefinition.Types.METHOD;
|
|
16
|
+
GetRightArm = TieDefinition.Types.METHOD;
|
|
17
17
|
|
|
18
|
-
GetAimPosition = TieDefinition.Types.METHOD
|
|
19
|
-
})
|
|
18
|
+
GetAimPosition = TieDefinition.Types.METHOD;
|
|
19
|
+
})
|
|
@@ -22,7 +22,7 @@ function IKResource.new(data)
|
|
|
22
22
|
self._instance = nil
|
|
23
23
|
self._childResourceMap = {} -- [robloxName] = { data = data; ikResource = ikResource }
|
|
24
24
|
self._descendantLookupMap = {
|
|
25
|
-
[data.name] = self
|
|
25
|
+
[data.name] = self;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
self._ready = self._maid:Add(ValueObject.new(false, "boolean"))
|
|
@@ -194,4 +194,4 @@ function IKResource:_calculateIsReady()
|
|
|
194
194
|
return true
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
-
return IKResource
|
|
197
|
+
return IKResource
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
local require = require(script.Parent.loader).load(script)
|
|
6
6
|
|
|
7
|
-
local ArmIKBase = require("ArmIKBase")
|
|
8
7
|
local BaseObject = require("BaseObject")
|
|
9
|
-
local
|
|
8
|
+
local TorsoIKBase = require("TorsoIKBase")
|
|
10
9
|
local Promise = require("Promise")
|
|
10
|
+
local CharacterUtils = require("CharacterUtils")
|
|
11
11
|
local Signal = require("Signal")
|
|
12
|
-
local
|
|
12
|
+
local ArmIKBase = require("ArmIKBase")
|
|
13
13
|
|
|
14
14
|
local IKRigBase = setmetatable({}, BaseObject)
|
|
15
15
|
IKRigBase.ClassName = "IKRigBase"
|
|
@@ -128,4 +128,4 @@ function IKRigBase:_getNewTorso()
|
|
|
128
128
|
return newIk
|
|
129
129
|
end
|
|
130
130
|
|
|
131
|
-
return IKRigBase
|
|
131
|
+
return IKRigBase
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
local require = require(script.Parent.loader).load(script)
|
|
7
7
|
|
|
8
8
|
local AccelTween = require("AccelTween")
|
|
9
|
+
local TorsoIKUtils = require("TorsoIKUtils")
|
|
10
|
+
local Signal = require("Signal")
|
|
9
11
|
local BaseObject = require("BaseObject")
|
|
10
12
|
local IKResource = require("IKResource")
|
|
11
13
|
local IKResourceUtils = require("IKResourceUtils")
|
|
12
|
-
local Signal = require("Signal")
|
|
13
|
-
local TorsoIKUtils = require("TorsoIKUtils")
|
|
14
14
|
|
|
15
15
|
local TorsoIKBase = setmetatable({}, BaseObject)
|
|
16
16
|
TorsoIKBase.__index = TorsoIKBase
|
|
@@ -10,31 +10,40 @@ local OFFSET_Y = 0.5
|
|
|
10
10
|
|
|
11
11
|
local TorsoIKUtils = {}
|
|
12
12
|
|
|
13
|
-
local waistYawClamper = IKUtils.getDampenedAngleClamp(
|
|
13
|
+
local waistYawClamper = IKUtils.getDampenedAngleClamp(
|
|
14
|
+
math.rad(20),
|
|
15
|
+
math.rad(10))
|
|
14
16
|
local waistPitchClamper = IKUtils.getDampenedAngleClamp(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
math.rad(20), -- TODO: Allow forward bend by 40 degrees
|
|
18
|
+
math.rad(10))
|
|
19
|
+
local headYawClamper = IKUtils.getDampenedAngleClamp(
|
|
20
|
+
math.rad(45),
|
|
21
|
+
math.rad(15))
|
|
22
|
+
local headPitchClamper = IKUtils.getDampenedAngleClamp(
|
|
23
|
+
math.rad(45),
|
|
24
|
+
math.rad(15))
|
|
20
25
|
|
|
21
26
|
function TorsoIKUtils.getTargetAngles(rootPart, target)
|
|
22
|
-
local baseCFrame = rootPart.CFrame
|
|
27
|
+
local baseCFrame = rootPart.CFrame
|
|
28
|
+
* CFrame.new(0, OFFSET_Y, 0)
|
|
23
29
|
|
|
24
30
|
local offsetWaistY = baseCFrame:pointToObjectSpace(target)
|
|
25
31
|
local waistY = waistYawClamper(math.atan2(-offsetWaistY.X, -offsetWaistY.Z))
|
|
26
32
|
|
|
27
|
-
local relativeToWaistY = baseCFrame
|
|
33
|
+
local relativeToWaistY = baseCFrame
|
|
34
|
+
* CFrame.Angles(0, waistY, 0)
|
|
28
35
|
|
|
29
36
|
local headOffsetY = relativeToWaistY:pointToObjectSpace(target)
|
|
30
37
|
local headY = headYawClamper(math.atan2(-headOffsetY.X, -headOffsetY.Z))
|
|
31
38
|
|
|
32
|
-
local relativeToHeadY = relativeToWaistY
|
|
39
|
+
local relativeToHeadY = relativeToWaistY
|
|
40
|
+
* CFrame.Angles(0, headY, 0)
|
|
33
41
|
|
|
34
42
|
local offsetWaistZ = relativeToHeadY:pointToObjectSpace(target)
|
|
35
43
|
local waistZ = waistPitchClamper(math.atan2(offsetWaistZ.Y, -offsetWaistZ.Z))
|
|
36
44
|
|
|
37
|
-
local relativeToEverything = relativeToHeadY
|
|
45
|
+
local relativeToEverything = relativeToHeadY
|
|
46
|
+
* CFrame.Angles(0, 0, waistZ)
|
|
38
47
|
|
|
39
48
|
local headOffsetZ = relativeToEverything:pointToObjectSpace(target)
|
|
40
49
|
local headZ = headPitchClamper(math.atan2(headOffsetZ.Y, -headOffsetZ.Z))
|
|
@@ -42,4 +51,4 @@ function TorsoIKUtils.getTargetAngles(rootPart, target)
|
|
|
42
51
|
return waistY, headY, waistZ, headZ
|
|
43
52
|
end
|
|
44
53
|
|
|
45
|
-
return TorsoIKUtils
|
|
54
|
+
return TorsoIKUtils
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
@class ServerMain
|
|
3
3
|
]]
|
|
4
4
|
|
|
5
|
-
local RunService = game:GetService("RunService")
|
|
6
5
|
local ServerScriptService = game:GetService("ServerScriptService")
|
|
6
|
+
local RunService = game:GetService("RunService")
|
|
7
7
|
|
|
8
8
|
local loader = ServerScriptService:FindFirstChild("LoaderUtils", true).Parent
|
|
9
9
|
local require = require(loader).bootstrapGame(ServerScriptService.ik)
|