@rig-c/play 1.15.0 → 1.16.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/README.md +40 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +143 -9
- package/dist/index.js.map +1 -1
- package/dist/player.d.ts +44 -5
- package/dist/player.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -603,6 +603,46 @@ poses the held pose again at the same time. Two active sets drawing the same
|
|
|
603
603
|
bone are refused by name, as two sets touching one slot are. A `drawn` naming
|
|
604
604
|
a bone the document does not have is refused when `sets.json` is loaded.
|
|
605
605
|
|
|
606
|
+
**Physics under a drawn bone** (#173). A physics chain hung from a bone a set
|
|
607
|
+
re-poses — a sleeve under a raised arm — reads the jump to the drawn angle as
|
|
608
|
+
motion: the constraint remembers where its bone was and pointed, so the
|
|
609
|
+
switch kicks it (on the test rig `drape`, a 110° raise throws the sleeve's
|
|
610
|
+
tip about 297 units off the arm in the switch itself, against an idle
|
|
611
|
+
frame-to-frame range of 1.5). Every set call takes an option for the chains
|
|
612
|
+
under the bones the switch re-poses:
|
|
613
|
+
|
|
614
|
+
```ts
|
|
615
|
+
player.setSets(['raise'], { physics: 'carry' }); // also setSet, addSet, removeSet
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
- `'carry'` moves each affected constraint's remembered state by the rigid
|
|
619
|
+
turn of its deepest re-posed ancestor, so the chain keeps its pose relative
|
|
620
|
+
to the arm and goes on swinging from there (the switch itself moves the
|
|
621
|
+
sleeve 0 relative to the arm; gravity then re-settles it in the turned pose,
|
|
622
|
+
which is physics and not the switch).
|
|
623
|
+
- `'reset'` restarts each affected constraint at the new pose, as a physics
|
|
624
|
+
`reset` key does: the chain snaps straight along its bones (17 units on the
|
|
625
|
+
same raise) and settles from there.
|
|
626
|
+
- Absent, nothing changes: today's behaviour, frame for frame. This stays the
|
|
627
|
+
default.
|
|
628
|
+
|
|
629
|
+
`'carry'` is recommended: on `drape` it moves the sleeve 0 relative to the arm
|
|
630
|
+
at the switch and 0 at the deactivation, where `'reset'` moves it 17 units at
|
|
631
|
+
the switch and 118 at the deactivation (no option: 297 and 298).
|
|
632
|
+
|
|
633
|
+
A constraint is affected when its bone is a bone whose drawn rotation the call
|
|
634
|
+
adds, removes or changes, or a descendant of one; every other chain is not
|
|
635
|
+
touched. The option does nothing before `play` (the setup pose carries no
|
|
636
|
+
physics state) and nothing when no physics hangs under a re-posed bone. Three limits:
|
|
637
|
+
|
|
638
|
+
- Carry moves the positions and direction the constraint remembers; a
|
|
639
|
+
constraint with `x`/`y` keeps its translation offsets along the world axes,
|
|
640
|
+
unturned.
|
|
641
|
+
- A drawn bone nested under a carried chain reads its new world from the
|
|
642
|
+
chain's state before the carry.
|
|
643
|
+
- A later `seek` replays from the start with the sets then active, as it
|
|
644
|
+
always has, so it does not reproduce a carried switch.
|
|
645
|
+
|
|
606
646
|
`sets.json` keys are read strictly. Besides `slots`, `hides` and `drawn`, a
|
|
607
647
|
set may carry `drawnLength`, `registration` and `threshold`, which parts
|
|
608
648
|
writes and which place nothing under `check --set`: play reads past them by
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ export { type CanvasBackend, CanvasRenderer, type CanvasViewport } from './Canva
|
|
|
2
2
|
export { DomRenderer, type MeshBackend, type MeshSourceRect } from './DomRenderer.js';
|
|
3
3
|
export { type PageLayout, type PageRegion, type RegionEncoding, type RegionImage, revokeRegions, type UnpackRegionsOptions, unpackRegions } from './DomTexture.js';
|
|
4
4
|
export { type LoadModelOptions, loadModel, type ModelAssets, type ModelDocument, readSetupMesh, type RegionLoading, type RigSet, type SetupMesh, type SetupMeshTarget } from './loadModel.js';
|
|
5
|
-
export { type AdjustableBones, type BoneAdjust, type BoneAdjustContext, type BoneLocals, type BoneWorld, type PhysicsParameters, type PhysicsParameterPatch, type PhysicsParameterRead, type PlayOptions, type PoseBounds, type QueueOptions, type RenderMode, type RigComplete, type RigEnvironment, type RigEvent, RigPlayer, type RigPlayerOptions, type SlotFilter, type SlotIdentity, type SlotIdentityReason, type SlotIdentitySnapshot, type TrackEntry } from './player.js';
|
|
5
|
+
export { type AdjustableBones, type BoneAdjust, type BoneAdjustContext, type BoneLocals, type BoneWorld, type PhysicsParameters, type PhysicsParameterPatch, type PhysicsParameterRead, type PlayOptions, type PoseBounds, type QueueOptions, type RenderMode, type RigComplete, type RigEnvironment, type RigEvent, RigPlayer, type RigPlayerOptions, type SetActivationOptions, type SlotFilter, type SlotIdentity, type SlotIdentityReason, type SlotIdentitySnapshot, type TrackEntry } from './player.js';
|
|
6
6
|
export type { BlendMode, PosedClip, PosedFrame, PosedMesh, PosedRegion, PosedSlot, } from './posedFrame.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnK,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9L,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACnK,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9L,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,KAAK,UAAU,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC/e,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8962,6 +8962,28 @@ function frameOf(source, pose, color = [1, 1, 1, 1], draws = () => true) {
|
|
|
8962
8962
|
return { order };
|
|
8963
8963
|
}
|
|
8964
8964
|
const DEFAULT_ENVIRONMENT = Object.freeze({ wind: Object.freeze([1, 0]), gravity: Object.freeze([0, 1]) });
|
|
8965
|
+
function setPhysicsOption(call, options) {
|
|
8966
|
+
if (options === void 0) return void 0;
|
|
8967
|
+
if (options === null || typeof options !== "object") {
|
|
8968
|
+
throw new Error(`${call}: options must be an object like { physics: 'carry' }, got ${JSON.stringify(options)}`);
|
|
8969
|
+
}
|
|
8970
|
+
const physics = options.physics;
|
|
8971
|
+
if (physics === void 0 || physics === "carry" || physics === "reset") return physics;
|
|
8972
|
+
throw new Error(`${call}: options.physics must be 'carry' or 'reset', got ${JSON.stringify(physics)}`);
|
|
8973
|
+
}
|
|
8974
|
+
function drawnChanged(before, after) {
|
|
8975
|
+
const changed = /* @__PURE__ */ new Set();
|
|
8976
|
+
if (before !== null) {
|
|
8977
|
+
for (const [bone2, rotation] of before) if (after?.get(bone2) !== rotation) changed.add(bone2);
|
|
8978
|
+
}
|
|
8979
|
+
if (after !== null) {
|
|
8980
|
+
for (const [bone2, rotation] of after) if (before?.get(bone2) !== rotation) changed.add(bone2);
|
|
8981
|
+
}
|
|
8982
|
+
return changed;
|
|
8983
|
+
}
|
|
8984
|
+
function physicsContextOf(stepper) {
|
|
8985
|
+
return "first" in stepper ? stepper.track.ctx : stepper.path.ctx;
|
|
8986
|
+
}
|
|
8965
8987
|
function predicateOf(names) {
|
|
8966
8988
|
const allowed = new Set(names);
|
|
8967
8989
|
return (slot) => allowed.has(slot);
|
|
@@ -9261,6 +9283,8 @@ class RigPlayer {
|
|
|
9261
9283
|
touchedSets = /* @__PURE__ */ new Map();
|
|
9262
9284
|
/** The active sets' drawn bones as local rotations, applied before `adjust` on every pose (#170); null when none draws. */
|
|
9263
9285
|
drawnPose = null;
|
|
9286
|
+
/** Test-only (#173's planted control): `carry` maps every state through the identity instead of the anchor's turn. Not API. */
|
|
9287
|
+
carryPlant = false;
|
|
9264
9288
|
adjustFn = null;
|
|
9265
9289
|
/** Current preview patches, reapplied through the public core API on replay; no edit history. */
|
|
9266
9290
|
physicsPatches = /* @__PURE__ */ new Map();
|
|
@@ -9852,11 +9876,12 @@ class RigPlayer {
|
|
|
9852
9876
|
* A name not in `sets.json` throws by name; a build without `sets.json` has
|
|
9853
9877
|
* `sets()` empty and `setSet` throws.
|
|
9854
9878
|
*/
|
|
9855
|
-
setSet(name) {
|
|
9879
|
+
setSet(name, options) {
|
|
9856
9880
|
if (this.setList.length === 0) {
|
|
9857
9881
|
throw new Error(`cannot setSet(${JSON.stringify(name)}): this model has no sets.json`);
|
|
9858
9882
|
}
|
|
9859
|
-
|
|
9883
|
+
const physics = setPhysicsOption("setSet", options);
|
|
9884
|
+
this.activate(name === null ? [] : [this.namedSet(name)], physics);
|
|
9860
9885
|
}
|
|
9861
9886
|
/**
|
|
9862
9887
|
* Makes exactly `names` the active attachment sets (#168), together: each
|
|
@@ -9865,43 +9890,59 @@ class RigPlayer {
|
|
|
9865
9890
|
* companion). Composition does not depend on the order of `names`. An
|
|
9866
9891
|
* unknown name, a repeated name or two sets touching one slot throw by name
|
|
9867
9892
|
* and leave the active sets as they were; `[]` restores the base.
|
|
9893
|
+
*
|
|
9894
|
+
* `options.physics` (#173) decides what a switch that re-poses `drawn` bones
|
|
9895
|
+
* does to the physics constraints hung under them — on a bone whose drawn
|
|
9896
|
+
* rotation this call adds, removes or changes, or on a descendant of one:
|
|
9897
|
+
* `'carry'` moves each one's remembered state (where its bone was and
|
|
9898
|
+
* pointed) by the rigid turn of its deepest re-posed ancestor, so the chain
|
|
9899
|
+
* keeps its pose relative to the bone; `'reset'` restarts each one at the
|
|
9900
|
+
* new pose, as a physics `reset` key does. Absent, the constraints read the
|
|
9901
|
+
* jump as motion and kick, as they always have. Anything else throws before
|
|
9902
|
+
* anything changes. Nothing to do before `play` or when no physics hangs
|
|
9903
|
+
* under a re-posed bone. A later `seek` replays from the start with the sets
|
|
9904
|
+
* then active and does not reproduce a carried switch. `setSet`, `addSet`
|
|
9905
|
+
* and `removeSet` take the same option.
|
|
9868
9906
|
*/
|
|
9869
|
-
setSets(names) {
|
|
9907
|
+
setSets(names, options) {
|
|
9870
9908
|
if (this.setList.length === 0) {
|
|
9871
9909
|
throw new Error(`cannot setSets(${JSON.stringify(names)}): this model has no sets.json`);
|
|
9872
9910
|
}
|
|
9911
|
+
const physics = setPhysicsOption("setSets", options);
|
|
9873
9912
|
const sets = names.map((name) => this.namedSet(name));
|
|
9874
9913
|
for (let i = 0; i < sets.length; i++) {
|
|
9875
9914
|
for (let j = 0; j < i; j++) {
|
|
9876
9915
|
if (sets[i] === sets[j]) throw new Error(`set ${JSON.stringify(sets[i].name)} is named twice in setSets`);
|
|
9877
9916
|
}
|
|
9878
9917
|
}
|
|
9879
|
-
this.activate(sets);
|
|
9918
|
+
this.activate(sets, physics);
|
|
9880
9919
|
}
|
|
9881
9920
|
/**
|
|
9882
9921
|
* Activates `name` beside the sets already active (#168): a set already
|
|
9883
9922
|
* active is left as it is; one touching a slot an active set touches throws
|
|
9884
9923
|
* by name (the slot and both sets) and changes nothing.
|
|
9885
9924
|
*/
|
|
9886
|
-
addSet(name) {
|
|
9925
|
+
addSet(name, options) {
|
|
9887
9926
|
if (this.setList.length === 0) {
|
|
9888
9927
|
throw new Error(`cannot addSet(${JSON.stringify(name)}): this model has no sets.json`);
|
|
9889
9928
|
}
|
|
9929
|
+
const physics = setPhysicsOption("addSet", options);
|
|
9890
9930
|
const found = this.namedSet(name);
|
|
9891
9931
|
if (this.activeList.includes(found)) return;
|
|
9892
|
-
this.activate([...this.activeList, found]);
|
|
9932
|
+
this.activate([...this.activeList, found], physics);
|
|
9893
9933
|
}
|
|
9894
9934
|
/**
|
|
9895
9935
|
* Deactivates `name`, keeping every other active set (#168). An unknown name
|
|
9896
9936
|
* throws by name; a set that is not active is left as it is.
|
|
9897
9937
|
*/
|
|
9898
|
-
removeSet(name) {
|
|
9938
|
+
removeSet(name, options) {
|
|
9899
9939
|
if (this.setList.length === 0) {
|
|
9900
9940
|
throw new Error(`cannot removeSet(${JSON.stringify(name)}): this model has no sets.json`);
|
|
9901
9941
|
}
|
|
9942
|
+
const physics = setPhysicsOption("removeSet", options);
|
|
9902
9943
|
const found = this.namedSet(name);
|
|
9903
9944
|
if (!this.activeList.includes(found)) return;
|
|
9904
|
-
this.activate(this.activeList.filter((s) => s !== found));
|
|
9945
|
+
this.activate(this.activeList.filter((s) => s !== found), physics);
|
|
9905
9946
|
}
|
|
9906
9947
|
/** The declared set named `name`, or a throw naming it and the available sets. */
|
|
9907
9948
|
namedSet(name) {
|
|
@@ -9947,11 +9988,102 @@ class RigPlayer {
|
|
|
9947
9988
|
}
|
|
9948
9989
|
return touched;
|
|
9949
9990
|
}
|
|
9991
|
+
/**
|
|
9992
|
+
* The physics under the bones a set switch re-poses (#173), before the
|
|
9993
|
+
* repose step: the drawn rotations went from `before` to `after` (already
|
|
9994
|
+
* `drawnPose`), and every physics constraint whose bone is one of the
|
|
9995
|
+
* changed bones or a descendant of one is carried or reset. Nothing to do
|
|
9996
|
+
* before `play` (the setup pose carries no physics state) or when no
|
|
9997
|
+
* constraint hangs under a changed bone.
|
|
9998
|
+
*/
|
|
9999
|
+
handOverPhysics(before, after, mode) {
|
|
10000
|
+
const stepper = this.tracks ?? this.track;
|
|
10001
|
+
if (stepper === null || this.pose === null || this.rawPose === null) return;
|
|
10002
|
+
const changed = drawnChanged(before, after);
|
|
10003
|
+
if (changed.size === 0) return;
|
|
10004
|
+
const parentOf = new Map(this.view.bones.map((b) => [b.name, b.parent]));
|
|
10005
|
+
const anchorOf = (bone2) => {
|
|
10006
|
+
for (let b = bone2; b !== void 0; b = parentOf.get(b)) if (changed.has(b)) return b;
|
|
10007
|
+
return void 0;
|
|
10008
|
+
};
|
|
10009
|
+
const ctx = physicsContextOf(stepper);
|
|
10010
|
+
const affected = [];
|
|
10011
|
+
for (const c of this.view.constraints) {
|
|
10012
|
+
if (c.kind !== "physics") continue;
|
|
10013
|
+
const bone2 = c.record?.bone;
|
|
10014
|
+
const anchor = bone2 === void 0 ? void 0 : anchorOf(bone2);
|
|
10015
|
+
if (anchor === void 0) continue;
|
|
10016
|
+
const state = ctx.states.get(c.name);
|
|
10017
|
+
if (state === void 0 || state.pending) continue;
|
|
10018
|
+
affected.push({ name: c.name, anchor });
|
|
10019
|
+
}
|
|
10020
|
+
if (affected.length === 0) return;
|
|
10021
|
+
if (mode === "reset") {
|
|
10022
|
+
for (const { name } of affected) {
|
|
10023
|
+
const s = ctx.states.get(name);
|
|
10024
|
+
s.remaining = 0;
|
|
10025
|
+
s.lastTime = ctx.time;
|
|
10026
|
+
s.pending = true;
|
|
10027
|
+
s.xOffset = s.xLag = s.xVelocity = 0;
|
|
10028
|
+
s.yOffset = s.yLag = s.yVelocity = 0;
|
|
10029
|
+
s.rotateOffset = s.rotateLag = s.rotateVelocity = 0;
|
|
10030
|
+
s.scaleOffset = s.scaleLag = s.scaleVelocity = 0;
|
|
10031
|
+
}
|
|
10032
|
+
return;
|
|
10033
|
+
}
|
|
10034
|
+
const anchors = new Set(affected.map((a) => a.anchor));
|
|
10035
|
+
const worlds = (pose) => {
|
|
10036
|
+
const out = /* @__PURE__ */ new Map();
|
|
10037
|
+
for (const b of pose.bones) if (anchors.has(b.name)) out.set(b.name, b);
|
|
10038
|
+
return out;
|
|
10039
|
+
};
|
|
10040
|
+
const old = worlds(this.rawPose);
|
|
10041
|
+
const snapshot = captureStepperState(stepper);
|
|
10042
|
+
const now = worlds(stepper.step(0));
|
|
10043
|
+
restoreStepperState(stepper, snapshot);
|
|
10044
|
+
const maps = /* @__PURE__ */ new Map();
|
|
10045
|
+
for (const anchor of anchors) {
|
|
10046
|
+
const o = old.get(anchor);
|
|
10047
|
+
const n = now.get(anchor);
|
|
10048
|
+
if (o === void 0 || n === void 0) continue;
|
|
10049
|
+
if (this.carryPlant) {
|
|
10050
|
+
maps.set(anchor, [1, 0, 0, 1, 0, 0]);
|
|
10051
|
+
continue;
|
|
10052
|
+
}
|
|
10053
|
+
const det = o.a * o.d - o.b * o.c;
|
|
10054
|
+
if (!Number.isFinite(det) || det === 0) continue;
|
|
10055
|
+
const ia = o.d / det;
|
|
10056
|
+
const ib = -o.b / det;
|
|
10057
|
+
const ic = -o.c / det;
|
|
10058
|
+
const id = o.a / det;
|
|
10059
|
+
const a = n.a * ia + n.b * ic;
|
|
10060
|
+
const b = n.a * ib + n.b * id;
|
|
10061
|
+
const c = n.c * ia + n.d * ic;
|
|
10062
|
+
const d = n.c * ib + n.d * id;
|
|
10063
|
+
maps.set(anchor, [a, b, c, d, n.worldX - (a * o.worldX + b * o.worldY), n.worldY - (c * o.worldX + d * o.worldY)]);
|
|
10064
|
+
}
|
|
10065
|
+
const states = physicsContextOf(stepper).states;
|
|
10066
|
+
for (const { name, anchor } of affected) {
|
|
10067
|
+
const m = maps.get(anchor);
|
|
10068
|
+
const s = states.get(name);
|
|
10069
|
+
if (m === void 0 || s === void 0) continue;
|
|
10070
|
+
const [a, b, c, d, x, y] = m;
|
|
10071
|
+
const ux = s.ux;
|
|
10072
|
+
s.ux = a * ux + b * s.uy + x;
|
|
10073
|
+
s.uy = c * ux + d * s.uy + y;
|
|
10074
|
+
const cx = s.cx;
|
|
10075
|
+
s.cx = a * cx + b * s.cy + x;
|
|
10076
|
+
s.cy = c * cx + d * s.cy + y;
|
|
10077
|
+
const tx = s.tx;
|
|
10078
|
+
s.tx = a * tx + b * s.ty;
|
|
10079
|
+
s.ty = c * tx + d * s.ty;
|
|
10080
|
+
}
|
|
10081
|
+
}
|
|
9950
10082
|
/**
|
|
9951
10083
|
* Makes `sets` (distinct) the active sets: refuses any two touching one slot
|
|
9952
10084
|
* before changing anything, then applies their composition to the held pose.
|
|
9953
10085
|
*/
|
|
9954
|
-
activate(sets) {
|
|
10086
|
+
activate(sets, physics) {
|
|
9955
10087
|
for (let i = 0; i < sets.length; i++) {
|
|
9956
10088
|
for (let j = 0; j < i; j++) {
|
|
9957
10089
|
const other = this.touched(sets[j]);
|
|
@@ -9978,7 +10110,9 @@ class RigPlayer {
|
|
|
9978
10110
|
this.clearSeekCache();
|
|
9979
10111
|
const drawn = this.activeSet?.drawn;
|
|
9980
10112
|
if (drawn !== drawnBefore && !(drawn === void 0 && drawnBefore === void 0)) {
|
|
10113
|
+
const posedBefore = this.drawnPose;
|
|
9981
10114
|
this.drawnPose = drawn === void 0 ? null : drawnLocals(this.view, drawn);
|
|
10115
|
+
if (physics !== void 0) this.handOverPhysics(posedBefore, this.drawnPose, physics);
|
|
9982
10116
|
this.reposeDrawn();
|
|
9983
10117
|
return;
|
|
9984
10118
|
}
|